約1年前に買って放置していたRaspberryPiで遊んだので、使ったセンサ/アクチュエータと制御プログラムをまとめます。
使用したコードはgithubに登録しています。
https://github.com/aratakokubun/RaspiBot.git
実装はpythonと一部shellで書いています。
Raspiでのプログラム概要
Twitterから操作を送信し、外部からセンサ情報を取得・アクチュエータを駆動するプログラを実装しています。
機能は以下の通り
- カメラキャプチャ
- カメラの首振り
- エアコンのON/OFF
- パソコンに設置した超音波測距センサの現在・ログのグラフ取得(基本的には自分とパソコン画面との距離)
- 湿温度センサの現在・ログのグラフ取得
サーボモータ
アクチュエータ概要
- GWS S03T
- 指定した角度に回転する、ごく普通のサーボモータ
- 値段 ¥1200 (秋月購入)
- 5V, GND, 制御端子の3端子
用途
Twitterから角度を指定して指令を送り、搭載したwebカメラの角度を変える
実装
RaspberryPiのピン入出力制御ライブラリのRPi.GPIOを使用しています。
参考文献1のページを参考に実装しました。
以下処理の抜粋
- 初期化
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
# サーボのGPIOピン番号を23に設定
SERVO_GPIO = 23
GPIO.setup(SERVO_GPIO, GPIO.OUT)
# 動作周波数は50Hz
HZ = 50
servo = GPIO.PWM(SERVO_GPIO, HZ)
servo.start(0.0)
- 角度を指定して制御
ChangeDutyCycle
メソッドで制御するが、動作範囲は2.0 - 12.0
で0° - 180°
に対応する。
dc = 2.0 + 10.0 * float(angle/180)
servo.ChangeDutyCycle(dc)
# Wait while finishing servo
time.sleep(0.5)
- プログラム終了
GPIOをcleanupしてから終了します。
GPIO.cleanup(SERVO_GPIO)
赤外線LED(送信・受信)
センサ・アクチュエータ概要
受信モジュール
- 赤外線リモコン受信モジュール GP1UXC41QS
- 値段 ? (元から持ってた)
- 5V, GND, 制御端子の3端子で回路は単純
送信モジュール
- 赤外線LED OSI5FU5111
- 値段 ? (元から持ってた)
- GND, 制御端子の2端子
用途
リモコンの信号を取得し、同じ信号を赤外線LEDで送信
実装
Linux用の赤外線モジュール制御のライブラリであるlircを使用しました。
参考文献2のページを参考に実装しました。
-
lircでのリモコンの信号取得と発信する信号の設定
lircの設定方法は参考文献2を参照してください。ここでは割愛します。
簡単には以下の設定を行います。(全てroot権限が必要)-
/etc/lirc/hardware.conf
の設定を変更する。 -
/boot/config.txt
の設定を変更し、起動時にLIRCを有効にする。 -
mode2 -d /dev/lirc0(hardware.confに設定した名称)
コマンドでlircを起動し、リモコンの信号を赤外線受信モジュールに送信した際にデータが取れることを確認する。 - 3のコマンドで取得したデータをデータ送信用のコマンド定義と共に
/etc/lirc/lircd.conf
に追記する。 -
/etc/init.d/lirc start
でlircを起動 -
irsend SEND_ONCE <コマンド>
でデータが送信できることを確認
-
-
初期化
初期化用のshellを用意しておき、pythonから初期化時に呼び出します。
sudo /etc/init.d/lirc stop
sudo /etc/init.d/lirc start
from subprocess import call
INIT_CMD = "sudo bash ./src/initLirc.sh"
call(INIT_CMD.strip().split(" "))
- エアコン制御
from subprocess import call
ON_CMD = "sudo irsend SEND_ONCE aircon cooler_on"
OFF_CMD = "sudo irsend SEND_ONCE aircon cooler_on"
call(ON_CMD.strip().split(" "))
call(OFF_CMD.strip().split(" "))
- プログラム終了
sudo /etc/init.d/lirc stop
from subprocess import call
STOP_CMD = "sudo bash ./src/stopLirc.sh"
call(STOP_CMD.strip().split(" "))
測距センサ
センサ概要
- HC-SR04
- 超音の反射時間を利用して非接触で測距するセンサモジュール
- 2-180cmまで測距可能
- 値段 ¥400 (秋月購入)
- 5V, GND, ECHO, TRIGGERの4端子
用途
パソコンに設置し、自分がパソコンに向き合ってる時の距離を測定
実装
こちらもRaspberryPiのピン入出力制御ライブラリのRPi.GPIOを使用しています。
- 初期化
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
# TRIGGERのGPIOを17, ECHOのGPIOを27に設定
TRIG_GPIO = 17
ECHO_GPIO = 27
# TRIGGERは出力ピン、ECHOは入力ピンに設定
GPIO.setup(TRIG_GPIO, GPIO.OUT)
GPIO.setup(ECHO_GPIO, GPIO.IN)
# TRIGGERを0Vに設定
GPIO.output(TRIG_GPIO, GPIO.LOW)
- 測定
GPIO.output(TRIG_GPIO, True)
time.sleep(0.00001)
GPIO.output(TRIG_GPIO, False)
while GPIO.input(ECHO_GPIO) == 0:
signaloff = time.time()
while GPIO.input(ECHO_GPIO) == 1:
signalon = time.time()
return (signalon - signal off) * 17000
- プログラム終了
GPIOをcleanupしてから終了します。
GPIO.cleanup(TRIG_GPIO)
GPIO.cleanup(ECHO_GPIO)
湿温度センサ
センサ概要
- DHT11
- 温度を1度単位・湿度を1%単位で計測可能
- 温度精度±2度・湿度精度±5%と精度は微妙
- 取得に失敗することもあり、動作も不安定
- 値段 ¥490 (amazon購入)
- 5V, GND, 入出力の4端子
用途
部屋の湿温度の現在値とログを取得
実装
RaspberryPiからDHT11の温度/湿度を取得する為のプログラムがgithubに公開されていたので、これを利用
https://github.com/adafruit/Adafruit_Python_DHT
- 初期化
import Adafruit_DHT
# DHTのGPIOを18番に設定
DHT_GPIO = 18
# センサを指定
sensor = Adafruit_DHT.DHT11
- 測定
1回だと失敗する可能性があるので、3回リトライしています。
MAX_TRIAL = 3
for _ in range(self.MAX_TRIAL):
humidity, temperature = Adafruit_DHT.read_retry(sensor, DHT_GPIO)
if humidity is None and temperature is None:
continue
return [humidity, temperature]
- プログラム終了
特に終了時に処理をする必要はなさそうです。
その他
-
Twitterでのコマンド送受信
TwitterStreamingAPIを使用し、特定のメッセージを監視しています。 -
各センサの終了時の処理
atexitパッケージで終了処理のハンドラを登録していますが、クラスの__del__メソッドでもいい気がします・・・
参考文献
- RaspberryPiでのサーボ制御
http://windvoice.hatenablog.jp/entry/2015/05/04/180110 - Raspberry Pi 2 でエアコン操作(赤外線リモコン編)
http://kaiware007.hatenablog.jp/entry/2015/08/28/020356 - Raspberry Piに超音波距離計”HC-SR04”つけてみた
http://arkouji.cocolog-nifty.com/blog/2014/05/raspberry-pihc-.html - 温湿度センサDHT11をRaspberryPiに接続しグラフ表示
http://blog.bnikka.com/raspberrypi/dht11-raspberrypi.html