RaspberryPiとTA7291PでDCモーターを制御した時の波形を観測してみた

#概要
表題の通り、TA7291Pの波形がどんなものかみてみたかったので観測をしてみました。


#構成
MCP3208でボリューム抵抗からの可変電圧を読み取り、TA7291へGPIOよりPWM出力をし、DCモーターを駆動させています。

![TA7291P_ブレッドボード0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/47569676-4447-91cd-1775-456fd2150879.png)



<Table>
  <TR>
    <TD></TD>
    <TD>IN1</TD>
    <TD>IN2</TD>
    <TD>OUT1</TD>
    <TD>OUT2</TD>
  </TR>
  <TR>
    <TD>ストップ</TD>
    <TD>L</TD>
    <TD>L</TD>
    <TD>∞</TD>
    <TD>∞</TD>
  </TR>
  <TR>
    <TD>正転</TD>
    <TD>H(PWM)</TD>
    <TD>L</TD>
    <TD>H(PWM)</TD>
    <TD>L</TD>
  </TR>
  <TR>
    <TD>反転</TD>
    <TD>L</TD>
    <TD>H(PWM)</TD>
    <TD>L</TD>
    <TD>H(PWM)</TD>
  </TR>
  <TR>
    <TD>ブレーキ</TD>
    <TD>H</TD>
    <TD>H</TD>
    <TD>L</TD>
    <TD>L</TD>
  </TR>

</Table>



#波形
##入力IN1、IN2（正転）
PWM周期は20msで、IN1のDUTY比約10%時の波形。モーターのノイズの影響は受けてなさそうです。
![01正転PWM.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/b21245ea-9a16-6449-bbe8-36cb136e2d0b.jpeg)

##入力IN1、IN2（反転）
同様に反転時。
![02反転PWM.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/fbb23c10-eb88-9a69-a480-eaced142665a.jpeg)

##出力OUT1、OUT2（正転・無負荷）
DCモーターを接続せず、OUT端子を計測しました。電圧は5.17Vで、乾電池の直列電圧がほぼ電圧降下なしで出力されています。気になるのはPWMのH/L切り替わりのなまりと、LになってほしいOUT2にスパイク電圧のようなものが出力されている点です。また、OUT2はOFF時も若干浮いててGNDに落ちきっていません。PWM周波数が大きすぎてTA7291が追従できてないのかと思いましたがモーター接続時の挙動は問題なかったので確認していません。
![03-1正転OUT_無負荷.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/b20f0ea8-7d6e-ff47-b327-73fa2d7f6669.jpeg)

##出力OUT1、OUT2（正転）
モーターを接続しているので電圧降下で3.85Vまで落ちています。DCモーターのノイズはすごいと本に書いてありましたが確かになかなかのノイズです。
![03-1正転OUT.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/c2f87653-f0c6-951c-b4df-21c7ccd888e2.jpeg)

##出力OUT1、OUT2（反転）
同様に反転時
![04反転OUT.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/b3f2a9f6-b115-e185-d5e0-f6c1592fab2c.jpeg)

##出力OUT1、OUT2（正転・セラコン10nF×1接続）
下図のように出力端子間に10nFのセラコンを接続します。若干ノイズが落ち着いたでしょうか。
![TA7291P_ブレッドボード1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/5aca7f00-a107-2c40-45c6-a149d44035f1.png)

![03-2正転OUT_10nF.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/e05beeb8-faf7-9601-ffc3-b0e8bc397069.jpeg)

##出力OUT1、OUT2（正転・セラコン10nF×2接続）
次は2つ並列で接続します。さらによくなった気がします。
![TA7291P_ブレッドボード2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/6af288d6-1021-65ac-4087-cc38b2fd19a5.png)
![03-3正転OUT_10nF×2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/be71af94-cb27-4900-5f56-8982e3546411.jpeg)

##出力OUT1、OUT2（正転・セラコン100nF×1接続）
切り替わり時のなまりが残っており、10nFのほうがよい気がします。
![03-4正転OUT_100nF.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/5a80c399-5872-f1d3-9ed0-e1d0de66ade1.jpeg)

##出力OUT1、OUT2（正転・セラコン100nF×2接続）
並列にしてもいまいち、なのかな。
![03-5正転OUT_100nF×2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/b5add182-ba09-b94c-9630-c194cf21dc74.jpeg)

##出力OUT1、OUT2（正転・セラコン10nF×1＋100nF×1接続）
10nF×2がベストな気がします。

![03-6正転OUT_100nF＋10nF.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530581/bee9af2d-bef2-b091-d299-bf41eda34df9.jpeg)



#ソース
参考図書のソースを参考にしています、ADコンバータからの出力が100未満、4000以上の時にDCモーターのノイズの影響を受けやすいそうで、その時は処理をしていません。補足に記載しましたがHW的にも最小・最大値付近の値は処理しない回路にしてあります。

```motor.py
import RPi.GPIO as GPIO
from time import sleep
import spidev


def readadc():
    command1 = 0x06
    command2 = 0x00
    ret = spi.xfer2([command1,command2,0])
    val = (ret[1]&0x0f)<<8 | ret[2]
    return val


GPIO.setmode(GPIO.BCM)
GPIO.setup(19,GPIO.OUT)
GPIO.setup(26,GPIO.OUT)
IN1 = GPIO.PWM(19,50)
IN2 = GPIO.PWM(26,50)
IN1.start(0)
IN2.start(0)

spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 1000000



try:
    while True:

        val = readadc()
        print val

        if val >=100 and val <2048:
            IN2.ChangeDutyCycle(0)
            duty = (2048-val)*70/2048
            IN1.ChangeDutyCycle(duty)
        elif val >= 2048 and val <4000:
            IN1.ChangeDutyCycle(0)
            duty = (val-2048)*70/2048
            IN2.ChangeDutyCycle(duty)


        sleep(0.5)


except KeyboardInterrupt:
    pass


spi.close()

```

#訂正
ブレッドボード図にはありませんが、ボリューム抵抗の両端に330Ωの抵抗を接続して、電圧の可変範囲を狭くしています。参考図書いわくDCモーターのノイズでMCP3208が0、4095の誤った出力をすることがあるそうで、それらの値をHW的に入力範囲外とするためのようです。さらに、SW的にも100～4000程度までの出力のみ取り扱う事でノイズ対策をしています。

#まとめ
よくバイパスコンデンサで、色んな周波数に対応するために数種類の容量のセラコンを電源ラインにおいてあるのは知っていましたが、どんな容量を選択すればいいのかはよくわかっていません。容量が大きすぎても波形のなまりの要因になるのかもしれませんし、小さすぎても効果がないとか想像していますが今回は参考図書にあったとおり10nFを接続するのがベストだというのが実証できてよかったです。

#参考
[RaspberryPiで学ぶ電子工作](http://bluebacks.kodansha.co.jp/books/9784062578912/appendix/)