さて、いよいよpythonに触れていく訳ですが、私も初心者に毛が生えた程度だと自覚しています。間違いがありましたら、遠慮なくご指摘下さい。よろしくお願いいたします!
simpletest.pyのソースコード
# Simple demo of of the PCA9685 PWM servo/LED controller library.
# This will move channel 0 from min to max position repeatedly.
# Author: Tony DiCola
# License: Public Domain
from __future__ import division
import time
# Import the PCA9685 module.
import Adafruit_PCA9685
# Uncomment to enable debug output.
#import logging
#logging.basicConfig(level=logging.DEBUG)
# Initialise the PCA9685 using the default address (0x40).
pwm = Adafruit_PCA9685.PCA9685()
# Alternatively specify a different address and/or bus:
#pwm = Adafruit_PCA9685.PCA9685(address=0x41, busnum=2)
# Configure min and max servo pulse lengths
servo_min = 150 # Min pulse length out of 4096
servo_max = 600 # Max pulse length out of 4096
# Helper function to make setting a servo pulse width simpler.
def set_servo_pulse(channel, pulse):
pulse_length = 1000000 # 1,000,000 us per second
pulse_length //= 60 # 60 Hz
print('{0}us per period'.format(pulse_length))
pulse_length //= 4096 # 12 bits of resolution
print('{0}us per bit'.format(pulse_length))
pulse *= 1000
pulse //= pulse_length
pwm.set_pwm(channel, 0, pulse)
# Set frequency to 60hz, good for servos.
pwm.set_pwm_freq(60)
print('Moving servo on channel 0, press Ctrl-C to quit...')
while True:
# Move servo on channel O between extremes.
pwm.set_pwm(0, 0, servo_min)
time.sleep(1)
pwm.set_pwm(0, 0, servo_max)
time.sleep(1)
pythonでは、#で始まる行はコメントです。
と言うことで、1~4行目はコメント。
from __future__ import division
これは、__future__モジュールから、divisionというライブラリをインポートしています。__future__モジュールの説明はここに書いてありました。python3系の機能を python2系でも実行できるようにするものだとか。
pythonには2系と3系があって、3系じゃなくて2系を使いたい人もいるらしいので、こういうモジュールが出来るんでしょうね。そして、その中のdivisionライブラリは、割り算をするライブラリのようです。
Thonnyのオプションを見たらこうなっていたので、Raspberry Piで使うのは3系のようです。
と言うことで、本当はこのモジュールはimportしなくてもOKなわけです。次の行の
import time
は、時間関係の処理をする際に必須なので、有名なライブラリです。
import Adafruit_PCA9685
が、このプログラムのキーです。この1行で、Adafruit_PCA9685の機能が全て使えるようになるのです。正確には、simpletest.pyにAdafruit_PCA9685を動かすためのプログラムをくっつけるのですが、ユーサーはその本体を意識する必要は無いというのが、pythonの優れている部分なのでは無いでしょうか。
# Initialise the PCA9685 using the default address (0x40).
pwm = Adafruit_PCA9685.PCA9685()
この部分で、 PCA9685を初期化しています。ここでやっているのは、さっきimportしたAdafruit_PCA9685というモジュールの中にあるPCA9685というクラスのインスタンス(コピー)を作って、その名前を「pwm」にしているのです。
クラスとは、PCA9685を扱うための細かい約束事みたいなものをパッケージしたもので、クラスを使うときは、それをコピーして使うというのがルールのようです。
その次にあるこの2行は、パルスの幅を決めています。最小の値と最大の値を決めていますが、サーボの角度を微調整したい場合は、ここの数字を微調整することで、サーボの回転角が微調整されます。
# Configure min and max servo pulse lengths
servo_min = 150 # Min pulse length out of 4096
servo_max = 600 # Max pulse length out of 4096
その下のこの部分は、set_servo_pulseという関数を定義しています。
# Helper function to make setting a servo pulse width simpler.
def set_servo_pulse(channel, pulse):
pulse_length = 1000000 # 1,000,000 us per second
pulse_length //= 60 # 60 Hz
print('{0}us per period'.format(pulse_length))
pulse_length //= 4096 # 12 bits of resolution
print('{0}us per bit'.format(pulse_length))
pulse *= 1000
pulse //= pulse_length
pwm.set_pwm(channel, 0, pulse)
この関数は、以降で使われていないので、読み飛ばしても構わないのですが、サーボのパルスをシンプルに設定する事が出来るようです。
# Set frequency to 60hz, good for servos.
pwm.set_pwm_freq(60)
この部分は、pwmの周波数を設定している部分です。60hzという事は、1秒間に60回パルスを送るという事なので、分解能的には60fpsでサーボに信号を送るという設定のようです。
print('Moving servo on channel 0, press Ctrl-C to quit...')
while True:
# Move servo on channel O between extremes.
pwm.set_pwm(0, 0, servo_min)
time.sleep(1)
pwm.set_pwm(0, 0, servo_max)
time.sleep(1)
この最後の部分は、まずprint文でシェルのところにメッセージを表示します。
次に、while True:と書かれていますが、while文の構文は
while 条件:
条件が真の間実行する処理
となります。上のプログラムでは、条件の所が True なので、「永遠に続けろ」という事です。
で、何を続けるのかというと、まず
pwm.set_pwm(0, 0, servo_min)
です。これは、pwmというPCA9685クラスにある、set_pwmメソッドを実行せよ。という命令です。最初の引数0はチャンネルの指定なので、0chに繋がれているサーボに送るpwmを指定するよという事です。
2番目の引数0は、パルスを立ち上げ始めるタイミングです。PCA9685は12bitなので、0~4095までの値で指定しますが、各チャンネルに時間差を設けなくて良いのであれば、0のままで構いません。例えば、この値を、ch0を0、ch1を50とかにすると、ch1は50/4096/60=0.0002秒=0.2msだけch0から遅れてパルスが送られることになるのです。
3つ目の引数は、servo_minとなっているので、中身は150となります。つまり、0で立ち上がったパルスが150で落ちて、4095まで落ちたまま。という状況をサーボに伝えるのです。サーボはそれを受け取って、150の角度(最小と言いつつ、もっと小さな値にするともうちょっと回ったりします)に回します。次の
time.sleep(1)
は、1秒待て。という命令。指定された角度までモーターが回るのには少し時間がかかるので、ここで待っているのです。そして、次の
pwm.set_pwm(0, 0, servo_max)
は、さっき150で送ったパルスを600にしてという命令。今度は、0で立ち上げたパルスを600まで引っ張って0に落とすという事なので、少しONの時間が長くなります。サーボは600の角度(最大と言いつつ、もうちょっと大きな値にすると、もうちょっとだけ余計に回ったりします)に回します。そしてまた1秒待つ。
というのを永遠に繰り返すので、1秒ごとにサーボが動くのでした。
以上、sinpletest.pyの解説でした。
いや〜今晩は記事書いて終わった〜明日はLEDを点灯してみようかな。
コメント