Raspberry pi でロボットアームを動かす その3 PCA9685
I2C接続16チャンネル サーボ&PWM駆動キット PCA9685 を試す
はんだ付け
先にPINを付けてから、電源のターミナルをつける。
そうしないと、裏返した際に傾いて、はんだ付けしにくい。
配線
SCL - RPI GPIO3 SDA - RPI GPIO2 GND - RPI GND Vcc - RPI 5v
I2C を有効にする
raspi-config から行う。
動作確認
$ sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: 70 -- -- -- -- -- -- --
Adafruitのライブラリとサンプルを使う。
$ git clone https://github.com/adafruit/Adafruit_Python_PCA9685.git $ cd Adafruit_Python_PCA9685 $ sudo python setup.py install
サンプルスクリプトを書き換える。
0と1に繋いであります。
$ cat PCA9685.py #!/usr/bin/python # coding: utf-8 from __future__ import division import time import Adafruit_PCA9685 # Uncomment to enable debug output. #import logging #logging.basicConfig(level=logging.DEBUG) pwm = Adafruit_PCA9685.PCA9685() def set_servo_pulse(channel, pulse): pulse_length = 1000000 # 1,000,000 us per second pulse_length //= 50 # 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 /= pulse_length print "%d pulse" % pulse pwm.set_pwm(channel, 0, int(pulse)) pwm_set = [800, 1200] if __name__ == '__main__': try: while True: channel = 0 set_servo_pulse(channel, pwm_set[0]) time.sleep(1) set_servo_pulse(channel, pwm_set[1]) time.sleep(1) channel = 1 set_servo_pulse(channel, pwm_set[0]) time.sleep(1) set_servo_pulse(channel, pwm_set[1]) time.sleep(1) except KeyboardInterrupt: pass
スクリプトその2
モーターの仕様に合わせて、50hzにしたり、DUty比を計算して値を当ててみたりしたんですが、どうも、PCA9685 と、Adafruitさんのドライバにおいては、サンプルに有るように、 60hz, 150最小, 600最大 で組んでしまったほうが良さそうです。
ドライバの詳細を読み込めば、分かるのかもしれませんが、現在の結論は、そうなってしまった。
$ cat PCA9685.py #!/usr/bin/python # coding: utf-8 from __future__ import division import time import Adafruit_PCA9685 # Uncomment to enable debug output. #import logging #logging.basicConfig(level=logging.DEBUG) pwm = Adafruit_PCA9685.PCA9685() pwm.set_pwm_freq(60) if __name__ == '__main__': try: while True: channel = 0 pwm.set_pwm(channel, 0, 150) time.sleep(1) pwm.set_pwm(channel, 0, 375) time.sleep(1) pwm.set_pwm(channel, 0, 600) time.sleep(1) pwm.set_pwm(channel, 0, 375) time.sleep(1) channel = 1 pwm.set_pwm(channel, 0, 150) time.sleep(1) pwm.set_pwm(channel, 0, 375) time.sleep(1) pwm.set_pwm(channel, 0, 600) time.sleep(1) pwm.set_pwm(channel, 0, 375) time.sleep(1) except KeyboardInterrupt: pass pwm.set_pwm(0, 0, 375) time.sleep(1) pwm.set_pwm(1, 0, 375) time.sleep(1) print("END.\n")
モーターをゼロポジションにする
上記のスクリプトで、とにかく 375 で終了にさせておく。
ただし、下から3つ目のサーボモーターは、設計図のままだと、可動域の中央ではない。
上を向かせて組まないといけない。
アームを組み上げる
これの、1:19 あたりから5軸の組み立て方が出ます。
最初は3軸用なので注意。
注意点!
1.ネジとホーンの種類
サーボモーターと一緒に入っているネジとホーン(5袋)は使用しません。
別の袋に入っている、金属のホーンと、その復路に貼っているネジで組み上げます。
2. ネジの長さが長すぎる
とくに、ハンドの部分。
ホーンの厚みよりもネジが長いので、当たっちゃいます。
ペンチでカットしました。
3. ハンドの可動域
120度全て動かせません。(開きすぎちゃう)
渡しの場合は、DUry比で50%で組合上げて、色々ずれて? 結局、
min = 250 max = 395
と成りました。
min で閉じて、 max で開き切ります。
なので、それ以上、それ以下にならないようにコーディングします。