ラズパイ3b＋で曲げセンサー使ってDCモーターのPWM制御＠最新 Raspberry Piで学ぶ電子工作(ブルーバックス)応用

#概要
前回の記事[ラズパイ3b＋でAD変換からのLED点灯＠最新 Raspberry Piで学ぶ電子工作(ブルーバックス)](https://qiita.com/Allovertom/items/225c0cfab8ec79b40aa5)の続き。
今度は、曲げセンサーの曲げ具合によって、DCモーターの回転数を制御したいと思います！
と言っても、やったのは[カラー図解 最新 Raspberry Piで学ぶ電子工作 作って動かしてしくみがわかる (ブルーバックス) ](https://www.amazon.co.jp/%E3%82%AB%E3%83%A9%E3%83%BC%E5%9B%B3%E8%A7%A3-Raspberry-Pi%E3%81%A7%E5%AD%A6%E3%81%B6%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C-%E4%BD%9C%E3%81%A3%E3%81%A6%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E3%81%97%E3%81%8F%E3%81%BF%E3%81%8C%E3%82%8F%E3%81%8B%E3%82%8B-%E3%83%96%E3%83%AB%E3%83%BC%E3%83%90%E3%83%83%E3%82%AF%E3%82%B9/dp/4062579774/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E3%83%A9%E3%82%BA%E3%83%99%E3%83%AA%E3%83%BC%E3%83%91%E3%82%A4%E3%81%A7%E5%AD%A6%E3%81%B6%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C&qid=1561894984&s=hobby&sr=1-3-catcorr)の8章の回路の可変抵抗を、曲げセンサーと抵抗10kΩに変えただけ。難しくないのでぜひやってみてください。


#使用部品
ADコンバーター：ＭＣＰ３２０８－ＣＩ／Ｐ　←[前回](https://qiita.com/Allovertom/items/225c0cfab8ec79b40aa5)と同じ！
抵抗：10kΩ　2個, 330Ω　2個
モータードライバー：　TA7291P     ご参考：[秋月電子モータードライバー　ＴＡ７２９１Ｐ　（２個入）](http://akizukidenshi.com/catalog/g/gI-02001/)
2個で300円だけど、送料が。。。

#配線図
![IMG_0523.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333380/282f2c5e-10f1-7d54-4a7f-256c08b12966.jpeg)
引用元：[カラー図解 最新 Raspberry Piで学ぶ電子工作 作って動かしてしくみがわかる (ブルーバックス) ](https://www.amazon.co.jp/%E3%82%AB%E3%83%A9%E3%83%BC%E5%9B%B3%E8%A7%A3-Raspberry-Pi%E3%81%A7%E5%AD%A6%E3%81%B6%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C-%E4%BD%9C%E3%81%A3%E3%81%A6%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E3%81%97%E3%81%8F%E3%81%BF%E3%81%8C%E3%82%8F%E3%81%8B%E3%82%8B-%E3%83%96%E3%83%AB%E3%83%BC%E3%83%90%E3%83%83%E3%82%AF%E3%82%B9/dp/4062579774/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E3%83%A9%E3%82%BA%E3%83%99%E3%83%AA%E3%83%BC%E3%83%91%E3%82%A4%E3%81%A7%E5%AD%A6%E3%81%B6%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C&qid=1561894984&s=hobby&sr=1-3-catcorr)

ここの、可変抵抗の部分を曲げセンサーと10kΩ抵抗で置き換え。下記参照。
![IMG_0525.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333380/93d2feaf-f1de-4c08-1eff-6c00219ae1e6.jpeg)


#実配線
![IMG_0524.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333380/a2c85141-8536-80d9-8fc8-d5e9dda9984a.jpeg)
モーターは、[タミヤのツインモーターギヤボックス](https://www.tamiya.com/japan/products/70097/index.html)に埋め込んでしまったので、２つ写ってますが、今回動かすの右側の１つです。
ノイズ処理で、0.01μFのコンデンサつけてます。

#プログラム

[Raspberry Piで学ぶ電子工作サポートページ](http://bluebacks.kodansha.co.jp/books/9784062578912/appendix/)からダウンロードできますが、ここに書いておきます。

```python:08-03-dcmotor.py
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
from time import sleep

# MCP3208からSPI通信で12ビットのデジタル値を取得。0から7の8チャンネル使用可
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
    if adcnum > 7 or adcnum < 0:
        return -1
    GPIO.output(cspin, GPIO.HIGH)
    GPIO.output(clockpin, GPIO.LOW)
    GPIO.output(cspin, GPIO.LOW)

    commandout = adcnum
    commandout |= 0x18  # スタートビット＋シングルエンドビット
    commandout <<= 3    # LSBから8ビット目を送信するようにする
    for i in range(5):
        # LSBから数えて8ビット目から4ビット目までを送信
        if commandout & 0x80:
            GPIO.output(mosipin, GPIO.HIGH)
        else:
            GPIO.output(mosipin, GPIO.LOW)
        commandout <<= 1
        GPIO.output(clockpin, GPIO.HIGH)
        GPIO.output(clockpin, GPIO.LOW)
    adcout = 0
    # 13ビット読む（ヌルビット＋12ビットデータ）
    for i in range(13):
        GPIO.output(clockpin, GPIO.HIGH)
        GPIO.output(clockpin, GPIO.LOW)
        adcout <<= 1
        if i>0 and GPIO.input(misopin)==GPIO.HIGH:
            adcout |= 0x1
    GPIO.output(cspin, GPIO.HIGH)
    return adcout

GPIO.setmode(GPIO.BCM)
# ピンの名前を変数として定義
SPICLK = 11
SPIMOSI = 10
SPIMISO = 9
SPICS = 8
# SPI通信用の入出力を定義
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICS, GPIO.OUT)

GPIO.setup(25, GPIO.OUT)
GPIO.setup(24, GPIO.OUT)
p0 = GPIO.PWM(25, 50)
p1 = GPIO.PWM(24, 50)
p0.start(0)
p1.start(0)

adc_pin0 = 0

try:
    while True:
        inputVal0 = readadc(adc_pin0, SPICLK, SPIMOSI, SPIMISO, SPICS)
        print(inputVal0)#今回僕が追加したところここだけ。画面にADコンバーターの出力をプリントするのみ
        if inputVal0 > 100 and inputVal0 < 2048:
            p1.ChangeDutyCycle(0)
            duty = (2048-inputVal0)*70/2048#出力を70%に押さえて、モータードライバーへの入力を制限している
            p0.ChangeDutyCycle(duty)
        elif inputVal0 >= 2048 and inputVal0 < 4000:
            p0.ChangeDutyCycle(0)
            duty = (inputVal0-2048)*70/2048#出力を70%に押さえて、モータードライバーへの入力を制限している
            p1.ChangeDutyCycle(duty)
        sleep(0.5)



except KeyboardInterrupt:
    pass

p0.stop()
p1.stop()
GPIO.cleanup()
```
勉強になったのは、ノイズ対策。
DCモーターが駆動すると、ADコンバーターから0とか4095とかのノイズが発生するらしい。ここで行っている対策は2点。
１，ハードでの対策：330Ωの抵抗２個を曲げセンサーを挟むように配置している。
２，ソフトでの対策：inputVal0が100以下と、4000以上はノイズとして読まないようプログラミングしている点。（上記参照）


残りの解説は[カラー図解 最新 Raspberry Piで学ぶ電子工作 作って動かしてしくみがわかる (ブルーバックス) ](https://www.amazon.co.jp/%E3%82%AB%E3%83%A9%E3%83%BC%E5%9B%B3%E8%A7%A3-Raspberry-Pi%E3%81%A7%E5%AD%A6%E3%81%B6%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C-%E4%BD%9C%E3%81%A3%E3%81%A6%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E3%81%97%E3%81%8F%E3%81%BF%E3%81%8C%E3%82%8F%E3%81%8B%E3%82%8B-%E3%83%96%E3%83%AB%E3%83%BC%E3%83%90%E3%83%83%E3%82%AF%E3%82%B9/dp/4062579774/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E3%83%A9%E3%82%BA%E3%83%99%E3%83%AA%E3%83%BC%E3%83%91%E3%82%A4%E3%81%A7%E5%AD%A6%E3%81%B6%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C&qid=1561894984&s=hobby&sr=1-3-catcorr)を見てみてください！！

#実行結果
＜曲げてないとき＞
![IMG_0521.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333380/29cf792d-227c-925b-7914-ac5c1d576602.jpeg)

＜曲げたとき＞
![IMG_0522.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333380/dc9bbb11-24b6-64f9-5844-98376df2b5e5.jpeg)
一応右のモーターが回っているます。。。
うーんわかりにくい。。。。
下記に動画上げてみましたので、見てみてください。こっちのほうが断然わかりやすい。
Youtube:[ラズパイ3の曲げセンサーを使ったDCモーター駆動](https://www.youtube.com/watch?v=e9IX0xlK4Rw)

<iframe width="560" height="315" src="https://www.youtube.com/embed/e9IX0xlK4Rw" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

#感想
ADコンバーターの値を見ると、曲げたときに800あたりになり、伸ばしたままだと2000くらいだったので、プログラムの通り、一方方向にしか回転させることができなかった。閾値変えれば、正転逆転できますね。