ITmedia NEWS > STUDIO >

Nゲージの模型をラズパイで動かす “らずてつ”その2――制御の準備名刺サイズの超小型PC「ラズパイ」で遊ぶ(第53回)

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

 前回はラズパイと鉄道模型の線路をつなげるところまで進めました。今回はラズパイから指令を出して、鉄道模型を動かすための準備をします。

 前回書いた通り、鉄道模型のモーターはPWMによって動かすことになります。今回はGPIO12番にPWMを設定し、パルス幅を周期で割り算した「デューティー比」を指定することで、電圧を変化させます(MONOistの解説)。

 まずは単純に、前後に模型を動かすことをやってみましょう。TB6612では、以下のように方向を制御できます。

TB6612の方向制御
GPIO20 GPIO21 方向
HIGH LOW 右回りに走る
LOW HIGH 左回りに走る
HIGH HIGH ブレーキ

 基本はこれに従って、GPIO20とGPIO21をそれぞれHIGHにしたりLOWにしたりして方向を制御します。スピードはPWMのデューティー比で決まりますが、あまりにも高いデューティー比だと暴走します。なので「40」くらいでいいかと思います。これを元にして作ったプログラムが以下です。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import RPi.GPIO as GPIO
# GPIOの設定
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
motor_r = 20 # 右回り
motor_l = 21 # 左回り
pwm = 12 # PWM
GPIO.setup(motor_r, GPIO.OUT) 
GPIO.setup(motor_l, GPIO.OUT) 
GPIO.setup(pwm, GPIO.OUT) 
pwm_m = GPIO.PWM(pwm, 100)
pwm_m.start(0)
GPIO.output(motor_r, 0)
GPIO.output(motor_l, 0)
time.sleep(1)
# 右回り
pwm_m.ChangeDutyCycle(0)
GPIO.output(motor_r, 1)
GPIO.output(motor_l, 0)
print ("go forward")
pwm_m.ChangeDutyCycle(40) # ここの「40」を変えると最大速度が変化する
time.sleep(10) # ここの数値を変えると走る距離が変化する
pwm_m.ChangeDutyCycle(0)
# 動作停止
print ("stop")
GPIO.output(motor_r, 1)
GPIO.output(motor_l, 1)
time.sleep(3)
# 左回り
GPIO.output(motor_r, 0)
GPIO.output(motor_l, 1)
print ("go backward")
pwm_m.ChangeDutyCycle(40) # ここの「40」を変えると最大速度が変化する
time.sleep(10) # ここの数値を変えると走る距離が変化する
pwm_m.ChangeDutyCycle(0)
GPIO.output(motor_l, 0)
# 動作停止
print ("stop")
GPIO.output(motor_r, 1)
GPIO.output(motor_l, 1)
pwm_m.stop()
GPIO.cleanup()
test1.py

 「pwm_m.ChangeDutyCycle(40)」とあるところの「40」を増減させると最大スピードが変わります。筆者の持っているキハ30では40くらいがスケールスピードかな、と思いました。「GPIO.output(motor_r, 0)」と「GPIO.output(motor_l, 1)」という箇所の、右側の「1」、「0」を変えると方向が変わります。「1」と「1」にするとブレーキがかかりますので、ピタッと止まるようになります。なお「pwm_m = GPIO.PWM(pwm, 100)」でPWMの周波数を指定していますが(ここでは100Hz)、低いと前照灯や室内灯がちらつきますので、できるだけ上げておいた方がいいです。

 ただしこのプログラムだと模型がいきなりトップスピードで走るので、少し面白くありません。そこで速度を段々と上げたり下げたりして走るようにしてみましょう。数値の変化はloop関数を使って「for i in range」でiの数値を変化させ、それをデューティー比の構文「pwm_m.ChangeDutyCycle(i)」と組み合わせればできそうです。for文を入れてtest1.pyを加工したのが以下のプログラムになります。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import RPi.GPIO as GPIO
# GPIOの設定
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
motor_r = 20 # 右回り
motor_l = 21 # 左回り
pwm = 12
GPIO.setup(motor_r, GPIO.OUT) # 右回り
GPIO.setup(motor_l, GPIO.OUT) # 左回り
GPIO.setup(pwm, GPIO.OUT) # PWM
pwm_m = GPIO.PWM(pwm, 100)
pwm_m.start(0)
GPIO.output(motor_r, 0)
GPIO.output(motor_l, 0)
time.sleep(1)
# 右回り
pwm_m.ChangeDutyCycle(0)
GPIO.output(motor_r, 1)
GPIO.output(motor_l, 0)
print ("go forward")
for loop in range(1):
    for i in range(0,40,1): # ここの「40」を変えると最大速度が変化する
        pwm_m.ChangeDutyCycle(i)
        time.sleep(0.1)
    
    time.sleep(10) # ここの数値を変えると走る距離が変化する
    for i in range(40,0,-1): # ここの「40」を変えると最大速度が変化する
        pwm_m.ChangeDutyCycle(i)
        time.sleep(0.1)
time.sleep(3)
pwm_m.ChangeDutyCycle(0)
# 動作停止
print ("stop")
GPIO.output(motor_r, 1)
GPIO.output(motor_l, 1)
# 左回り
GPIO.output(motor_r, 0)
GPIO.output(motor_l, 1)
print ("go backward")
for loop in range(1):
    for i in range(0,40,1): # ここの「40」を変えると最大速度が変化する
        pwm_m.ChangeDutyCycle(i)
        time.sleep(0.1)
    time.sleep(10) # ここの数値を変えると走る距離が変化する
    for i in range(40,0,-1): # ここの「40」を変えると最大速度が変化する
        pwm_m.ChangeDutyCycle(i)
        time.sleep(0.1)
#    time.sleep(3)
pwm_m.ChangeDutyCycle(0)
# 動作停止
print ("stop")
GPIO.output(motor_r, 1)
GPIO.output(motor_l, 1)
pwm_m.stop()
GPIO.cleanup()
test1.py

 いかがでしょうか。ゆっくりとスタートしてゆっくりと止まるようになりました。これで鉄道模型のコントロールがワンランクアップした気がします。次回はラズパイでポイントをコントロールする仕組みについて考えていきたいと思っています。

Copyright © ITmedia, Inc. All Rights Reserved.