ラズパイ戦車をスマホからコントロールする

シェアする

Pocket

1.pythonでLチカをコントロール

前回の記事(スマホから戦車を直接動かす!準備編/WobIOpiセットアップ)で、WebIOpiを用いてLチカを行ってみました。

確かに、スマホからボタンをクリックすることで、Lチカを実現できましたが、ラズパイのピンに電流を流すだけのことでした。

戦車を動かすには、ボタンをクリックした際、前進、後退などを実現できなければならないので、これだけでは戦車のコントロールはできないですね。

そこで、こちらのページ(WebブラウザからRaspberry Pi のGPIOを操作する(WebIOPi 利用))では、同じLチカでも、pythonとhtmlを使用した例題を載せています。

実際、このページで提示されている内容をやってみると、こんなことができました。

2.戦車のプロトタイプの実行

Lチカはできましたが、戦車に応用するとなると、チェックボックスではなく、ボタンの方が良さそうです。

そして、このボタンに前進、後退・・などの名称を付けて、その動きをさせればいいわけです。

(1) pi zero WH へ WebIOpi をセットアップ

Lチカは、pi3 で実行しました。

しかし、戦車に乗せるにはちいさな筐体がいいので、pi zero WH でコントロールしましょう。

それには、pi zero WH へ WebIOpi をセットアップしなければなりません。

前回の記事に従い、WebIOpiをインストールし、設定用の環境もセットアップします。

(2) プロトタイプの画面

最初から完成形を目指すと時間がかかりそうなので、前進と停止だけを持つプロトタイプを作成してみます。

こんな感じです。

前進を forward、停止を stop にしています。

なんか、デザイン性を全く無視した画面ですが、プロトタイプなので気にしなくともいいでしょう。

HTMLは、次のようになります。

<!DOCTYPE html>
<html>
<head>
    <title>dcmotor</title>
    <script type="text/javascript" src="/webiopi.js"></script>
    <script type="text/javascript">
        function init() {
            var btn0, ct0;
            ct0 = $("#box");
            btn0 = webiopi().createButton("f", "forward", click_forward);
            ct0.append(btn0);
            btn0 = webiopi().createButton("s", "stop", click_stop);
            ct0.append(btn0);
        }
        function click_forward(){
            webiopi().callMacro("forward");
        }
        function click_stop() {
            webiopi().callMacro("stop");
        }
        webiopi().ready(init);
    </script>
    <style type="text/css">
        button{
            display:block;
            margin:5px 5px 5px 5px;
            width:160px;
            height:45px;
            font-size:24pt;
            font-weight:bold;
            color:black;
        }
    </style>
</head>
<body>
    <div id="box" align="center"></div>
    <input type="range" style="width:150px">
</body>
</html>

(3) プロトタイプのプログラム

こちらが、pythonプログラムです。

色々調べましたが、webiopi の pwmWrite 命令を使えばいいようです。ピン番号は、buetoothで動かしたときの回路をそのまま流用しましたので、それをそのまま使用します。

前進は、def forward()、停止は、def stop()で指示しています。

import webiopi

# Debug
webiopi.setDebug()

GPIO = webiopi.GPIO

# GPIO 18,23が左モータ、GPIO 24,25が右モータ

MOTOR_L1 = 18
MOTOR_L2 = 23
MOTOR_R1 = 24
MOTOR_R2 = 25
duty=50

# WebIOPi起動時CALL

def setup():
    webiopi.debug("Script with macros - Setup")
    # GPIOのセットアップ

    GPIO.setFunction(MOTOR_L1, GPIO.PWM)
    GPIO.setFunction(MOTOR_L2, GPIO.PWM)
    GPIO.setFunction(MOTOR_R1, GPIO.PWM)
    GPIO.setFunction(MOTOR_R2, GPIO.PWM)

    # 初期のデューティー比を0%に(静止状態)

    GPIO.pwmWrite(MOTOR_L1, 0)
    GPIO.pwmWrite(MOTOR_L2, 0)
    GPIO.pwmWrite(MOTOR_R1, 0)
    GPIO.pwmWrite(MOTOR_R2, 0)

#

def loop():
    webiopi.sleep(5)

# WebIOPi終了時に呼ばれる関数

def destroy():

    webiopi.debug("Script with macros - Destroy")

    # GPIO関数のリセット(入力にセットすることで行う)

    GPIO.setFunction(MOTOR_L1, GPIO.IN)
    GPIO.setFunction(MOTOR_L2, GPIO.IN)
    GPIO.setFunction(MOTOR_R1, GPIO.IN)
    GPIO.setFunction(MOTOR_R2, GPIO.IN)

#defult function

@webiopi.macro
def forward():
    GPIO.pwmWrite(MOTOR_L1, duty)
    GPIO.pwmWrite(MOTOR_L2, 0)
    GPIO.pwmWrite(MOTOR_R1, duty)
    GPIO.pwmWrite(MOTOR_R2, 0)
    webiopi.debug("foward")

@webiopi.macro
def stop():
    GPIO.pwmWrite(MOTOR_L1, 0)
    GPIO.pwmWrite(MOTOR_L2, 0)
    GPIO.pwmWrite(MOTOR_R1, 0)
    GPIO.pwmWrite(MOTOR_R2, 0)
    webiopi.debug("stop")

(4) プロトタイプ実行

これらをセッティングしたので、WebIOPi サービスの設定を変更します。先ほどの記事に従って、「/etc/webiopi/config」ファイルを設定します。

sudo vi /etc/webiopi/config

[SCRIPTS] セクションの「myscript =」を変更します。

#myscript = /home/pi/webiopi/examples/scripts/macros/script.py
myscript = /home/pi/work/webiopi/script.py

[HTTP] セクションの「doc-root =」、「welcome-file =」を変更します。

#Use doc-root to change default HTML and resource files location
#doc-root = /home/pi/webiopi/examples/scripts/macros
doc-root = /home/pi/work/webiopi/

#Use welcome-file to change the default "Welcome" file
#welcome-file = index.html
welcome-file = index.html

これで、プロタイプ実行の準備ができました。

それでは、WebIOPi のサービスを開始します。

sudo systemctl start webiopi

現在、プロトタイプ中なので、pi zero WH は、直電源で行っているので、キャタピラは取り外しています。

それでは、スマホに画面を出して実行してみます。ラズパイのアドレスに:8000を追加して画面を出します。

http://192.XXX.XXX.XXX:8000

おおっ!!60爺にしては、素直に動きましたね。

3.戦車をスマホからコントロール

それでは、今の考え方を戦車のコントロールに応用してみましょう。

出来上がった戦車は、 ブレッドボードがでかすぎて、ちょっと、格好悪いですね!電池ボックス、ラズパイ電源となるモバイル電池も大きいので武骨な形になってます。

この先、別の戦車を拵えるときは、もっと小さなブレッドボードを使用するようにします。

(1) 戦車コントロール画面

戦車コントロール画面ですが、こんなイメージです。

これを、HTMLで書きます。

左折、右折及び後退のボタンを追加します。合わせて、実行時のマクロの呼び出しを追加します。

また、上記の画面デザインに合わせて、編集を行います。行ごとに載せるボタンの数が違いますので、コードが追加となります。

<!DOCTYPE html>
<html>
<head>
    <title>dcmotor</title>
    <script type="text/javascript" src="/webiopi.js"></script>
    <script type="text/javascript">
        function init() {
            var btn0;
            btn0 = webiopi().createButton("r", "Turn Right", click_right);
            $("#r").append(btn0);
            btn0 = webiopi().createButton("l", "Turn Left", click_left);
            $("#l").append(btn0);
            btn0 = webiopi().createButton("f", "Forward", click_forward);
            $("#f").append(btn0);
            btn0 = webiopi().createButton("b", "Back", click_back);
            $("#b").append(btn0);
            btn0 = webiopi().createButton("s", "Stop", click_stop);
            $("#s").append(btn0);
        }
        function click_right() {
            webiopi().callMacro("right");
        }
        function click_left() {
            webiopi().callMacro("left");
        }
        function click_forward(){
            webiopi().callMacro("forward");
        }
        function click_back(){
            webiopi().callMacro("back");
        }
        function click_stop() {
            webiopi().callMacro("stop");
        }
        webiopi().ready(init);
    </script>
    <style type="text/css">
        button{
            display:block;
            margin:5px 5px 5px 5px;
            width:160px;
            height:100px;
            font-size:24pt;
            font-weight:bold;
            color:black;
        }
    </style>
</head>
<body>
    <div align="center"></div>
        <table>
            <tr>
                <td>
                    <table border=0 cellspacing="10″ cellpadding="0″>
                    <tbody>
                        <tr>
                            <td> </td>
                            <td><div id="f"></div></td>
                            <td> </td>
                        </tr>
                        <tr>
                            <td><div id="l"></div></td>
                            <td><div id="s"></div></td>
                            <td><div id="r"></div></td>
                        </tr>
                        <tr>
                            <td> </td>
                            <td><div id="b"></div></td>
                            <td> </td>
                        </tr>
                    </tbody>
                    </table>
                </td>
            </tr>
        </table>
    </div>
</body>
</html>

(2) pythonプログラム

そして、これらのボタンがクリックされた際のpythonプログラムがこちらです。

プロトタイプのプログラムに、右折(Turn Right)、左折(Turn Left)、後退(Back)を追加します。

import webiopi

# Debug
webiopi.setDebug()

GPIO = webiopi.GPIO

# GPIO 18,23が左モータ、GPIO 24,25が右モータ

MOTOR_L1 = 18
MOTOR_L2 = 23
MOTOR_R1 = 24
MOTOR_R2 = 25
duty=50

# WebIOPi起動時CALL

def setup():
    webiopi.debug("Script with macros - Setup")
    # GPIOのセットアップ

    GPIO.setFunction(MOTOR_L1, GPIO.PWM)
    GPIO.setFunction(MOTOR_L2, GPIO.PWM)
    GPIO.setFunction(MOTOR_R1, GPIO.PWM)
    GPIO.setFunction(MOTOR_R2, GPIO.PWM)

    # 静止状態

    GPIO.pwmWrite(MOTOR_L1, 0)
    GPIO.pwmWrite(MOTOR_L2, 0)
    GPIO.pwmWrite(MOTOR_R1, 0)
    GPIO.pwmWrite(MOTOR_R2, 0)

#

def loop():
    webiopi.sleep(5)

# WebIOPi終了時

def destroy():

    webiopi.debug("Script with macros - Destroy")

    # GPIO関数のリセット(入力にセットすることで行う)

    GPIO.setFunction(MOTOR_L1, GPIO.IN)
    GPIO.setFunction(MOTOR_L2, GPIO.IN)
    GPIO.setFunction(MOTOR_R1, GPIO.IN)
    GPIO.setFunction(MOTOR_R2, GPIO.IN)

#defult function

@webiopi.macro
def forward():
    GPIO.pwmWrite(MOTOR_L1, duty)
    GPIO.pwmWrite(MOTOR_L2, 0)
    GPIO.pwmWrite(MOTOR_R1, duty)
    GPIO.pwmWrite(MOTOR_R2, 0)
    webiopi.debug("foward")

@webiopi.macro
def left():
    GPIO.pwmWrite(MOTOR_L1, 0)
    GPIO.pwmWrite(MOTOR_L2, duty)
    GPIO.pwmWrite(MOTOR_R1, duty)
    GPIO.pwmWrite(MOTOR_R2, 0)
    webiopi.debug("left")

@webiopi.macro
def stop():
    GPIO.pwmWrite(MOTOR_L1, 0)
    GPIO.pwmWrite(MOTOR_L2, 0)
    GPIO.pwmWrite(MOTOR_R1, 0)
    GPIO.pwmWrite(MOTOR_R2, 0)
    webiopi.debug("stop")

@webiopi.macro
def right():
    GPIO.pwmWrite(MOTOR_L1, duty)
    GPIO.pwmWrite(MOTOR_L2, 0)
    GPIO.pwmWrite(MOTOR_R1, 0)
    GPIO.pwmWrite(MOTOR_R2, duty)
    webiopi.debug("right")

@webiopi.macro
def back():
    GPIO.pwmWrite(MOTOR_L1, 0)
    GPIO.pwmWrite(MOTOR_L2, duty)
    GPIO.pwmWrite(MOTOR_R1, 0)
    GPIO.pwmWrite(MOTOR_R2, duty)
    webiopi.debug("back")

(3) スマホから戦車をリモートコントロール

上記で示した通り、/etc/webiopi/config の内容を設定します。

それでは、戦車をスマホからコントロールしてみましょう。
動画を載せますので見てください。

動きが鈍い感じもしますが、まア、こんなものでしょう!

参考にしたページはこちらです。

Raspberry Pi でブラウザから操作できるラジコン戦車を作る! – WebIOPi から DC モーターを制御する –

『RaspberryPiで学ぶ電子工作』でラジコン操作につまったときの対処 その3

スポンサーリンク

シェアする

フォローする