監視カメラとNASでタイムラプス動画を作成する
最近色々と物騒ではありますのでAmazonプライムデーで監視カメラを購入しました。
格安でってことでTP-LinkのTapo C320WSにしてみました。
ちなみに購入時はセールで6,000円ぐらいでした。
動画はスタンドアロン(設定にスマホアプリが必要なので完全なスタンドアロンは無理ですが)でSDカードに保存したり、TP-Linkが運営するクラウドに保存したりできますが私はSynology社のNAS(DS120Jという最廉価モデル)を運用していましたので、そこに保存してみました。
SynologyのNASにはSurveillance Stationというアプリが付属しており2台のIPカメラを無償で接続できます(追加ライセンスで台数は増やせる模様)。購入したC320WSはサポート対象のカメラでしたのでIPカメラ追加を行えば自動でカメラ検索に表示されました。
これで追加をすればよいのですがカメラ側でログインを許可するためのアカウントの設定が必要になります。
スマホのTapoアプリから「カメラの設定」→「高度な設定」→「デバイスアカウント」でユーザー名とパスワードを設定してログインを許可します。
これでNASにIPカメラからの動画を保存が可能になります。NAS側で録画スケジュールや保持日数などを設定可能です。
またSurveillance Stationにはスマートタイムラプスという機能があってIPカメラの画像をタイムラプス動画にすることができます。
タスクとしてタイムラプス動画にしたい時間帯を選び「設定」で「時間の圧縮率」(120だと2時間が1分になる)を設定すれば通常の動画とは別にタイムラプス動画が作成されます。
カメラのビットレートが不足な感じで動画カメラとしては満足できませんが、格安監視カメラとしてはまぁこんなもんだろうって感じです。
ダイヤフラムポンプでミスト散水を作る
暑い季節が近づいてきましたので今年は2階のベランダにアサガオでグリーンカーテンを作ろうとプランターを設置しました。
当然ですが水を撒かなければならないのですが水道が手近に無くジョーロを1階から運ぶことになるのですが自動化でもできないかと調べましたらダイヤフラムポンプというのが割と安価に手に入るので試してみました。
ダイヤフラムポンプ
購入時2,180円でした。ミスト散水ですと、それなりに水圧が必要と思われましたので噴水用ポンプなどでは無理そうでダイヤフラム式にしました。
これは0.8Mpaとラベルに表記されてますので水道と同等の水圧が得られるはずです。
ミスト散水セット
とにかく安かった。購入時855円で10mホース、ノズル10個、クイックコネクターなどが揃うってのは国内ではなかなか無さそう。
接続用ホース
ポンプは入出力とも内径8mmのようです。ミスト側は内径4mmですのでなんらかのジョイントが必要となります。
ちょうどいいのがこれで切断してポンプの入出力とクイックコネクターのオス側を使ってミスト側に接続できます。
実物
結構大きいです。上記タカギの延長ホースを接続してあります。下の赤黒線に直流12Vを与えれば動きます。ポンプそのものは防水じゃないみたいなんでちょっと面倒です。
延長ホースのクイックコネクターをミスト側のコネクターに接続します。
実働させてみました。音はこんな感じでそこそこ大きいです。振動もあって固定しないと動きます。10Lバケツであれば数分で撒き散らします。
タイマーとか土水分センサーでも使って自動化とも考えましたがバケツに水がなければ意味が無いわけで手動で十分ですね
イルミネーションを飾ってみた
へっぽこな動画撮影機材しか無いのでなんともわかりにくいですがLEDテープをESP32で制御しております。
LEDテープはWS2812Bで300個と150個の2本を別IOポートに接続しています。WS2812Bは5V動作なのですがロットが新しい物の信号線は3.3Vで問題ないとのことでESP32と直結しましたが問題ありませんでした。
発光制御はFastLEDライブラリを使用しています。fill_rainbow(指定範囲を虹色で埋める)、blur1d(前後に色をボカして減衰させる)、fadeToBlackBy(全体を減衰させる)など使ってはみましたがタイミングなどが難しく思ったような点灯にはなりませんでしたが凝っていると終わらないでしょうからとりあえず設置してみました。
来年はもうちょっと頑張ろうと
Arduino IDEは如何にしてコンパイルを行っているのか?
Arduino IDEで開発を行っています。ソースが長くなってきたので複数ファイルに分割したのですが2個目の.inoファイル先頭にライブラリーのincludeを行ったところ、その.h内で大量のコンパイルエラーが出たのです。
いろいろ調べたら、なんてことはなく1個目の.inoのブロックが閉じてなかった("}"が足りなかった)ってオチでした。
Arduino IDEの言語は基本的にC++なのですが微妙に異なる(宣言していない関数を前方で呼んでもエラーにならないなど)のが不思議だったので、どこかに資料があるのだろうなと思いながら試してみました。
拡張子.ino、.c、.cpp以外はスケッチに加えてもコンパイル対象にならない
.hや適当な拡張子のファイルをスケッチに加えてもコンパイル対象になりません。これらのファイルがボードに転送されるかは検証していません。当然ですが.hを.inoなどからincludeすればコンパイル対象になります。
.c、.cppは厳密なc++言語としてコンパイルされる
ソースの後方にある関数は呼び出す前にプロトタイプ宣言をしていないとエラーになります。また.inoで何気に呼んでいたSerial.println("test");などもarduino.hをインクルードしていないとエラーになります。
.ino内の関数はプロトタイプ不要だが同じスケッチ内の.cpp内の関数は宣言してないとエラーとなる
.ino内の関数はソース上後方にあっても前方で呼び出せます。別の.inoファイルであっても問題ありません。しかし同じスケッチ内の.cppなどの関数はプロトタイプ宣言しないとエラーとなります。
.ino内でもstructやclassは前方に宣言がないとエラーになります。
.inoは連続して扱われる
先頭の.inoにvoid loop(){と書いて2番めの.inoで}と書けばコンパイルエラーになりません。これが最初のinclude内でのエラーの原因で1つ目の.inoのブロック内にincludeが展開されてしまったためにエラーとなったようです。
結論的なもの
ということで.inoファイルはプリプロセッサ的なもので全ファイルがテキストとしてマージされて処理されているようです。マージ後にino内の関数をチェックしてプロトタイプ的なものを生成してarduino.hなどの必須includeと共に挿入してcppとしてコンパイルしているんではないかなと思う次第です。
イルミネーションを作る(WiFi周りのソースコード)
前回の記事で書いたWiFi周りのソースを張っておきます。
それにしてもマイコンボードの開発環境でこれだけ色々揃っていることに感心しました。IOT用で結構使われてるっていうのも納得です。
デバッグをシリアルデバッグに頼らざるを得ないのがちょっと厄介ですがそれでも慣れればなんとかなるでしょう。
ところでWiFiを使うにあたってはSSIDやパスワードをソースに埋め込む必要があるのがちょっと厄介ですね。APモードで立ち上げて入力させるとかできるとは思いますが結局フラッシュなどに書き込むわけで持ち去られてダンプ取られる(取れるのか不明ですが)とどうしようもないと思います。
一応今回はWiFiアクセスポイントのゲストポートに接続することにしてます。そっちであればバレても内部のPCを触られる可能性を減らせますんで。
さてLED発光周りの実装はクリスマスまでに間に合うんでしょうか?
イルミネーションを作る(前準備でWiFi周りで遊ぶ)
Arduinoで遊んでいるとゲーミングPCの照明などで使われているフルカラーLEDが制御可能だってことがわかりまして庭にイルミネーションしてみようじゃないかということになりました。300個と150個のLEDテープ2本用意して電源も5V10A出せるものを用意しました。
当初はArduino nanoで作っていたのですがRAMが2Kバイトしかないってのがきつくなってきました。LED表示にひとつあたり3バイト使用しますんで450個で1.5Kバイト近く使う計算となりギリすぎるということでESP32を使用することとしました(こちらはArduinoIDEからで320K使えます)。
ESP32を使うとなればWiFiが使えるので遊びついでに機能を加えることとしました。
- 点灯時間を制御するためにタイムサーバーにアクセスして内部時間を設定する。
- ESP32でWebサーバーを立てて点灯時間以外でも強制的にON/OFFできるようにする。
- WebサーバーにアクセスするためにはIPアドレスが必要なのだけどWiFiアクセスポイントはDHCPなので取得したIPアドレスを報告する
- 屋外設置なのでプログラム書き換えをWiFi経由で行う
1.時刻設定
イルミネーションは基本、夜に点灯ですので当初はフォトレジスタを繋いで暗くなったら点灯と考えていたのですがWiFi接続できるんであればntpサーバーにアクセスして簡単に正確な時間を得られるので17時~21時点灯などとすることにしました。
configTime(9 * 3600L, 0, "ntp.nict.jp", "pool.ntp.org");
でESP32の時計が設定できて(9*3600は世界標準時との時差)
tm tmBuff;
getLocalTime(&tmBuff);
で設定した時刻を取得できます。
2.Webサーバー
ESP32のコアに含まれているのでライブラリー追加は必要ありません。
#include <WebServer.h>
WebServer webSvr(80);
インスタンスを作成して、setupでアクセスされたときのハンドル関数を設定して開始します。
webSvr.on("/", handleRoot); // rootへのアクセス
webSvr.on("/button", handleButton); // buttonへのアクセス
webSvr.begin(); // WEBサーバー開始
Loop内でWebサーバーにアクセスされたかチェックして当該処理を呼び出すメンバー毎回呼びます。
webSvr.handleClient();
ハンドル関数はクライアントで表示したいhtmlを編集して送り返せば良いです
webSvr.send(200, "text/html", str);
3.IPアドレスの通知
DHCPで運用していても、それほどIPアドレスが変わるわけでは無いのでシリアル出力で良いのですがLINEへの通知が簡単にできるのでそれでやってみました(Line Notifyという機能です)。
LINE上での設定はいろいろあって、それは端折りますが最終的にはトークンが得られます。
ESP32用のライブラリーがあるので検索して追加してください。
#include <ESP_Line_Notify.h>
を行って
LineNotifyClient line;
line.token = "取得したトークン文字列";
line.message = "ESP32起動 " + WiFi.localIP().toString();
LineNotify.send(line);
などとすればLINEに通知が届きます。画像なども送れるようなので今後カメラ付きのESP32でも買って遊ぼうかと思っています。
4.WiFIでのプログラム更新
ESP32のコアにArduinoOTAという名前で含まれています。
#include <ArduinoOTA.h>
を行いsetup内で
ArduinoOTA.begin();
を行いLoopで
ArduinoOTA.handle();
を行えばArduinoIDEでシリアルポートと並んでIPアドレスが表示されますので、それでWiFi経由の書き込みが可能です(色々設定はできるみたいですが全部端折りました)。ArduinoOTAインスタンスはインクルード内で定義されているのでソース内で定義する必要はありません。
書き込み時パスワードを聞かれますがadminです。
当方の環境では書き込みは正常に完了するのですがIDEでの書き込み表示が終了せずIDEの再起動が必要な状態となっています。(IDEのバージョンは2.0.2です)
ソースはもうちょっと整理して次の記事にしようと思います。
視覚障害者用音楽再生機を作る(状態を保存する)
このままでは電源を投入するたびに1枚目のCDの1曲めを再生することになりますので再生中の曲情報を保存して次の電源投入時には続けて再生できるようにしました。
ESP32はフラッシュメモリとして4MB実装されており、そこに作成したプログラムを書き込んで実行しています。その一部をファイルシステムとして使用してデータを保存することが出来ます。
デフォルトでは1.2MBをアプリケーション、1.5MBをファイルシステムとして使用できるようです。
ライブラリーはコアに含まれているようですので追加の必要はありません。
フラッシュメモリーをSPIFFSとして使用しようとした初回はシリアルモニターに"mount failed"と表示されて動作しない場合があります。これはファイルシステムとしてフォーマットされていないことが原因で発生しますので、1回目だけSPIFFS.begin(true)として実行してください。
とりあえずこれで完成ですのでソースを貼っておきます。
https://github.com/softcircus/DFPlayerTest/blob/main/DePlayer.ino