今回はラズパイで動くラジコン(ラズパイカー)をスマホで操作できるようにしてみます。
WebIOPiというものを活用することでスマホのブラウザからラズパイのGPIOを操作制御することが可能になります!
ただし注意事項としては同一ネットワーク内(ラズパイとスマホが同じWi-Fiを利用)の場合に動くようになっています。
早速進めていきましょう!
ラズパイでラジコンを動かしてみる
まずはラズパイでラジコンを動かすところまで進めます。
まだ作成できていない方は最初にラズパイと接続しているキーボードから操作できるようにしてみましょう。
必要な材料やラズパイカーの作成方法はこちらの記事にすべて載せています。
Vol.1 ラズパイとPythonでラジコンを作ってみる
ここまで進められたら今回の目的であるWebIOPiを利用してスマホでラズパイカーを操作できるようにしていきます。
WebIOPiのインストール
WebIOPiというのはRaspberryPiにインストールすることで、webサーバーを立ててブラウザからGPIOの操作やプログラムの実行をしてくれる便利なモジュールです。
早速インストールをしていきましょう。
WebIOPiをダウンロードします。
wget https://sourceforge.net/projects/webiopi/files/WebIOPi-0.7.1.tar.gz
ダウンロードしたものは圧縮ファイルなので解凍して、そのディレクトリに移動します。
tar xvzf WebIOPi-0.7.1.tar.gz
cd WebIOPi-0.7.1
WebIOPiのソースコードをダウンロードします。以下のコマンドを実行して、WebIOPiのパッチファイルをダウンロードします。
ダウンロードしたパッチファイルを使用して、WebIOPiに必要な修正を適用します。以下のコマンドを実行して、パッチを適用します。
wget https://raw.githubusercontent.com/doublebind/raspi/master/webiopi-pi2bplus.patch
patch -p1 -i webiopi-pi2bplus.patch
次にビルドスクリプトの実行します。
途中で「Do you want to access WebIOPi over Internet ? [y/n]」と表示されたら「n」を入力します。
sudo ./setup.sh
以下のコマンドを実行してサービスユニットファイルをダウンロードします。
cd /etc/systemd/system/
sudo wget https://raw.githubusercontent.com/doublebind/raspi/master/webiopi.service
WebIOPiのインストールはこれで完了です。
一部設定ファイルの変更もあるのでこの後進めていきます。
WebIOPiの起動と終了のコマンド一覧
これらのサービス操作コマンドを使用することで、WebIOPiを柔軟に制御できます。必要に応じて、サービスの起動や停止を手動で行ったり、状態を確認したり、再起動したりできます。
WebIOPiサービスを手動で起動するには、次のコマンドを実行します。
sudo systemctl start webiopi
WebIOPiサービスを手動で停止するには、以下のコマンドを使用します。
sudo systemctl stop webiopi
Webサーバが正常に起動しているかどうかを確認するには、次のコマンドを使用します。
このコマンドにより、WebIOPiサービスの現在の状態が表示されます。エラーや問題が発生した場合、ここで詳細情報を確認できます。
sudo systemctl status webiopi
サービスを停止してから再起動するには、次のコマンドを使用します。
このコマンドは、サービスの停止と再起動を一連の操作として実行します。サービスの設定が変更された場合などに便利です。
sudo systemctl restart webiopi
WebIOPiのインストールが完了したのでWebIOPiに接続できるか確認しましょう。
WebIOPiの設定ファイルの編集と接続確認
WebIOPiの設定ファイルを編集して、動作やセキュリティ設定をカスタマイズすることができます。以下の手順に従って、設定ファイルを編集します。
設定ファイルを編集するには、お好きなテキストエディタを使用して、以下のコマンドを実行します。
sudo vim /etc/webiopi/config
設定ファイル内の [SCRIPTS]
セクションに、動作させたいPythonプログラムを指定します。
この設定を追加することで、WebIOPiは myscript
という名前で指定したPythonスクリプトを実行できるようになります。
[SCRIPTS]
myscript = /home/pi/WebIOPi-0.7.1/htdocs/raspi_car_sp.py
WebIOPiのドキュメントルートを変更することで、Webサーバが提供するコンテンツのディレクトリを指定できます。設定ファイル内で、doc-root
の行を適切に変更します。
doc-root = /home/vivi/WebIOPi-0.7.1/htdocs
ログイン画面を非表示にする場合、設定ファイル内の passwd-file
の行をコメントアウトします。行の先頭に #
を追加することで、この行が無効になります。
# passwd-file = /etc/webiopi/passwd
全部編集できたら、[esc]キーを押して、[:wq]を入力してEnterをクリックすると保存されます。
WebIOPiの動作確認をします。
ブラウザからhttp://raspberrypi.local:8000/にアクセスします。
アクセスして次の画像が表示されたらOKです!
ラズパイカーを動かすプログラムファイルの作成
WebIOPiの準備は一通り作成完了したので、あとはラズパイカーを動かすためのプログラムとファイルを用意します。
用意するファイルは3つです。
- index.html
スマホのブラウザに表示する操作画面用のHTMLファイルです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ラズパイカメラ付きラジコン</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="/webiopi.js"></script>
<script type="text/javascript" src="motor.js"></script>
<style>
/* スタイルの追加 */
.button-row {
list-style-type: none;
padding: 0;
margin: 0;
text-align: center;
}
.button {
display: inline-block;
width: 100px;
height: 100px;
background-color: #3498db;
color: #ffffff;
font-size: 18px;
margin: 10px;
cursor: pointer;
}
.a, .b, .c, .d, .e {
display: block;
}
</style>
</head>
<body>
<main>
<div class="button-container">
<div class="button-row">
<button id="forward" class="button">前進</button>
</div>
<div class="button-row">
<button id="left" class="button">左旋回</button>
<button id="stop" class="button">停止</button>
<button id="right" class="button">右旋回</button>
</div>
<div class="button-row">
<button id="backward" class="button">後退</button>
</div>
</div>
</main>
</body>
</html>
- motor.js
HTMLファイルで操作されたボタンをPython側にリクエストするための処理ファイルです。
w().ready(function() {
var motor = "STOP";
// 「前進」ボタンが押されたときのイベント処理
$('#forward').bind(BUTTON_DOWN, function(event) {
// 押されたとき
if(motor == "STOP") {
$(this).addClass('ledon');
change_motor('FOWARD');
}
}).bind(BUTTON_UP, function(event) {
// 離したとき
$(this).removeClass('ledon');
change_motor('STOP');
});
// 「後退」ボタンが押されたときのイベント処理
$('#backward').bind(BUTTON_DOWN, function(event) {
if(motor == "STOP") {
$(this).addClass('ledon');
change_motor('BACKWARD');
}
}).bind(BUTTON_UP, function(event) {
$(this).removeClass('ledon');
change_motor('STOP');
});
// 「右」ボタンが押されたときのイベント処理
$('#right').bind(BUTTON_DOWN, function(event) {
if(motor == "STOP") {
$(this).addClass('ledon');
change_motor('RIGHT');
}
}).bind(BUTTON_UP, function(event) {
$(this).removeClass('ledon');
change_motor('STOP');
});
// 「左」ボタンが押されたときのイベント処理
$('#left').bind(BUTTON_DOWN, function(event) {
if(motor == "STOP") {
$(this).addClass('ledon');
change_motor('LEFT');
}
}).bind(BUTTON_UP, function(event) {
$(this).removeClass('ledon');
change_motor('STOP');
});
// 関数:モーターを動かすマクロ呼び出し
function change_motor(type) {
motor = type;
if(type == "FOWARD") { // 前進
w().callMacro('FW');
} else if(type == "BACKWARD") { // 後進
w().callMacro('BK');
} else if(type == "RIGHT") { // 右旋回
w().callMacro('RT');
} else if(type == "LEFT") { // 左旋回
w().callMacro('LT');
} else if(type == "STOP") { // 停止
w().callMacro('ST');
}
}
});
- raspi_car_sp.py
jsファイルから来たリクエストを元にラズパイのGPIOを制御するPythonファイルです。
# coding: utf-8
## inport文
import webiopi
import RPi.GPIO as GPIO
## 初期化
GPIO.setmode(GPIO.BCM)
motorGpioA1 = 18
motorGpioA2 = 23
motorGpioB1 = 24
motorGpioB2 = 13
def setup():
GPIO.setup(motorGpioA1, GPIO.OUT)
GPIO.setup(motorGpioA2, GPIO.OUT)
GPIO.setup(motorGpioB1, GPIO.OUT)
GPIO.setup(motorGpioB2, GPIO.OUT)
## 以下マクロ 前進
@webiopi.macro
def FW():
print("saaaaaaaaaaa")
GPIO.output(motorGpioA1,True)
GPIO.output(motorGpioA2,False)
GPIO.output(motorGpioB1,True)
GPIO.output(motorGpioB2,False)
## 後退
@webiopi.macro
def BK():
GPIO.output(motorGpioA1,False)
GPIO.output(motorGpioA2,True)
GPIO.output(motorGpioB1,False)
GPIO.output(motorGpioB2,True)
## 左旋回
@webiopi.macro
def LT():
GPIO.output(motorGpioA1,False)
GPIO.output(motorGpioA2,True)
GPIO.output(motorGpioB1,True)
GPIO.output(motorGpioB2,False)
## 右旋回
@webiopi.macro
def RT():
GPIO.output(motorGpioA1,True)
GPIO.output(motorGpioA2,False)
GPIO.output(motorGpioB1,False)
GPIO.output(motorGpioB2,True)
## 停止
@webiopi.macro
def ST():
GPIO.output(motorGpioA1,False)
GPIO.output(motorGpioA2,False)
GPIO.output(motorGpioB1,False)
GPIO.output(motorGpioB2,False)
作成できたら3つのファイルをすべて次のフォルダに置きます。
/home/pi/WebIOPi-0.7.1/htdocs/
ファイルが設置できたらあとはWebIOPiを起動して完了です!
スマホでラズパイカーを動かす
作成できたら次のリンクをスマホのブラウザで開いてみましょう!
http://ラズベリーパイのIPアドレス:8000/
そうすると次のような画面になります。
ボタンを押している間はその動作を続ける処理になっているので、カスタマイズしたい方はそれぞれのファイルの処理を変更してみてください。
実際に動かしてみた動画がこちらになります。
これでスマホでラズパイカーの操作が簡単になりました!
スマホで操作できることで活用の幅が広がりますね、できれば同一ネットワーク内だけでなく外からも操作できるようになるともっと楽しくなりそうですね!
参考にしたサイト
WebIOPiなどの実装を進めるにあたって参考にさせていただいたサイトになります。
https://dev.classmethod.jp/articles/webiopi-raspberry-pi-gpio-operation/
https://maausa.marurm.com/raspi-webiopi/
https://elchika.com/article/da0ba267-1f0d-4104-ace4-56edf804ebe4/