今回は、
サーボモータにカメラを取り付け、
遠隔ブラウザからカメラ画像を見ながら、カメラを動かしていきます。
遠隔からモノを動かすって夢がありますよね。
使い方としては、
ペットとか、動きのあるモノでも追従して
遠隔から見ることが出来るよ。
あなたなら、何に使ってみます?
この記事で学べること。
- IoT
- マイコン
- Linux
- Python
- HTML
- カメラ制御
- モータ制御
やりたいこと
・ラズパイに接続したカメラ映像を、スマホのブラウザで見る
・ラズパイに接続したモータを、スマホのブラウザから操作する
システム構成図
やることリスト
上記の「やりたいこと」をみて、
どんな作業が必要か、自分で項目を考えてみてください。
これを考えることで、「プログラミング的思考」が身に付いていきます。
番号 | 作業項目 | 備考 |
1 | やりたいこと・システム構成図の作成 | |
2 | やることリストの作成 | 処理項目の洗い出し |
3 | 部品の準備 | |
4 | ラズパイ専用カメラ画像をスマホで見る | MJPG-streamingライブラリ |
5 | サーボモータ制御 | |
6 | ブラウザからモータを動かす | |
7 | まとめ | 以上の機能をまとめて、 やりたいことを実現する! |
部品の準備
今回のシステムに必要な部品です。
不足している部品があれば購入下さい。
部品名 | |
Raspberry Pi | 別途、電源・SDカード・HDMIケーブルが必要です。 |
Raspberry Pi用遠隔操作カメラキット | |
ジャンパー線(※1) | オスーメス:6本 |
購入に必要な部品を、
Raspberry Pi 関連に記載しています。
ラズパイは、電源を入れただけでは起動しません。
ラズパイの起動手順の記事を参照ください。
ラズパイ専用カメラ画像をスマホで見る
ラズパイとカメラ接続
以下図の通り、ラズパイとカメラを接続します。
接続方法は、カメラコネクタの両脇のツメを引き上げ、
ケーブルの青い面を LANコネクタ側に向けて、奥まで差し込ます。
カメラコネクタの両脇のツメを押し下げてケーブルを固定します。
カメラ機能の有効化
ラズパイ専用カメラを使う為に、カメラ機能を有効にします。
左上の「ラズパイアイコン」 → 「設定」→「Raspberry Piの設定」を選択。
「インターフェイス」タブ → カメラの有効/無効ボタンを「有効」を選択し、
画面右下の「OK」ボタン(画面切れてますが・・・)を押します。
ラズパイを再起動すると設定が反映されます。
カメラの画像をスマホで見る
以下記事「カメラの画像をスマホで見る」の章を
参照ください。
サーボモータ制御
以下記事「サーボモータ制御」の章を
参照ください。
ブラウザからモータを動かす
ブラウザの画面とラズパイ間でデータのやり取りを行う為に、Flaskを使用します。
Flaskは、Python用のWebアプリケーションフレームワークです。
Webアプリケーションフレームワークとは、
ウェブサイト、Webアプリケーション等の作成をサポートする為のフレームワーク(ソフト)です。
以下コマンドでラズパイにFlaskをインストールする。
pip3 install flask
プログラム
以下ディレクトリ通り、ディレクトリとファイルを作成する。
この章では、以下赤字のファイルを修正する。
/home/pi/work/camera/ ├app.py ├servo.sh └templates/ └index.html
app.py
# -*- coding: utf-8 -*-
from flask import Flask, render_template, request
import servo
app = Flask(__name__)
DEGREE_MAX = 30
DEGREE_MIN = -30
DEGREE_MOVE = 5
# 上下
servo_0 = servo.Servo(servo.PWM0_GPIO)
# 左右
servo_1 = servo.Servo(servo.PWM1_GPIO)
servo_0_degree = 0
servo_1_degree = 0
# ブラウザに画面を表示
@app.route('/', methods=['GET'])
def get():
return render_template('index.html')
# ブラウザからのデータ取得
@app.route('/', methods=['POST'])
def index():
global servo_0_degree
global servo_1_degree
servo_action = request.form.get('servo_action')
print(servo_action)
if servo_action == '●':
servo_0_degree = 0
servo_1_degree = 0
servo_0.set_degree(servo_0_degree)
servo_1.set_degree(servo_1_degree)
elif servo_action == '↑':
if DEGREE_MIN <= servo_0_degree - DEGREE_MOVE <= DEGREE_MAX:
servo_0_degree -= DEGREE_MOVE
servo_0.set_degree(servo_0_degree)
elif servo_action == '↓':
if DEGREE_MIN <= servo_0_degree + DEGREE_MOVE <= DEGREE_MAX:
servo_0_degree += DEGREE_MOVE
servo_0.set_degree(servo_0_degree)
elif servo_action == '→':
if DEGREE_MIN <= servo_1_degree - DEGREE_MOVE <= DEGREE_MAX:
servo_1_degree -= DEGREE_MOVE
servo_1.set_degree(servo_1_degree)
elif servo_action == '←':
if DEGREE_MIN <= servo_1_degree + DEGREE_MOVE <= DEGREE_MAX:
servo_1_degree += DEGREE_MOVE
servo_1.set_degree(servo_1_degree)
return render_template('index.html')
if __name__ == '__main__':
app.run("0.0.0.0")
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div align="center">
<table style="border-collapse: collapse">
<tbody>
<tr>
<td align="center" width="100" height="100"></td>
<td align="center" width="100" height="100">
<form action="/" method="POST">
<input type="submit" name="servo_action" value="↑" style="width:100px;height:100px;font-size:50px;">
</form>
</td>
<td align="center" width="100" height="100"></td>
</tr>
<tr>
<td align="center" width="100" height="100">
<form action="/" method="POST">
<input type="submit" name="servo_action" value="←" style="width:100px;height:100px;font-size:50px;">
</form>
</td>
<td align="center" width="100" height="100">
<form action="/" method="POST">
<input type="submit" name="servo_action" value="●" style="width:100px;height:100px;font-size:50px;">
</form>
</td>
<td align="center" width="100" height="100">
<form action="/" method="POST">
<input type="submit" name="servo_action" value="→" style="width:100px;height:100px;font-size:50px;">
</form>
</td>
</tr>
<tr>
<td align="center" width="100" height="100"></td>
<td align="center" width="100" height="100">
<form action="/" method="POST">
<input type="submit" name="servo_action" value="↓" style="width:100px;height:100px;font-size:50px;">
</form>
</td>
<td align="center" width="100" height="100"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
実行
以下コマンドでプログラムを実行します。
python3 app.py
パソコン or スマホのブラウザを開き、
Raspberry Pi の IPアドレス:ポート(デフォルト5000)でアクセスします。
例えば、
http://192.168.11.9:5000
です。
※注意点としては、ラズパイとパソコン or スマホは、
同じLANに接続されている必要があります。
起動成功すると以下動画の画面が表示され、操作することが可能です。
まとめ
配線図
プログラム
ブラウザにカメラ画像を映す為、
index.html ファイルに、以下 <img ・・・/> 行を追加します。
{192.168.11.8}のIPアドレスの箇所には、
あなたの Raspberry Pi のIPアドレスを設定してね。
<div align="center"> <img src="http://192.168.11.8:8080/?action=stream" /> <table style="border-collapse: collapse">
実行
以下のコマンドを使って、mjpg-streamer を起動します。
mjpg-streamer を停止するには、
以下コマンドを実行したターミナルソフトにて、「Ctrl + C」を実行します。
sudo ./mjpg_streamer -i "./input_uvc.so -f 10 -r 320x240 -d /dev/video0 -y -n" -o "./output_http.so -w ./www -p 8080"
上記コマンドを実行したターミナルソフトとは別のターミナルソフトを起動し、
以下コマンドでプログラムを実行します。
python3 app.py
パソコン or スマホのブラウザを開き、
Raspberry Pi の IPアドレス:ポート(デフォルト5000)でアクセスします。
例えば、
http://192.168.11.9:5000
です。
※注意点としては、ラズパイとパソコン or スマホは、
同じLANに接続されている必要があります。
起動成功すると以下動画の画面が表示され、操作することが可能です。
おまけ
今回、「Raspberry Pi用遠隔操作カメラキット」を使って電子工作を行いましたが、
このカメラキット、カメラの土台を何かに固定しないと、
サーボを動かす度にこけてしまいます。
そこで、以下画像の様に、カメラの土台を固定する基盤を作成しました。
1枚 \2,000円(送料込み)でお譲りしようかと思います。
興味のある方は、 ページTOPの「お問い合わせ」にてご連絡下さい。
最後に
如何だったでしょうか?
・カメラ映像がブラウザで見れた時、
・ブラウザからサーボモータ動かせた時、
ワクワクしましたよね♪
自分で作ったものが動くって楽しいですよね♪
以下記事では他にも色んな電子工作を作っています。
あなたが作りたいモノのヒントがあれば嬉しいです。
記事を更新するとTwitterでつぶやきます。
フォローしてもらうと、記事を書くモチベーションが上がります。
下のTwitterアイコンからフォローお願いします。
不明な点があればページTOPの「お問い合わせ」にてご連絡下さい。
もし一人で作るのが難しかったら、
一緒に作るサービスをしています。
お気軽に ページTOPの「お問い合わせ」にてご連絡下さい。