Raspberry Piでセンサーとアクチュエータを制御:加速度計、サーボ、データストリーミング
多くの開発者が静的ファイルやシンプルなグラフィックを扱う一方で、フィジカルコンピューティングは現実世界とのインタラクションへの扉を開きます。センサーからデータを読み取り、アクチュエータを駆動することで、物理世界を感知・判断・行動するシステムを構築できます。
目標
Raspberry Piを使って加速度計の値を読み取り、サーボモーターを制御し、フィジカルコンピューティングの核心概念を実演します。
主要概念
- Raspberry Pi – HDMI、Ethernet、USBポート2つ、そして何よりGPIOピンを備えた35ドルのLinuxコンピューター。信号の送受信が可能です。
- GPIOピン – 汎用入出力ピン。バイナリスイッチとして機能し、HIGH(3.3V)またはLOW(0V)に設定してアクチュエータを駆動したり、状態を読み取ってセンサーデータを収集したりできます。
この記事では、Piのハードウェア能力を示す4つの実践的なPythonプロジェクトを解説します:
- LEDの点滅
- ポテンショメーターの読み取り
- ネットワーク経由でのデータストリーミング
- サーボモーターの制御
LEDを点滅させる
LED(発光ダイオード)は、順方向に電流が流れると発光します。PiとLEDを保護するため、500Ω〜1.5kΩの抵抗を使用します。抵抗値はR = (V_s - V_d) / Iで計算可能ですが、上記範囲ならほとんどのホビーキットで動作します。
import time
from itertools import cycle
import RPi.GPIO as io
io.setmode(io.BCM)
io.setup(12, io.OUT)
for state in cycle([1, 0]):
io.output(12, state)
time.sleep(0.5)
ピン12を出力に設定し、0.5秒ごとに切り替えることでLEDを点滅させます。
ポテンショメーターを読み取る
ポテンショメーター(ポット)は可変抵抗で、ノブの位置を電圧に変換します。GPIOピンはデジタルなので、アナログ・デジタルコンバータ(ADC)が必要です。MCP3008は8チャネルの10ビットADCで、0〜3.3Vを整数値0〜1023にマッピングします。
SPI通信でMCP3008とやり取りするためspidevをインストール:
pip install spidev
チャネル0から値を読み取るスクリプト:
import spidev
import time
spi = spidev.SpiDev()
spi.open(0, 0)
def readadc(adcnum):
if not 0 <= adcnum <= 7:
return -1
r = spi.xfer2([1, (8 + adcnum) << 4, 0])
adcout = ((r[1] & 3) << 8) + r[2]
return adcout
while True:
val = readadc(0)
print(val)
time.sleep(0.5)
ØMQでデータをストリーミング
ØMQ(ZeroMQ)は高性能メッセージングライブラリで、ネットワーキングを簡素化します。REQUEST/REPLYパターンを使えば、Pythonで軽量なサーバーとクライアントを構築できます。
サーバー
import zmq
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind('tcp://*:1980')
while True:
message = socket.recv()
print(message)
socket.send(b"I'm here")
クライアント
import zmq
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect('tcp://192.168.1.6:1980')
for _ in range(10):
socket.send(b'You home?')
message = socket.recv()
print(message)
traitsとenamlを使えば、ストリーミングデータを可視化するレスポンシブUIを作成可能です。完全な例はacc_plotデモを参照してください。
サーボモーターを制御
サーボはPWM(パルス幅変調)で精密な位置制御を行います。一般的なホビーサーボでは、0.5msパルスが最小角度、2.5msパルスが最大角度に対応し、20ms周期で繰り返します。
汎用OSで精密なタイミングを出すのは困難です。ServoBlasterはカーネルモジュールとしてPWM生成をDMAコントローラにオフロードし、シンプルな/dev/servoblasterインターフェースを提供します。
この機能をオブジェクト指向ライブラリでラップしました:RobotBrain。以下はサーボを0%〜100%デューティサイクルで動かす例です。
import time
import numpy as np
from robot_brain.servo import Servo
# ピン4でサーボ初期化、カスタム最小/最大パルス幅(μs)
servo = Servo(0, min=60, max=200)
for val in np.arange(0, 1, 0.05):
servo.set(val)
time.sleep(0.1)
GitHubのservo_sliderデモで、ネットワーク経由のサーボ制御を確認できます。
Raspberry Piでのセンサーとアクチュエータ制御についてさらに深く知りたい場合は、元のドキュメントやコミュニティチュートリアルを参照してください。
製造プロセス
- シームレスMQTT統合:NodeMCU DHT22センサーとRaspberry Pi 3 B+ブローカー
- 5ドルI2C温度センサーで作るRaspberry Pi温度ロガー
- 複数DS18B20 1-WireセンサーをRaspberry Pi接続で精密温度監視
- Raspberry PiとPythonでリモート温度センサーを構築 – ステップバイステップガイド
- Raspberry Piで気象観測ステーションを構築し、日次天気データをメール送信
- HC-SR04超音波距離センサーをRaspberry Pi 3に接続 – 完全ガイド
- Raspberry PiでPIRモーションセンサーとLEDを制御
- Raspberry Piで低コスト土壌水分センサーを構築 - スマート灌漑に活用
- Raspberry Piでリニアホールセンサーを読み取り: JavaガイドとADC0832の知見
- Raspberry PiとDS18B20でマルチセンサー温度・光監視システムを構築
- Raspberry PiとTwilioで実現するトイレ占有センサー:音声通話とSMSで通知