ITmedia NEWS >

Nゲージの模型をラズパイで動かす “らずてつ”その6――センサーで模型をコントロールする名刺サイズの超小型PC「ラズパイ」で遊ぶ(第57回)

» 2022年04月29日 08時00分 公開
[岩泉茂ITmedia]

 前回は線路にセンサーを設置するところまでを解説しました。今回はそのセンサーで模型を制御してみましょう。Pythonのプログラムは前回ご紹介した通り、GPIO ZeroでADコンバーターのMCP3008をコントロールする方が簡単ですので、模型本体とポイントについて、当初のRPi.GPIOによる制御からGPIO Zeroに変更して進めていきます。

 なお、GPIO Zeroを使うことにより、利用している「TPR-105」の接続方法が変わります。「PWM A」「PWM B」として用意されているピンはGPIOではなく3.3Vの端子に接続しますので注意してください。

Raspberry Pi 試験的に作った周回レイアウト

 GPIO Zeroでモーターを使うためには「Motor」というAPIを使います。前後に動かす場合は「forward」と「backword」で指定します。前後に動かすプログラムは以下のようになります。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from gpiozero import Motor
from gpiozero import MCP3008
import time
motor = Motor(forward=20, backward=21)
sen01 = MCP3008(channel=0)
speed = 0.18
time.sleep(1)
motor.forward(speed)
time.sleep(10)
motor.stop()
time.sleep(1)
motor.backward(speed)
time.sleep(10)
motor.stop()
motortest.py

 記述したら動かしてみましょう。

$ python motortest.py

 前後に模型が動いたかと思います。ここで「motor.forward(speed)」と「motor.backward(speed)」と指定していますので、9行目に定義した変数「speed」の数字を増減することでスピードが変わります。「0〜1」までの間で指定します。

 さて、模型を動かす手順が分かったところで、いよいよセンサーによる制御へと移っていきましょう。TPR-105は前回述べたとおり、本体の左側にある赤外線LEDから発光された光を、右側にある反射型フォトトランジスタで受信して値を返します。そこで車両の底に白い紙を貼り付けて赤外線LEDの光を反射させてセンサーで読み取るようにしました。

 まずはどのような値になっているのか調べます。模型をずっと動かし、センサーの上に来たときの値の変化を見てみます。プログラムは以下のようになります。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from gpiozero import Motor
from gpiozero import MCP3008
import time
motor = Motor(forward=20, backward=21)
sen01 = MCP3008(channel=0)
speed = 0.18 # 模型のスピード
time.sleep(1)
try:
    while True:
        rail1 = round(sen01.value * 100,2)
        print (rail1)
        time.sleep(0.05)
        motor.forward(speed)
               
except: KeyboardInterrupt
motor.stop()
movetest.py

 プログラムを保存したら、以下のようにして走らせてみましょう。

$ python movetest.py

 列車が右回りに動いてセンサーの上を通過したときに、以下のようにセンサーからの値が変わるのを確かめられます。なお今回は、モーターのスピードを簡単に変えられるように「speed」という変数を作りました。Ctrl+Cを押すと停止します。

8.06
8.16
8.06
8.16
8.06
8.06
8.16
8.16
8.06
8.16
8.55
9.04
10.31
13.43
19.69
15.1
33.66 ←通過しているところ
33.37 ←通過しているところ
94.24 ←通過しているところ
94.53 ←通過しているところ
34.73 ←通過しているところ
27.6
15.68
9.62
18.42
9.53
9.82
7.87
8.16
8.16
8.16
8.16
8.16
8.16
8.06
8.16
8.06
……(続く)

 続いて、センサーの上を通過すると動きが変わるようにしてみましょう。その際の動作ですが、何もなければ左回りに模型が動くようにし、センサーを通ったらいったん停止して逆行するという形にしました。プログラムは以下の通りです。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from gpiozero import Motor
from gpiozero import MCP3008
import time
motor = Motor(forward=20, backward=21)
sen01 = MCP3008(channel=0)
speed = 0.18 # 模型のスピード
time.sleep(1)
try:
    while True:
        rail1 = round(sen01.value * 100,2)
        print (rail1)
        time.sleep(0.01) #センサーの読み取り間隔
        if rail1 >= 50: # フォトセンサーの返り値が50以上であれば反転
            motor.stop()
            time.sleep(2)
            motor.backward(speed)
            time.sleep(10)
            motor.stop()
            time.sleep(2)
        else:
            motor.forward(speed)
except: KeyboardInterrupt
motor.stop()
movetest2.py

 TPR-105を手で遮ったとき、Maxの状態だと100程度、何もしなければ7〜9程度の値を返しましたので、センサーに捉えられるよう、50以上であれば反転して動作させるようにしてあります。ただし光センサーなので、部屋が明るすぎると反応しないことがあります。その時はフォトセンサーの返り値を大きくするなどして対応してください。

 なお「time.sleep(0.01)」はセンサーの読み取り間隔です。あまり大きくしてしまうとセンサーの反応が鈍くなりますので、値を少なめにしています。

 次回はこれを元に、もう一歩上の動きができるようにしてみます。

Copyright © ITmedia, Inc. All Rights Reserved.