
Photo by
narukuni
Bluetoothシャッターボタンで電子工作
こういうのを作りました。
プログラムを備忘録として残します。
構成
Raspberry Pi
Bluetoothシャッターボタンと接続し、ArduinoとはUSBで接続します。
シャッターボタンの入力を得て、USB経由によるシリアル通信でArduinoに命令を送ります。
Arduino
Raspberry Piから受け取った命令をもとにサーボモータの角度を制御します。
コード
簡単なほうから書きます。
ということで、Arduino側がこちら。
#include <Servo.h>
// サーボインスタンスを生成
Servo myServo;
// サーボピンと角度変数を宣言
const int servoPin = 7;
int servoAngle;
// LED出力
const int outputLEDPin = LED_BUILTIN;
void setup() {
// サーボピンにサーボを割り当て
myServo.attach(servoPin);
// 初期角度を設定
servoAngle = 0;
myServo.write(servoAngle);
// LED設定
pinMode(outputLEDPin, OUTPUT);
digitalWrite(outputLEDPin, LOW);
// シリアル通信の通信速度を設定
Serial.begin(9600);
}
void loop() {
// シリアル通信をしたときのみif文内を実行する
if (Serial.available() > 0) {
// シリアルモニターで入力した角度にサーボモーターを動かす
servoAngle = Serial.parseInt();
myServo.write(servoAngle);
digitalWrite(outputLEDPin, HIGH);
}
delay(100);
digitalWrite(outputLEDPin, LOW);
}
Raspberry Pi側はこんな感じです。Pythonで書いています。
import time
import serial
from evdev import InputDevice, categorize, ecodes
# シリアル通信の初期化
ser = serial.Serial("/dev/ttyACM0", 9600, timeout=10)
time.sleep(2)
# デバイスを指定(evtestで確認したデバイスパス)
device_path = "/dev/input/event2" # 例: シャッターのデバイスパス
device = InputDevice(device_path)
# デバイスの入力をグラブ(システムへの影響を防ぐ)
device.grab()
print(f"デバイス {device.name} を監視しています...")
try:
for event in device.read_loop():
if event.type == ecodes.EV_KEY: # キーイベントの場合
key_event = categorize(event)
print(f"キーイベント: {key_event}")
print(key_event.keycode)
print(key_event.keystate)
if key_event.keycode == "KEY_VOLUMEUP" and key_event.keystate == 1:
print("start")
ser.write(b'75') # 75度
time.sleep(1)
ser.write(b'\n') # 0度に戻す
time.sleep(2)
except:
pass
finally:
# プログラム終了時にシリアル接続の解除と、デバイスの解放をする
ser.close()
device.ungrab()
print("デバイスのグラブを解除しました")
モジュールとして以下が必要ですので、インストールしておきます。
pip install pyserial
pip install evdev
Bluetoothシャッターボタンなどの入力デバイスが認識されているのか、その詳細を知るにはevtestコマンドで確認ができます。
以下のPythonコードでも確認できます。
from evdev import InputDevice, list_devices
# 接続されている入力デバイスを一覧表示
devices = [InputDevice(dev) for dev in list_devices()]
for device in devices:
print(device.path, device.name)