LoginSignup
7
4

More than 3 years have passed since last update.

M5StickCである一定の音域が検出されたらSwitchBotを作動させる

Last updated at Posted at 2020-04-30

動作イメージ

M5StickCにはマイクが内蔵されており、それを使ってなんか物音がしたら部屋の電気などをつけてみようかと思います。
泥棒や指パッチンでも使えるかも…?

Image from Gyazo

開発環境、使った機材

注意点

以下は今回のとは関係なく既存である問題ですね…

  • ESP32への書き込みエラー
    • Mac OSX 10.15系でのみ、出る
    • A0とGNDをピンでつなげる
    • USB接続
    • 書き込み
    • ピンを抜き、M5StickCの再起動(電源ボタン6秒押し、その後2秒押し)
    • 参考サイト
  • M5StickCのディスプレイがつかない
    • Arduinoのスケッチの例のM5StickC内の「Hello World」を書き込む

ちなみにArduinoのダウンロードやESP32系に対して書き込む設定だったりは省略します。

ソースコード

GitHubで共有しました!
https://github.com/tkyko13/M5StickC-SwitchBot

プログラムの変更、調整

#include <M5StickC.h>
#include <driver/i2s.h>
#include "arduinoFFT.h"
#include "BLEDevice.h"

// 5kHz -> 5/0.17=29.411... の四捨五入整数 = 29
// 値が-1の場合、周波数はなし
#define TH_FREQ_BAND -1
// 音量閾値
#define TH_VOLUME 0.1

// 手元のSwitchBotのMACアドレス
#define MAC_SWITCHBOT "Your_SwitchBot_MAC"
<---以下省略--->

閾値変更

TH_VOLUMEの値を変更することで音量による閾値を設定できます。
0.1でも結構大きい音じゃないと反応しないです。

周波数フィルタリング機能

TH_FREQ_BANDの値を変えることで、検出する周波数帯を変更します。
周波数ではなく周波数帯です。
1帯域につき0.17kHzです。
例えばTH_FREQ_BAND 0であれば、0kHzから0.17kHzの間の音量だけを検出します。
5kHzの周波数を検出したい場合、TH_FREQ_BAND 29になります。(29*0.17=4.93)

MACアドレスの変更

SwitchBotの個体と接続することができます。
MACアドレスの取得方法と変更箇所は以下です。

手持ちSwitchBotのBLEのMACアドレスの取得
ソースコード変更

MAC_SWITCHBOTのYour_SwitchBot_MACを変更します。

01:23:45:67:89:abみたいな文字列ですね。

実は

if (addr.equalsIgnoreCase(MAC_SWITCHBOT)) {
// SwitchBot を発見
// if (advertisedDevice.getServiceUUID().equals(SERV_SWITCHBOT)) {
          log("found");

SwitchBotのMACアドレスがわからなかったり面倒であればわからなくても大丈夫です。
上記の部分を探して、

// if (addr.equalsIgnoreCase(MAC_SWITCHBOT)) {
// SwitchBot を発見
if (advertisedDevice.getServiceUUID().equals(SERV_SWITCHBOT)) {
          log("found");

このように変更するとよいです。
詳しくは説明しないですが、BLEの中のサービスというのがあって、SwitchBotではそれがすべて同じ値なのでその値でSwitchBotを探しています。
これでもいいですが、もしかしたら隣の部屋の人のSwitchBotが動いちゃうかも??

実際実装してみて

M5StickCでBluetooth接続失敗の取得方法

SwitchBotを探すスキャンは安定していますが、どうしても接続するときに失敗が起きます。
これは別のアプリで、関係ないものと接続してもなるので、仕方ないことなのかと思います。
ただ、Arduinoで書くM5StickCの接続で、失敗の取得がスマートにはできないです。
具体的には、

pClient->connect(myDevice)

非公式日本語リファレンスでは、こちらの引数で失敗したらfalseが返ってくるはずですが、処理が止まっちゃいます。
接続開始する前にフラグを立てておき、接続失敗イベント(接続が切れたイベント)を貼っておき、成功か失敗かを取得します。
失敗していたら、処理が止まっているため再接続ではなく再起動しています…
幸いラズパイなんかよりかは断然再起動早いのでまぁいいかなくらいです。

bool connecting = false;

// 略

connecting = true;
pClient->setClientCallbacks(new MyClientCallback());
pClient->connect(myDevice);
connecting = false;

// 略

class MyClientCallback : public BLEClientCallbacks {
    void onDisconnect(BLEClient* pclient) {
      Serial.println("onDisconnect");
      if (connecting) {
        esp_restart();
      }
    }
};

抜粋するとこんなコードになります。
connect処理で止まって次の行に行かないです、onDisconnectイベントは実行されるけど…

雑談

MacOSがカタリナだと書き込みも面倒だったので、古いMacbook取り出して開発しちゃってました。
ATOM Lite(https://www.switch-science.com/catalog/6262/) も同じマイコンを使っているはずですが、カタリナで書き込めたらしい…
ほしい…

7
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4