Raspberry PiでIoTを始めよう企画
紙相撲が無駄にIoTになった!~Raspberry Piで始めるIoTデバイス入門
IoT実装編
さて、いよいよこの自作ハードを、Raspberry Piに接続。IoTデバイスとして仕上げていきます。
この先はソフトウェアの作業になります。工程を追って見ていただくより、完成したコードを解説していったほうが分かりやすいかもしれませんね。
まずはWebIOPiの設定ファイルから。/etc/webiopi/configを開いて、以下の2行だけ書き換えました。
myscript = /home/pi/sumo/python/script.py doc-root = /home/pi/sumo/html
myscriptというのが、先に説明した、Arduinoでいうとスケッチに相当するPythonスクリプトのパスです。doc-rootはブラウザで表示するHTMLファイルのパスです。ホームディレクトリにsumoディレクトリを作って、そこにすべてのファイルをまとめています。
つづいて心臓部。script.pyの中身です。
# -*- coding: utf-8 -*- import webiopi GPIO = webiopi.GPIO #プレーヤーごとの設定 #ボタンに対応するサーボの角度 angles = {"0":[45, 15, -15, -45, -75], "1":[-75, -45, -15, 15, 45]} #サーボ制御に使用するGPIOピン番号 pwmPin = {"0":8, "1":9} #ソレノイド制御に使用するGPIOピン番号 tapPin = {"0":3, "1":4} def setup(): #GPIOピンの動作モード設定 for v in pwmPin.values(): GPIO.setFunction(v, GPIO.PWM) #サーボをセンターに GPIO.pulseAngle(v, -15) for v in tapPin.values(): GPIO.setFunction(v, GPIO.OUT) def loop(): webiopi.sleep(1) def destroy(): #GPIOピンをINに戻しておく for v in pwmPin.values(): GPIO.setFunction(v, GPIO.IN) for v in tapPin.values(): GPIO.setFunction(v, GPIO.IN) def tap(player, count): #指定回数だけソレノイドを動かす for i in range(count): GPIO.digitalWrite(tapPin[player], GPIO.HIGH) webiopi.sleep(0.1) GPIO.digitalWrite(tapPin[player], GPIO.LOW) webiopi.sleep(0.2) @webiopi.macro def pwm(player, position = "2"): #サーボを動かして土俵をたたくマクロ GPIO.pulseAngle(pwmPin[player], angles[player][int(position)]) webiopi.sleep(0.3) tap(player, 3)
順にご紹介していきましょう。
# -*- coding: utf-8 -*- import webiopi GPIO = webiopi.GPIO
この辺は、おまじないみたいなものですね。このスクリプトはUTF-8で書かれていて、WebIOPiを使いますよ、あと今後GPIOって言ったらWebIOPiのGPIO機能のことですよ、ということを言っています。
#プレーヤーごとの設定 #ボタンに対応するサーボの角度 angles = {"0":[45, 15, -15, -45, -75], "1":[-75, -45, -15, 15, 45]}
サーボの回転角度を決めています。今回は、
こんな感じで、(1)~(5)のボタンが押されると、土俵の対応した位置をたたくようにしています。この1~5を、何度の位置にするか、というのをプレーヤー2人分決めています。
(ちなみに真ん中の3が0度になっていないのは使っているサーボによりパルス信号の解釈が違うからだと思います。たぶん……。ここは実際に動かしながら調節するしかないです)
#サーボ制御に使用するGPIOピン番号 pwmPin = {"0":8, "1":9} #ソレノイド制御に使用するGPIOピン番号 tapPin = {"0":3, "1":4}
ここでは、どのGPIOピンにどの部品を接続するか決めています。
続いて、いよいよ初期化処理です。
def setup(): #GPIOピンの動作モード設定 for v in pwmPin.values(): GPIO.setFunction(v, GPIO.PWM) #サーボをセンターに GPIO.pulseAngle(v, -15)
サーボ用のGPIOピンの初期化です。PWMモード(パルス信号を送るモード)にして、サーボの角度をセンターに合わせます。
for v in tapPin.values(): GPIO.setFunction(v, GPIO.OUT)
ソレノイド用のGPIOピンの初期化です。出力モードにします。
ここまでが初期化処理で、次が待機処理ですね。
def loop(): webiopi.sleep(1)
今回は待機処理は特にありません。のでスリープ(何もしない)だけを入れています。
この後は、Webサーバを終了させたときの後片付けについて書いてあります。
def destroy(): #GPIOピンをINに戻しておく for v in pwmPin.values(): GPIO.setFunction(v, GPIO.IN) for v in tapPin.values(): GPIO.setFunction(v, GPIO.IN)
さて、最低限、ここまで書いておけばWebIOPiは動きます。でも、今回はボタン入力によっていろんな動作をさせたいので、この続きにはそのあたりの処理を書いてあります。
def tap(player, count): #指定回数だけソレノイドを動かす for i in range(count): GPIO.digitalWrite(tapPin[player], GPIO.HIGH) webiopi.sleep(0.1) GPIO.digitalWrite(tapPin[player], GPIO.LOW) webiopi.sleep(0.2)
まずはtapという関数を作りました。指定された回数だけ、ソレノイドで土俵をたたきます。
GPIOピンをHIGHにして土俵をたたき、LOWにして戻す、の繰り返しです。
これは次に説明する、pwm関数の中から呼び出します。
@webiopi.macro
これが「ここから先はブラウザ操作で呼び出される関数ですよ」という目印になります。次からが、実際にボタン入力時に呼び出される関数です。
def pwm(player, position = "2"): #サーボを動かして土俵をたたくマクロ GPIO.pulseAngle(pwmPin[player], angles[player][int(position)]) webiopi.sleep(0.3) tap(player, 3)
pwmという関数です。サーボの角度を変えて、少しスリープした後、先ほどのtap関数を呼び出します。
この関数は、ブラウザ上でボタンを押した際に呼び出されます。
というわけでスクリプトの説明は以上です。ちなみに僕はPythonはあまり触ったことがないのですが、それほど苦労せず書くことができました。ほかの言語でのプログラミング経験があれば、難なく動かせると思います。Python未経験者の方は、インデントも文法の一部であることに注意しましょう!