nihsokのアイコン画像
nihsok 2023年06月12日作成 © GPL-3.0+
製作品 製作品 閲覧数 1889
nihsok 2023年06月12日作成 © GPL-3.0+ 製作品 製作品 閲覧数 1889

1000円台で作るスマートスイッチ

1000円台で作るスマートスイッチ

はじめに

物理ボタンを遠隔操作するためのガジェットは市販のもの(SwitchBot ボット、+Style スイッチなど)だと数千円もするが、マイコン+モーターの単純な構成なら低コストで実現できそうである。なるべく安価に作成して、気軽に導入できるようにしたい。

先行例

今回やりたいこと
キャプションを入力できます

  • Raspberry Pi Pico Wは常時待ち受け状態にしてHTTPサーバーを立て、スマホなどのブラウザ操作によりサーボモーターを動かす。
  • モーターの角度などのパラメータもブラウザから調整できるようにする。
  • 任意の時間がたった後に動作するようなタイマーも設定する。

ハードウェア

分量外もあるが、1700円くらい?

このほか作業用に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>&deg;<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のアイコン画像 zanjibar 2023/06/12

    雲台できるといいですね。

    nihsokのアイコン画像 nihsok 2023/06/18

    コメントありがとうございます。
    マイコン部分がとても軽いため、浮かしたままでもしばらくは大丈夫そうで助かるなと思っています。ただこれまでとは全く別のスキルが必要になるので、かなり後回しになりそうです。

    1 件の返信が折りたたまれています
ログインしてコメントを投稿する