はじめに
物理ボタンを遠隔操作するためのガジェットは市販のもの(SwitchBot ボット、+Style スイッチなど)だと数千円もするが、マイコン+モーターの単純な構成なら低コストで実現できそうである。なるべく安価に作成して、気軽に導入できるようにしたい。
先行例
- ESP32でWeb上の情報に基づきサーボモーターを動かす (https://elchika.com/article/c6cf26f3-8751-41af-9cd4-0b8a655c8de5/ )
- ESP32でローカルサーバーの情報に基づきサーボモーターを動かす (https://elchika.com/article/2e305a2c-5ef0-4826-8f70-a4643898a389/)
- Raspberry Pi Pico Wは常時待ち受け状態にしてHTTPサーバーを立て、スマホなどのブラウザ操作によりサーボモーターを動かす。
- モーターの角度などのパラメータもブラウザから調整できるようにする。
- 任意の時間がたった後に動作するようなタイマーも設定する。
ハードウェア
分量外もあるが、1700円くらい?
- マイコンボード:Raspberry Pi Pico W
(秋月電子で1210円 https://akizukidenshi.com/catalog/g/gM-17947/ ) - サーボモーター:FS-90
(マルツで396円 https://www.marutsu.co.jp/pc/i/2228273/ ) - 壁への固定:3M コマンドタブ
(十分な粘着力がありつつ、引き延ばすと簡単にはがせる。セットで300円弱) - 電源:micro USBアダプタとケーブル
- はんだ適量
このほか作業用にPC、はんだごて、ニッパー等
組み立て
サーボモーターの赤い線をVBUS (40) 、茶色い線をGND (38) 、オレンジの線をPWM(今回は34)に接続。
サーボモーターをスイッチの枠に設置。モーターの力が最も伝わるような配置を考える。モーターのトルクは足りているが浮き上がって力が伝わらないことが往々にしてあるので、いろいろ試行錯誤する。今回はスイッチの枠を外して壁にねじどめされている基部に接着した。また、サーボモーターの腕はやや引いた状態で0度とした。
Webページの様子
ソフトウェア
動作するまでの初期設定等は他の資料を参照のこと。
main.py
import re
from machine import PWM,Pin,Timer
import socket
import time
import re
import wifi
import sg90
wifi.connect('SSID','PASSWD') #適宜
html = """<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Pico Switch</title>
</head>
<body>
<form oninput="display.value=Number(deg.value);">
<p><input type="number" name="timer" min="0" value="%s">分後に<input type="submit" name="action" value="実行"></p>
<p>角度:<output name="display">%s</output>°<input type="range" name="deg" min="-90" max="90" step="1" value="%s"></p>
<p>押す長さ:<input type="number" name="keep" min="1" list="numlist" value="%s">秒</p>
<datalist id="numlist">
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
<option value="4"></option>
<option value="5"></option>
<option value="6"></option>
<option value="7"></option>
<option value="8"></option>
<option value="9"></option>
<option value="10"></option>
</datalist>
<input type="submit" name="action" value="適用">
</form>
%s
</body>
</html>
"""
addr = socket.getaddrinfo('0.0.0.0',80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(addr)
s.listen(1)
servo = PWM(Pin(28))
servo.freq(50)
servo.duty_u16(sg90.set_degree(0))
timer=Timer()
while True:
try:
cl, addr = s.accept()
request = str(cl.recv(1024))
result = re.search(r'deg=-?\d+',request)
degree = 0 if result is None else result.group(0)[4:]
result = re.search(r'keep=\d+',request)
keep = 1 if result is None else result.group(0)[5:]
result = re.search(r'timer=\d+',request)
count = 0 if result is None else result.group(0)[6:]
result = re.search(r'action=(%E5%AE%9F%E8%A1%8C|%E9%81%A9%E7%94%A8)',request)
action = None if result is None else result.group(0)[7:]
if action=='%E5%AE%9F%E8%A1%8C':
message='実行しました。'
elif action=='%E9%81%A9%E7%94%A8':
message='適用しました。'
else:
message=''
cl.send('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n')
cl.send(html % (count,degree,degree,keep,message))
cl.close()
def func(timer):
servo.duty_u16(sg90.set_degree(int(degree)))
time.sleep(int(keep))
servo.duty_u16(sg90.set_degree(0))
if action=='%E5%AE%9F%E8%A1%8C':
timer.deinit()
timer.init(mode=Timer.ONE_SHOT,period=60000*int(count),callback=func)
except OSError as e:
cl.close()
wifi.py
import network
import time
def connect(ssid,passwd,retry=10):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid,passwd)
time.sleep(3)
print(wlan.ifconfig())
sg90.py
def set_degree(degree):
if degree < -90 : degree = -90
if degree > 90 : degree = 90
return int( ( degree * 0.0475 / 90 + 0.0725 ) * 65535 )
まとめ
タイマーが使えるのが意外と便利というのは使い始めてからわかった。しばらく使用してみて、問題点が見つかれば修正する予定。
今後やってみるとよさそうなアイディア
- 複数タイマー
- Bluetooth対応
- 家の外からの遠隔操作
- 3Dプリンターでかっこいいケースを作る
- バッテリーでの動作
投稿者の人気記事
-
nihsok
さんが
2023/06/12
に
編集
をしました。
(メッセージ: 初版)
Opening
zanjibar
2023/06/12
nihsok
2023/06/18
ログインしてコメントを投稿する雲台できるといいですね。
コメントありがとうございます。
マイコン部分がとても軽いため、浮かしたままでもしばらくは大丈夫そうで助かるなと思っています。ただこれまでとは全く別のスキルが必要になるので、かなり後回しになりそうです。