ラズパイ電子工作～PWM制御を用いた簡易扇風機～

この記事は[リンク情報システム](https://www.lis.co.jp/)の「[2019 Tech Connect Summer](https://qiita.com/dgkz/items/2862d5e6b77203a126b3)」のリレー記事です。
engineer.hanzomonのグループメンバーによってリレーされます。

(リンク情報システムのFacebookは[コチラ](https://ja-jp.facebook.com/lis.co.jp/))

今日で5日目………筆者は私@t_slash_kです。
ふぇぇ………暑い……けど…………頑張る………………！
………ということで本日はそんな暑い夏を少しでも快適に過ごせるように、
「Raspberry Pi 3」と「PWM制御」を用いてモーターを制御する扇風機を製作してみました。記事の内容も割と**箸休め**的部分が大きいので、読みながら涼んでいってください。~~くれぐれも体調は壊さないように。~~

##1.扇風機の仕様
####仕様
「ラズパイで扇風機を作ろう！」といっても、「ただスイッチを入れたら扇風機の羽が回る」だけのものならわざわざラズパイを使わなくてもモーターとスイッチと電源と配線材があればすぐに出来上がります。それではラズパイを使う意味がないので、以下の仕様を追加しました。
・4段階の風量調節(後述のPWM制御を用いる)
・1つの押ボタンスイッチを押す度に「扇風機の回転／停止」及び
「4段階の風量調節」をおこなう(市販のハンディ扇風機によくある仕様)
・現在の扇風機の状態をコンソールで表示

####PWM制御とは
**ラズパイの出力はデジタル方式**なので、オン／オフの2通りしか出力できません。そこで、**PWM**(Pulse Width Modulation：パルス変調)という出力方式を用いることで、**擬似的にアナログ方式の出力**を行います。
PWMの仕組みとしては、**出力のオン／オフの切り替えを高速で行い、1周期のうちの「オンの時間の長さ」に比例した任意の電圧を出力することで擬似的なアナログ出力を得る**といった感じです。
本記事ではこのPWMを用いて、扇風機の羽を回すモーターの回転数を制御していきます。

##2.用意／準備したもの
* Raspberry Pi 3 Model B(ラズパイ)及びラズパイ用の電源
* FA‐130モーター(FA-130RAでも可)
* 3枚プロペラ(小)
* 単3電池2本用電池ボックス×2(単3×4電池ボックスでも可)
* 単3電池×4
* コンデンサ 0.1μF
* 抵抗 5.1kΩ
* タクトスイッチ(押ボタンスイッチ)
* モータードライバー TA7291P
* ブレッドボード
* ジャンパワイヤ(オス～オス)(オス～メス)
* はんだごて＆はんだ
* 両面テープ
* カップ焼きそばの容器

##3.ラズパイ側の準備
####初期設定
ラズパイを動かすにはまず初期設定として「Raspbian」をインストールする必要がありますが、この方法についてはラズパイ関連の書籍には必ずと言っていいほど記載されていますし、ネットの海にごろごろ転がっているためここでは割愛します。
なんなら、最近は秋葉原に行けば**「OS書き込み済Raspberry Piスターターセット」**なるお得セットが店頭に陳列されています。便利な世の中になったなぁ…

####インターフェースの準備
ラズパイで電子回路を制御するには、 **GPIO** (General Purpose Input/Output)とよばれる 
インターフェースを利用します。このGPIOをプログラムで操作するには、関連するライブラリが必要となります。そのライブラリとしてraspberry-gpio-python(RPi.GPIO)がラズパイには標準でインストールされているされていますが、今回は「WiringPi」と呼ばれるライブラリを用いているため、以下のコマンドを実行してWiringPiをインストールしておきます。

```
$ sudo pip3 install wiringpi
```

####GPIOピンとラズパイピンの対応図
**ラズパイピンの端子番号とGPIOの番号は違う**ため、以下に対応図を示します。
![ラズパイピンとGPIOの端子対応図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317905/971d0007-622b-e287-4800-229a69f72c56.png)


##4.扇風機の製作
####回路について
今回製作する扇風機の回路図を以下に示します。
![回路図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317905/ea3f6bef-afb9-e789-d62d-1d48654a7c58.png)


まずは前提として、<font color="Red">モーターの動作には数百mA~数十Aの大電流を消費</font>します。そんな大電流を流したら<font color="Red">ラズパイ自体が停止する</font>か、最悪<font color="Red">壊れる</font>リスクがあります。つまり何が言いたいかと言うと、**モーターはラズパイで直接制御できません。**
そこで今回は**TA7291P**というモータードライバーを介して、ラズパイでのモーター制御を行うようにしました。[データシートはこちらから。](https://toshiba.semicon-storage.com/jp/product/linear/motordriver/detail.TA7291P.html)
また、モーターにはノイズ軽減用のコンデンサーを、モータードライバーのVrefには電流制限用の抵抗をつけておきます。

####実際に組み立て
1.ノイズ軽減用のコンデンサーをモーターの端子にはんだ付けします。![IMG_0449.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317905/123f1712-3935-8839-1860-6c06fc466b9e.jpeg)
2.回路図の通りに、ブレッドボードに回路を組んでいきます。ここでポイントを1点。
・モータードライバー「TA7291P」は1列に10本のピンが並んだ形状となっていますが、金属の角の部分の切り欠きが大きいほうの端のピンが1番ピンとなります。以降はのピン配置は単純に順送りとなっています。~~データシート見れば何言いたいかは大体わかるはず~~
3.配線が終わったら、モーター、電池ボックス、ブレッドボードをカップ焼きそばの容器に両面テープで固定します。この際、モーターの軸にプロペラも取り付けてしまいます。
![IMG_0453.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317905/c992ba7c-b3b3-63ab-36eb-f61a7740a130.jpeg)


##5.ソースコードの説明
ソースコード及びソースコードの説明について、以下に記述します。
なお、ソースコードはpythonを使って書きました。

```python

# ライブラリのインポート
import RPi.GPIO as GPIO
import wiringpi as pi
import time

# スイッチを接続したGPIOピンの定義
POWER_SW_PIN = 4

# モータードライバーを接続したGPIOピンの定義
IN1_MOTOR_PIN = 23
IN2_MOTOR_PIN = 24

# 各種設定
pi.wiringPiSetupGpio()
pi.pinMode( POWER_SW_PIN, pi.INPUT )
pi.pinMode( IN1_MOTOR_PIN, pi.OUTPUT )
pi.pinMode( IN2_MOTOR_PIN, pi.OUTPUT )
pi.pullUpDnControl( POWER_SW_PIN, pi.PUD_DOWN )

# モータードライバを接続したGPIOをPWM出力できるようにする
pi.softPwmCreate( IN1_MOTOR_PIN, 0, 100 )
pi.softPwmCreate( IN2_MOTOR_PIN, 0, 100 )

# モーターを停止した状態にする
pi.softPwmWrite( IN1_MOTOR_PIN, 0 )
pi.softPwmWrite( IN2_MOTOR_PIN, 0 )

# ボタンが押された回数を初期化
countPower = 0

# 正常処理
try:
    while True:
        # ボタンが押されたらif文内の処理を実行
        if ( pi.digitalRead( POWER_SW_PIN ) == pi.HIGH ):
            time.sleep( 0.5 )
            
            # ボタンが押された回数のカウントを1つ上げる
            countPower = countPower + 1
            
            # ボタンが押された回数によってモーターの制御を分岐
            if countPower % 5 == 1:
                pi.softPwmWrite( IN1_MOTOR_PIN, 0 )
                pi.softPwmWrite( IN2_MOTOR_PIN, 25 )
                print("微風")
            elif countPower % 5 == 2:
                pi.softPwmWrite( IN1_MOTOR_PIN, 0 )
                pi.softPwmWrite( IN2_MOTOR_PIN, 50 )
                print("弱風")
            elif countPower % 5 == 3:
                pi.softPwmWrite( IN1_MOTOR_PIN, 0 )
                pi.softPwmWrite( IN2_MOTOR_PIN, 75 )
                print("強風")
            elif countPower % 5 == 4:
                pi.softPwmWrite( IN1_MOTOR_PIN, 0 )
                pi.softPwmWrite( IN2_MOTOR_PIN, 100 )
                print("最大")
            else:
                pi.softPwmWrite( IN1_MOTOR_PIN, 100 )
                pi.softPwmWrite( IN2_MOTOR_PIN, 100 )
                print("停止\n")
            
            # スイッチのチャタリング防止
            while ( pi.digitalRead( POWER_SW_PIN ) == pi.LOW ):
                time.sleep( 0.1 )

            time.sleep( 0.1 )

# プログラム強制終了時にモーターを止める                        
except KeyboardInterrupt:
    pi.softPwmWrite( IN1_MOTOR_PIN, 0 )
    pi.softPwmWrite( IN2_MOTOR_PIN, 0 )
    print("Stop")

```
~~ソースコードのコメント文で説明しきれなかった~~特筆すべき点として、
・「#各種設定」の処理は上から順に
　・「GPIOの初期化」
　・「スイッチを接続したGPIOピンを入力モードに指定」
　・「モータードライバのIN1に接続した端子を出力モードに指定」
　・「モータードライバのIN2に接続した端子を出力モードに指定」
　・「スイッチを接続したGPIOピンのプルダウン抵抗を有効化」
　となっております。
・「# ボタンが押された回数によってモーターの制御を分岐」について、現在のソースコードではプロペラは左回転します。右回転にしたい場合は、「pi.softPwmWrite()」内の第2引数の数字をIN1とIN2で逆にすることで実現できます。


##6.実行~涼んでみよう~
回路の組み立て及びソースコードの準備が完了したらさっそくプログラムを実行してみましょう。
実行しただけだとモーターは停止状態のままになっています。その状態で、押ボタンスイッチを1回押します。すると……
![IMG_0454.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317905/47602309-3cf1-7fb2-a5e9-da641c6795af.jpeg)

モーターが回り始め、プロペラから風が出てきます。押ボタンスイッチを押すたびに、**「微風→弱風→強風→最大風→停止→微風・・・」**と、風量の状態が切り替わります。プログラムを終了すると扇風機も止まります。これらの状態はコンソール上でも確認できます(下図)。
![2019-07-15-135506_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317905/a715dbe4-feac-dddf-50fb-32937b1f6755.png)


**………………とにかく、めっちゃ涼しい！**

##7.おわりに
筆者は小～中学生の頃から趣味でちょくちょく電子工作をしていました(~~最近はあまりしていなかったのですが~~)。
今回の記事執筆を通して「Raspberry Piを用いての電子工作」というものに触れて、<font color=blue>「電子工作の形態の多様化」</font>と<font color=blue>「自分もしかしたらこんなものも作れるかもしれない」という自分への新たな可能性</font>を改めて感じました。**ぶっちゃけ楽しかったです。**今後も続けていきたいです。

最後に、夏休みの宿題の「自由研究」のネタに悩んでいるであろう小中学生の皆さん。電子工作やロボット工作などの「ものづくり」を通して童心に帰りたい大人の皆さん。~~筆者と同じように「手軽に楽しく技術スキルを上げたい」と考えている皆さん。~~<font color=blue>**この機会にラズパイ電子工作に触れてみるのはいかがでしょうか。**</font>
特に小学生の皆さんは2020年度には小学校でプログラミング教育が必修化されるみたいだし………

(P.S.)明日は@taisuke3さんが記事執筆を担当します。