Jetson nano でPWMコントローラーのPCA9685を使ってサーボモータを複数動かすまでの備忘録。
PWMコントローラーを使えば、モータを16個同時に操作できるし、スクリプト側でマルチthreadingを使わなくて済むとかいいことばかりなので使ってみた。
あとPWMコントローラーは普通にサーボモータを使うより角度や、デューティ比を正確に設定できるので必須アイテム。
目次
1. Adafruit-PCA9685のインストール
2. PCA9685とjetson nanoの配線
3. 複数のサーボモータを実際に動かす
1. Adafruit-PCA9685のインストール
pip3 install Adafruit_PCA9685
このままだとエラーが出るのでI2C.pyを書き換え。
vi ~/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py
I2C.pyの以下を修正
・2行をコメントアウト
・return Device(address, "1", i2c_interface, **kwargs)
にする
def get_i2c_device(address, busnum=None, i2c_interface=None, **kwargs): """Return an I2C device for the specified address and on the specified bus. If busnum isn't specified, the default I2C bus for the platform will attempt to be detected. """ # if busnum is None: # busnum = get_default_bus() return Device(address, "1", i2c_interface, **kwargs)
下のように信号が表示されればOK。
$ sudo i2cdetect -y -r 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 -- -- -- -- -- -- --
2. PCA9685とjetson nanoの配線
PCA9685. Jetson Nano ------------------------------------ GND -> GND SCL -> I2C(5 番) SDA -> I2C(3番) VCC -> 3.3V V+ -> 5V
3. 複数のサーボモータを実際に動かす
simpletest.pyfrom __future__ import division import time import Adafruit_PCA9685 pwm = Adafruit_PCA9685.PCA9685() # Configure min and max servo pulse lengths servo_min = 102 # Min pulse length out of 4096 servo_max = 492 # 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(50) print('Moving servo on channel 0, press Ctrl-C to quit...') while True: # Move servo on channel O between extremes. pwm.set_pwm(15, 0, servo_min) time.sleep(1) pwm.set_pwm(14, 0, servo_max) time.sleep(1) pwm.set_pwm(15, 0, servo_max) time.sleep(1) pwm.set_pwm(14, 0, servo_min) time.sleep(1)
Tkinerを使ったversion
from __future__ import division import time import Adafruit_PCA9685 from tkinter import * pwm = Adafruit_PCA9685.PCA9685() pwm.set_pwm_freq(50) class App: def __init__(self, master): frame = Frame(master) frame.pack() scale_pan = Scale(frame, label="pan", from_=0, to=180, tickinterval=90, orient=HORIZONTAL, command=self.update_pan) scale_pan.set(90) scale_pan.grid(row=0, column=0) scale_tilt = Scale(frame, label="tilt", from_=0, to=180, tickinterval=90, orient=VERTICAL, command=self.update_tilt) scale_tilt.set(90) scale_tilt.grid(row=0, column=1) def update_pan(self, angle): duty = int( float(angle) * 2.17 + 102 ) pwm.set_pwm(14, 0, duty) time.sleep(0.1) def update_tilt(self, angle): duty = int( float(angle) * 2.17 + 102 ) pwm.set_pwm(15, 0, duty) time.sleep(0.1) root = Tk() root.wm_title('Servo Control') app = App(root) root.geometry("220x120+0+0") root.mainloop()
うまくいった。
参考サイト
・Jetson nanoとPCA9685でサーボを動かそうとするときのI2Cエラー対処法!・jetson_nano_grove