Raspberry Piとステッピングモータ28BYJ-48 5V/モータドライバULN2003でパンチルトのうち、パン(左右首振り)機能を作ろうと思い見つけたWebIOPiを使ったプログラムをpywebviewに移植してみた話。
流用すべく、解析してみるとPythonとJavaScript間でマクロを使って相互に通信している部分は...、似たようなことができるものもあるのか?と検索してみるといわゆるデスクトップアプリを作ることができるというEelやpywebviewの存在を知った次第。
この組み合わせだと3B+には厳しいのか、映像を表示させるとパン機能が効かなくなるので動画でも映像なしでカメラのみ動かしています。
また、完成してみれば、薄々感じていたとおり、デスクトップ版であるこれらでは、リモート操作できない模様であるため、他をあたることにし、結果、Raspberry Pi/Flask/WebSocket/RPI.GPIO/28BYJ-48にしましたが、せっかくなので公開しておこうかと。
pywebviewは、pip(pip3)でインストールできます。
RPi.GPIOは、標準で入っている場合もあると思いますが、なければ、pip(pip3)でインストールできます。
script.pyは、こんな感じ。
JavaScriptとPythonのやりとり部分は、Javascript APIとExposeとをにらめっこしつつ、トライ&エラーの末、完成。
static/camera.jsは、こんな感じ。
WebIOPiからpywebviewへの移植に伴い、それなりに編集しました。
オリジナルソースだとid=Current0のinput type=textタグの内容は、美しくもボタン押下ごとにカウントダウン/カウントアップします。
が、そこ端折った、このロジックだとid=Current0のinput type=textタグは、id=Tartget0のそれと同じなので不要ですが残しました。
一部の関数や#ws-status行など使っていない部分、オリジナルにはないHTMLファイルに残したid=return0のinput type=textタグ用DOMなどコメントアウトしつつ、場合によっては使うかなという部分も。
static/camera.cssは、こんな感じ。
CSSに関しては、index.html内にあった元のソースを外部ファイルとして分離しただけです。
pywebviewの場合、FirefoxとかChrome/Chromiumなどではなく、webviewに表示されるわけですが、templates/index.htmlは、こんな感じ。
ほか、中身は少し編集しました。
ソース通りなら、ラズパイのGPIO(BCM)ピン17/18/27/22を、それぞれULN2003のIN1/IN2/IN3/IN4に接続し、電源投入、端末でustreamer --host=0.0.0.0 &、script.pyを実行(python script.py)、表示されるwebview画面でボタン操作。
左/右ボタンをクリックすると、Number of Step分だけ、Target Positionが増減、元プログラムでは、Current Positonは、ほぼリアルタイムに値が増減しますが、今回、端折ってTarget Positionと同じ値を示します。
script.pyに追記したprint文を有効にしてあるので端末には、ボタン押下ごとにGPIOピンの状態も表示されます。
視覚的に不要なinputタグのtext類を非表示にした上、例えば、ustreamerやmjpg-streamerなどの映像を加えるだけで動作中のカメラのパンチルト状態をリアルタイムで見て取れるようになるのですが、ラズパイ3B+には荷が重いのか、映像表示させるとパンが機能せず、今回の要件にはマッチしませんでした。
というか、それ以前にpywebview(やeelが実現するのは)デスクトップアプリであり、外部サイトを表示することはできてもリモートホストのブラウザから容易に遠隔操作できないので見送ることになったわけですが。