編集履歴一覧に戻る
ftakeのアイコン画像

ftake が 2021年04月12日22時51分15秒 に編集

説明を追加

本文の変更

はじめに ==================== リモートワークで外出しない日々が続くと、郵便受けに郵便物があるかどうかをチェックするのが遅れがちな今日この頃です。そこで、郵便受けに郵便物があることを通知する装置を作ってみました。 郵便物の確認というと、例えば次のような方法がよく出てきます。 * 郵便受けの扉部分が動いたことを検知する * カメラで内部を撮影して、画像認識する * 重さを測ることで郵便物があることを検知する 今回はシンプルに郵便受けの底面に設置したフォトリフレクター(赤外線を照射して、反射して返って来るとトランジスタに電流が流れるセンサー)を使って、フォトリフレクターの上に郵便物があることを検知することで実現することにしました。この方法では、どのような郵便物が入っているかは分かりませんが十分でしょう。高性能なマイコンボードや、高価なセンサー、大容量の電池が要らないメリットもあります。 ![郵便物を検知する仕組み](https://camo.elchika.com/e0ad5512348cabc8923a69420619dd0d13af6a14/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62656137353162662d646535382d343265342d623863662d3336636561346235366365652f61656235636536652d623163642d346633362d383362652d373337346239346330393230/) また、郵便受けは集合型で自室の外にあり、検知結果を無線で通知する必要があります。そこで、Bluetooth Low Energy (BLE) で飛ばして、室内に置いた Raspberry Pi でキャッチすることにしました。金属の箱の中からでも意外と届くものですね。(ただし、Raspberry Pi を郵便受けから近く電源も取れるトイレの窓際に設置) 今回は、基本的な仕組みの動作検証ということで、通知はターミナルに出すだけです。Raspberry Pi まで来てしまえば、IFTTT 経由で LINE にメッセージを送ったりとか、なんとでもできますね。連続稼働時間についても実用面では今後検討ですが、M5 Stack でどこまでいけるかを試します。 材料 ======================= * M5 Stack Gray: 手元にあったので…。連続稼働時間を考えると変えた方がよさそう。 * フォトリフレクタ コーデンシ SG-105: 検知可能距離が短いのでこちらを選びました。 * 抵抗: 750, 470 k(調整必要) * 電源が自動で切れないモバイルバッテリ(ノベルティでもらったもの) * 適当なユニバーサル基板、銅線 * 自己融着テープ * 段ボール 作り方 ========================== 回路定数決め --------------------------------------------------- ![ブレッドボード上で調整](https://camo.elchika.com/4b2d33d73ab14ae38f6d1bd6c4f391b20d515129/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62656137353162662d646535382d343265342d623863662d3336636561346235366365652f38616561626263312d333336342d343138352d623363612d643439356232303533363338/)

-

まずは、ブレッドボードで実装して回路定数を決めます。A/D 変換を使ったり、可変抵抗をつければ後から調整することもきるのですがシンプルに GPIO 取り込むこと、反射濃紺の某宅配レンタル)封筒も検知きるように抵抗調整

+

まずは、ブレッドボードで実装して回路定数を決めます。電源は 3.3 V を使います。Vcc からはなくGPIO 5 から電源を供給しているのは、測定時以外は OFF きるようするです。LED の抵抗はスマホのカメラで点灯ているのを確認しながら大きな抵抗してきます数 mA で点灯する、だいたいこのくらいの抵抗すね)。抵抗小さく過ぎると LED が焼き切れたり、消費電力が増えるのはもちろんですが、天井から反射て返って来る量が増えるのも注意が必要です

-

電源は 3.3 V を使います。Vcc からなく、GPIO 5 から供給測定時以外は OFF できるようました。

+

次に、重要なセンサー値の読み取りです。A/D 変換を使ったり、可変抵抗をつければ後から調整することもきるのですが、シンプルに GPIO で取り込むことにしました。そのために郵便物があるときに、GPIO 2 の電圧がプログラムから読み取ったときに1になる圧になるように R2 の抵抗値調整ます。反射しにくい濃紺の(某宅配レンタルの)封筒をセンサーの上にかざした状態で、R2 を増やしいった結果750 なりました。

![回路図](https://camo.elchika.com/d03f6491b4b5b6ecbeeb7cc1463b55c860e610a2/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62656137353162662d646535382d343265342d623863662d3336636561346235366365652f38376339346365352d306537642d343239632d383736382d363765343363636134616532/) 実装 ----------------------------------------------------- ユニバーサル基板でこのような感じに実装しました。この配置で大丈夫?と思う方もいるかと思いますが、久しぶりの電子工作で、半田付けしている最中に配線間違いに気づいて裏側は残念な感じになっています(一応ノージャンパー)。 ![ユニバーサル基板での実装](https://camo.elchika.com/1313a8aac6436d2821d1a0c18e8a15f2de59f382/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62656137353162662d646535382d343265342d623863662d3336636561346235366365652f37343461666665632d333635622d343463332d396635642d393666363338666561323062/) 郵便受けは金属なので自己融着テープで簡単に絶縁しました。 ![絶縁した基板](https://camo.elchika.com/816269855f6e4c2878819fee3e6e77d21ddb0158/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62656137353162662d646535382d343265342d623863662d3336636561346235366365652f30653430353661392d343831342d343037632d383036662d366536333733323430663363/) 郵便受けの床の部分は段ボールで作りました。真ん中に穴を開けて取り付けます。フォトインタラプタは対象物から多少離れていた方が感度が良いため、床面から少し離したほうが良いです。段ボールの穴のサイズも余裕を持っておかないと、赤外線がフチで反射する可能性があります。 ![組み立て後](https://camo.elchika.com/17b151df22fac90b19ecccf43585e634316e5f7e/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62656137353162662d646535382d343265342d623863662d3336636561346235366365652f37393563393030362d383535342d343665612d386537312d376462383139316362666437/) M5 Stack のプログラミング ---------------------------------------------------- M5 Stack で BLE は色々な人が実践していますが、今回はこちらを参考にしました。 https://pages.switch-science.com/letsiot/bleperiph/index.html

-

今回は、BLE でもブロードキャストモードを使用しています。自身をアドバタイズするときに、一緒に郵便物の状態を配ります。受信するデバイスとはコネクションを確立する必要はありません。ただし、ポストの状態は周りに丸見えになってしまいます。

+

今回は、BLE でもブロードキャストモードを使用しています。ブロードキャストモードは自身をアドバタイズする(デーバイス名などを通知する)ときに、データを送る方法で、この場合は郵便物の状態を配ります。受信するデバイスとはペアリングしたり、コネクションを確立する必要はありません。ただし、ポストの状態は周りに丸見えになってしまうので注意が必要です。

+

このプログラムでは 30分に1回起きて、フォトリフレクタの赤外線を点灯して郵便物の有無をチェックします。その後、10秒間の間 Bluetooth で郵便物の状態を送ります。普通の Bluetooth デバイスはスマートフォンなどのデバイスからスキャンすると、これに応答する形でアドバタイズします。このプログラムでは M5 Stack 側から勝手に送るので、このスキャンに応答する必要がありません(`setScanResponse(false)`)。

```c++ #include <Arduino.h> #include <M5Stack.h> #include <BLEDevice.h> #include <BLEServer.h> static BLEServer *pBLEServer; static void setup_ble() { BLEDevice::init("Post Notifier"); pBLEServer = BLEDevice::createServer(); } void setup() { M5.begin(); Serial.begin(115200); pinMode(GPIO_NUM_2, INPUT); pinMode(GPIO_NUM_5, OUTPUT); // スピーカーとディスプレイを止めておく pinMode(GPIO_NUM_25, OUTPUT); M5.Lcd.writecommand(ILI9341_DISPOFF); M5.Lcd.setBrightness(0); setup_ble(); } static void advertise_data(char val) { BLEAdvertisementData advertisementData {}; advertisementData.setFlags(0x06); std::string data; data += (char)0x04; // Length data += (char)0xff; // AD Type: Manufacture Specific data += (char)0xff; // Company Identifier Code data += (char)0xff; // Company Identifier Code data += val; // Specific data advertisementData.addData(data); BLEAdvertising *pAdvertising = pBLEServer->getAdvertising(); pAdvertising->setAdvertisementData(advertisementData); // Passive スキャンを使うので、スキャンに応答不要 pAdvertising->setScanResponse(false); pAdvertising->start(); delay(10 * 1000); pAdvertising->stop(); } void loop() { digitalWrite(GPIO_NUM_5, HIGH); delay(50); auto input1 = digitalRead(GPIO_NUM_2); digitalWrite(GPIO_NUM_5, LOW); Serial.printf("%5d\n", input1); advertise_data(input1);

-

M5.Power.lightSleep(SLEEP_MIN(10));

+

M5.Power.lightSleep(SLEEP_MIN(30));

} ``` Raspberry Pi 側のプログラミング ------------------------------------------------------------------------ Python で 10 秒タイムアウトで繰り返しスキャンを実行し、M5 Stack からのデータを拾います。とりあえずコンソールに状態を書き出すことで今回は良しとします。

-

ポイントはアドバタイズを要求せずに受信するパッシブモードを使っています。これにより、M5 Stack 側で Scan Response に応答する必要がなくなります。

+

ポイントはスキャンでアドバタイズを要求せずに受信するパッシブモードを使っています。これにより、M5 Stack 側で Scan Response に応答する必要がなくなります。

```python from datetime import datetime from time import sleep from bluepy.btle import BTLEException, ScanEntry, Scanner, def main(): # とりあえず、HW アドレス直書き device_addr = "xx:xx:xx:xx:xx:xx" print(f"{datetime.now()} Post Notifier GW") scanner = Scanner() while True: try: # パッシブモード entries = scanner.scan(10.0, passive=True) for entry in entries: entry: ScanEntry if entry.addr == device_addr: data = entry.getValueText(ScanEntry.MANUFACTURER) val = int(str(data[4:6]), 16) print(f"{datetime.now()} status: {val}") except BTLEException as e: print(f"{datetime.now()} Error {e}") sleep(60) if __name__ == "__main__": main() ``` 出力はこのような感じです。16:45〜16:55 の間に投函されたことが分かります。 ``` 2021-02-19 16:45:33.953899 status: 0 2021-02-19 16:45:43.978746 status: 0 2021-02-19 16:55:35.156646 status: 0 2021-02-19 16:55:45.176626 status: 0 2021-02-19 17:05:36.366733 status: 1 2021-02-19 17:05:46.387938 status: 1 2021-02-19 17:15:27.542689 status: 1 2021-02-19 17:15:37.563869 status: 1 ``` 今後の計画 =========================================== フォトリフレクタを使った郵便物チェッカーの基本部分を作ってみました。 現状と今後の改造についても書いておきたいと思います。 * もうちょっとマシな通知の仕組みを考える

-

* バッテリーの持ち: 9.25 Wh のモバイルバッテリーで4日ほど持ちます。スリープを Deep sleep にして、検知間隔を伸ばすとどの程度使えるかは試してみようと思います。

+

* バッテリーの持ち: 9.25 Wh のモバイルバッテリーで4日ほど持ちます。残念ながら M5 Stack は待機時の消費電力が大きいようで、スリープを Deep sleep にして、検知間隔を増やしてもバッテリーの持ちは変わません。マイコンを変える必要があるようす。

* LPWA を使ってみる: 今回は BLE で届いてしまったのですが、当初の計画では Sigfox で飛ばしてみたいなと思っていました