simpletest.pyの解読

さて、いよいよ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を点灯してみようかな。

コメント

タイトルとURLをコピーしました