スポンサードリンク

デバイス編#16 ~ハードと格闘していたその裏で~

スマートカーテン

皆さん、お盆休みはどのように過ごされたでしょうか?

私は墓参りのために実家に一泊帰省してました。

先祖様のおかげで生きられていることに感謝しつつ、今日も活動に精を出します。


こんにちは、ポニ丸です。

今回は、ファームウェア(マイコン上で動作するソフトウェア)でどういうことを実現するのかの設計図を考えてゆきます!

趣味の範囲なのできちっとはやりませんが、ざっくりした仕様を考えたのちに掘り下げていきますね。

システム概要

システム全体のイメージがこんな感じです。ちょっとした復習ですね。

窓枠の横についているのが私がいま作っているスマートカーテンのデバイスです。

デバイスは有線でつながっているスイッチでカーテンを昇降制御を行う

BLEを使って接続したスマホ上のアプリから遠隔でも昇降制御可能

ここまでは当初決まっていたざっくり仕様ですね。

動作仕様

では、ざっくり仕様から徐々に深く仕様を考えていきます。

1.スマホアプリからできること

まずは、スマホアプリから何ができるのかを決めていきました。大きく2つの機能を持ちます。

カーテンの「開」「閉」「停止」制御

当然といえば当然ですが、アプリ上のボタンを押すことで開動作、閉動作、停止動作を制御することができることとします。

注意点としては制御できる方法としてデバイスに接続された昇降スイッチと2種類存在するので、どこから制御されたかによって優先度をつける必要があります。

自動的に開閉する時間の予約

ここがある種一番やりたかったことです。

この時間になったら自動的にカーテンが開く、またはカーテンが閉じるという時間設定を行い、デバイス側に予約できることとします。

2.BLE通信

次に通信仕様ですね。

このページを参考にしながら仕様を検討しました。簡単にBLEを説明してくれるいいページなのでよかったら見てみてください。

開発視点の超簡単BLE入門
今回はBLEそのものについて超簡単に説明します。BlueJellyに限らず、全てのBLEに共通した内容です。BLE雑学ではなく、開発視点での最低限必要な情報だけを説明します!

役割

スマホアプリ側がCentral、デバイス側がPeripheralとなります。

Peripheralの構造

Peripheralには用途に合わせて内部構成を考えないといけないです。

大きいところからやりまっしょい。

Service

Peripheral内のフォルダのようなものらしいです。

今回はスマートカーテンというサービスしか必要ないので、Serviceは1つのみ定義します。

Characteristic

Service内のファイルのようなものらしいです。CharacteristicはValue、Property、Descriptorの3種類のデータを持っています。

今回のシステムでは以下の3つのCharacteristicを定義します。

Characteristic 0:Valueが「スマホアプリからの制御指示」、Propertyが「WriteNoReturn」
Characteristic 1:Valueが「カーテンの動作状態」、Propertyが「Notify」
Characteristic 2:Valueが「開閉の予約時間」、Propertyが「Notify」

肝心の各Valueはどうするの?という疑問はあると思いますが、少々お待ちくださいねー。

デバイスの構造(ここまでのまとめ)

上記の情報から図にまとめると、こんな感じの構造になります。伝わるかな?笑

本来、ここから通信に必要な情報を洗い出して通信仕様とValueの中身を事細かく決めていくんですが・・・実はずっと前から決めてました!

これがタイトルにかかる部分ではあるんですけど、私がハードで格闘している間、やぎ星人もSwift UIと戦いつつ通信仕様だったりを相談してくれてて裏で決めちゃってたっていう話です。

口約束とかだと忘れちゃうのである程度の内容はドキュメント化してあります。

それを見ていただければここまでの決定事項と、そこから進んだ通信仕様等も理解していただけるかと。

リンクになっちゃいますがこちらの仕様書をどうぞ!

初版の日付見てもらえればわかりますが、6月から形になりつつあったんですねー笑

一応、この仕様書の内容でBLEに関する機能はOKです!

3.昇降スイッチ

回路図に従った仕様ではありますが、昇降スイッチは3本の線から成ります。

IO18:デジタル出力ポート。IO19、IO5に対してHighレベルを与えるためHigh出力
IO19:デジタル入力ポート。High時に「開方向の回転ON」となる。
IO5:デジタル入力ポート。High時に「閉方向の回転ON」となる。

※IO18でHigh出力しているのは昇降スイッチ入力が禁止とするタイミングがあった場合に、このポートをLow出力にすることで消費電流を抑えることができるからです。

4.モータ制御

モータの回転方向を制御するためにモータドライバICをかましているので、IC側の制御を行います。

IO32:デジタル出力ポート。モータドライバICに電源電圧を与えるためのHigh出力
IO25:デジタルPWM出力ポート。正回転時にPWM信号を印加
IO26:デジタルPWM出力ポート。逆回転時にPWM信号を印加

※IO32でHigh出力しているのはモータ動作を禁止とするタイミングがあった場合に、このポートをLow出力にすることで消費電流を抑えることができるからです。

PWM信号によって回転数を制御できるのですが、今回はハードの実験からonDuty:100%で動作させます。

5.LED制御

これは回路設計の際にも書きましたがデバッグ用です。

IO13:Highで点灯、Lowで消灯

6.開閉制御の優先度

カーテンが開閉する手段としては3種類存在します。

  • 昇降スイッチ操作による手動制御
  • スマホアプリ操作による遠隔制御
  • 予約時間による自動制御

これらの手段がタイミング的にかち合う可能性は0ではないので、優先度をつけておきます。

優先度が高い手段で動作している際はそれ以下の手段による制御を棄却し、また、優先度が低い手段で動作している際はそれ以上の手段による制御があれば上書き制御を行うこととします。

肝心の優先度ですが、以下としました。

  1. 昇降スイッチ操作による手動制御
  2. スマホアプリ操作による遠隔制御
  3. 予約時間による自動制御

7.現在時刻の取得

スマホアプリから開閉の時間予約をすることができるんですが、予約された時間になったら開けたり閉めたりするにはマイコン内で現在時刻を知っておく必要があります。

ESP32マイコンでどうやって現在時刻を取得できるかなーとググってみたところ、Wi-Fiに接続してNTPサーバという日本標準時を配信しているサーバにアクセスすることで現在時刻が取得することができるらしいです。

このページを参考にしました。

ESP32で現在時刻を取得する(これが一番良いと思います)
以前にESP8266で現在時刻を取得する記事をあげました ここ”ESP32でもできるんじゃね?”という考察をしましたが、やってみたらできました少しプログラムが異なるため、まとめておきます

兼ねてからBLEとWi-Fiの同居をポイントにしていたのはここにつながるんですね。長い伏線でございました笑


今回も結構長めになってしまいましたが、ファームの仕様はこれで決定とします。

仕事とは違うまとめ方なので見づらい部分もあるかもしれません。ごめんなさい。

次回は決まった仕様に基づいて実装を進めていきますね!

ではでは!

コメント