Raspberry Pi 備忘録 / Mbedもあるよ!

Raspberry Pi であれこれやった事の記録

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軸用なので注意。

www.youtube.com

注意点!

1.ネジとホーンの種類

サーボモーターと一緒に入っているネジとホーン(5袋)は使用しません。

別の袋に入っている、金属のホーンと、その復路に貼っているネジで組み上げます。

2. ネジの長さが長すぎる とくに、ハンドの部分。
ホーンの厚みよりもネジが長いので、当たっちゃいます。
ペンチでカットしました。

3. ハンドの可動域 120度全て動かせません。(開きすぎちゃう)
渡しの場合は、DUry比で50%で組合上げて、色々ずれて? 結局、

min = 250
max = 395

と成りました。

min で閉じて、 max で開き切ります。

なので、それ以上、それ以下にならないようにコーディングします。

f:id:pongsuke:20170116161417j:plain

f:id:pongsuke:20170116161437j:plain

f:id:pongsuke:20170116161443j:plain