2017
03.15

ハードウェアPWMの制御

Internship

インターン生の並木(学部1年)です。

日曜日は今まで作ってきた人工知能ワカサギ釣竿を実際に使用し、テストしました。何匹かワカサギを釣ることができた一方で、様々な問題点も見つかりました。これらの課題を一つずつ解決していこうと思います。

その問題点の一つに釣竿を振っているサーボが安定しないという問題がありました。ソフトウェアPWMを使用しているため、実行環境やプログラムのバグによってPWMの出力が不安定になることがあります。

そこでハードウェアPWMを使用することでサーボを制御できないか試してみることにしました。使用したICはPCA9685です。I2Cを使用して制御します。

import smbus
import time
bus = smbus.SMBus(1)

PCA9685_ADDRESS = 0x40
CONTROL_REG = 0x00
OSC_CLOCK = 25000000

PWM0_ON_L = 0x06
PWM0_ON_H = 0x07
PWM0_OFF_L = 0x08
PWM0_OFF_H = 0x09

ALL_PWM_ON_L = 0xFA
ALL_PWM_ON_H = 0xFB
ALL_PWM_OFF_L = 0xFC
ALL_PWM_OFF_H = 0xFD
PRE_SCALE = 0xFE

SLEEP_BIT = 0x10

def setFrequency(hz):
    setval=int(round(OSC_CLOCK/(4096*hz))-1)
    ctrl_dat = bus.read_word_data(PCA9685_ADDRESS,CONTROL_REG)

    #スリープにする
    bus.write_i2c_block_data(PCA9685_ADDRESS,CONTROL_REG,[ctrl_dat | SLEEP_BIT])
    time.sleep(0.01)
    #周波数を設定
    bus.write_i2c_block_data(PCA9685_ADDRESS,PRE_SCALE,[setval])
    time.sleep(0.01)
    #スリープを解除
    bus.write_i2c_block_data(PCA9685_ADDRESS,CONTROL_REG,[ctrl_dat & (~SLEEP_BIT)])

def setPWM(pwmpin,value):
    if (value100):
        print "Error"
        return
#     0~100を0~4096に変換
    setval=int(value*4096/100)
#     最初からオン
    bus.write_i2c_block_data(PCA9685_ADDRESS,PWM0_ON_L+pwmpin*4,[0x00])
    bus.write_i2c_block_data(PCA9685_ADDRESS,PWM0_ON_H+pwmpin*4,[0x00])
#     Value%経過後にオフ
    bus.write_i2c_block_data(PCA9685_ADDRESS,PWM0_OFF_L+pwmpin*4,[setval & 0xff])
    bus.write_i2c_block_data(PCA9685_ADDRESS,PWM0_OFF_H+pwmpin*4,[setval>>8])

# サンプル
setFrequency(50)#50Hzに設定
# サーボの範囲は2.5~13.7%
while True:
    for m in range(0,4):
        for i in range(125,100,-1):
            setPWM(m,float(i)/10)
            time.sleep(0.001)
        time.sleep(0.1)
        for i in range(100,120,1):
            setPWM(m,float(i)/10)
            time.sleep(0.001)
        time.sleep(1)

4台のサーボを順番に動かすサンプルです。

クロックの設定で苦戦しましたが、比較的簡単に制御できました。これからはこのハードウェアPWMを使って釣竿を制御していきたいと思います。

Comment

  1. No comments yet.

  1. No trackbacks yet.

You must be logged in to post a comment.