記事公開日

ダイソー「スマートフォンシャッターリモコン」でM5Stackを無線操作(Bluetooth通信)

ダイソー「スマートフォンシャッターリモコン」

ダイソーで販売している220円の「スマートフォンシャッターリモコン」

今回は、このBluetooth通信ができるリモコンを使って、M5Stack BASICの無線操作を行ってみました。

  1. 操作の流れ
  2. Arduino IDEの設定
  3. プログラム

操作の流れ

  1. M5Stack上に「Connecting…」が表示されているときに、リモコンの電源をONにすると、ペアリングが行われます。
  2. ペアリングに成功すると、M5Stackの画面が「Success!」という表示に切り替わります。
  3. リモコンのボタンを押すと、その回数がM5Stack上に表示されます。

Arduino IDEの設定

今回使用した開発環境・マイコンは以下の通りです↓

  • Arduino IDE 2.3.2
  • M5Stack BASIC v2.6

ボードのインストール

Arduino IDEを起動後、上部メニューから、[ファイル]ー[基本設定]を選択します。

[追加のボードマネージャのURL]に以下のURL↓を貼り付けて、[OK」をクリックします。

https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json

これで、M5Stack関連のボードがArduino IDEにインストールされます。

追加のボードマネージャのURL]にURLを貼り付け

ボードの設定

上部メニューから、[ツール]ー[ボード]を選択します。

今回は「M5Stack BASIC」を使用しますが、選択肢に「BASIC」がないので、[M5Stack]ー[M5Fire]を選択します。

ボードに「M5Fire」を選択

ライブラリのインストール

上部メニューから、[スケッチ]ー[ライブラリをインクルード]ー[ライブラリを管理]を開きます。

ライブラリを管理

画面左に表示されたフォームに「NimBLEDevice」を入力し、「NimBLE-Arduino by h2zero」をインストールします。

「NimBLE-Arduino by h2zero」ライブラリをインストール

プログラム

#include <M5Stack.h>
#include "NimBLEDevice.h"

// Bluetooth Low Energy (BLE)で使用するサービスのUUIDを設定
NimBLEUUID serviceUUID("1812");

// BLEのスキャンオブジェクトとデバイスオブジェクトを定義
NimBLEScan* pBLEScan;
BLEAdvertisedDevice* myDevice;

// 接続状態を示すフラグを定義
boolean connected = false;

// ボタン押下回数を記録する変数を定義
int buttonPressCount = 0;  

// BLEの通知を受け取るためのコールバック関数を定義
static void notifyCallback(NimBLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) {
  
  // 受信した通知の特徴のUUIDとハンドルをシリアルモニターに出力
  Serial.print("Notify callback for characteristic ");
  Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
  Serial.print("(");
  Serial.print(pBLERemoteCharacteristic->getHandle());
  Serial.print(") of data length ");
  
  // 受信したデータの長さを出力
  Serial.print(length);
  Serial.print(" data: ");
  
  // 受信データの内容を16進数形式で出力
  for (int i = 0; i < length; i++) {
    Serial.printf("%02X ", pData[i]);

    // データが'02'の場合、ボタンが押されたとみなしてカウントアップ
    if(pData[i] == 02) {
        // ボタン押下回数をカウントアップ
        buttonPressCount++;
        
        // M5StackのLCDにボタン押下回数を表示
        M5.Lcd.setCursor(10, 20);           // カーソルを(10, 20)に設定
        M5.Lcd.printf("Button pressed: %d", buttonPressCount); // ボタン押下回数を表示
        
        // 表示を300ミリ秒遅延
        delay(300);
    }
  }
  
  // 行末に改行を挿入してデータ表示の完了を示す
  Serial.println();
}

// BLEクライアント接続時のコールバッククラスを定義
class MyClientCallback : public NimBLEClientCallbacks {
  
  // クライアントが接続したときに呼ばれる関数
  void onConnect(NimBLEClient* pclient) {
  }
  
  // クライアントが切断したときに呼ばれる関数
  void onDisconnect(NimBLEClient* pclient) {
    // 接続状態をfalseに設定し、切断をシリアルに出力
    connected = false;
    Serial.println("onDisconnect");
  }
};

// BLEでアドバタイズされているデバイスを処理するクラスを定義
class MyAdvertisedDeviceCallbacks : public NimBLEAdvertisedDeviceCallbacks {
  
  // BLEデバイスを発見したときに呼ばれる関数
  void onResult(NimBLEAdvertisedDevice* advertisedDevice) {
    
    // アドバタイズされたデバイス情報をシリアルモニターに出力
    Serial.printf("Advertised Device: %s \n", advertisedDevice->toString().c_str());
    
    // サービスUUIDを持つかつ該当するサービスをアドバタイズしている場合、スキャンを停止してデバイスを保存
    if (advertisedDevice->haveServiceUUID() && advertisedDevice->isAdvertisingService(serviceUUID)) {
      NimBLEDevice::getScan()->stop();
      myDevice = advertisedDevice;
    }
  }
};

// 初期設定関数
void setup() {
  
  // M5Stackと電源の初期化
  M5.begin();
  M5.Power.begin();

  // シリアル通信の初期化と待機
  Serial.begin(115200);
  delay(1000);
  Serial.println("Scanning...");

  // BLEデバイスのスキャン設定
  NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE);
  NimBLEDevice::setScanDuplicateCacheSize(200);
  NimBLEDevice::init("");

  // スキャンオブジェクトの取得と設定
  pBLEScan = NimBLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), false);
  pBLEScan->setActiveScan(true);
  pBLEScan->setInterval(97);
  pBLEScan->setWindow(37);
  pBLEScan->setMaxResults(0);
  
  // スキャンの開始
  pBLEScan->start(0, nullptr, false);
}

// メインループ
void loop() {

  // デバイスが見つかり、接続がまだされていない場合に接続を試みる
  if (myDevice != NULL && connected == false) {
    
    // BLEクライアントの作成とコールバックの設定
    BLEClient* pClient = BLEDevice::createClient();
    pClient->setClientCallbacks(new MyClientCallback());
    
    // デバイスへの接続を試みる
    pClient->connect(myDevice);

    // 指定したサービスの取得
    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    
    // サービスが見つからなければ切断して戻る
    if (pRemoteService == nullptr) {
      pClient->disconnect();
      return;
    }

    // サービスに含まれる全てのCharacteristicを取得
    Serial.println("characteristic list");
    std::vector<NimBLERemoteCharacteristic*>* vectorCharacteristics = pRemoteService->getCharacteristics(true);
    
    // 取得したCharacteristicが通知可能であれば、通知を受け取る設定を行う
    for (int i = 0; i < vectorCharacteristics->size(); i++) {
      if (vectorCharacteristics->at(i)->canNotify()) {
        Serial.print(vectorCharacteristics->at(i)->registerForNotify(notifyCallback));
      }
    }
    
    // 接続フラグをtrueに設定
    connected = true;

    // 接続成功メッセージをM5StackのLCDに表示
    M5.Lcd.setCursor(10, 10);
    M5.Lcd.print("Success!     ");
    M5.Lcd.setCursor(10, 20);           // カーソルを(10, 20)に設定
    M5.Lcd.printf("Button pressed: 0"); // ボタン押下回数を表示

  }

  // 接続されていない場合は、M5StackのLCDに接続待ちのメッセージを表示
  if(!connected) {
    M5.Lcd.fillScreen(BLACK); // 画面を黒で塗りつぶし
    M5.Lcd.setCursor(10, 10);
    M5.Lcd.print("Connecting...");
  }

  // 1秒ごとにループ
  delay(1000);
}

プログラムは下記の記事を参考にさせていただきました↓
ダイソーの新型Bluetoothシャッター | Lang-ship

プログラムが正常に書き込まれた後、シリアルモニタを表示させると、Bluetooth通信可能なデバイス一覧やボタンを押したときのキーが表示されます。

文字化けしているときは、通信速度を115200bpsに変更してください。

シリアルモニタ

なお、リモコンには大きなボタンと小さなボタンがありますが、どちらを押しても同じキーが送信されています。

使い分けはできませんので、実質、ボタン1つのリモコンです。

この記事のURLをコピー

メールアドレスは公開されませんのでご安心ください。また、* が付いている欄は必須項目となります。

内容に問題なければ、下記の「コメントを送信する」ボタンを押してください。

関連情報

  • 【2024年度版】マイコンおすすめランキングBEST5
運営者プロフィール
コダマ

職業はIT系フリーランス。過去、電子配線業務の経験が10年ある為、はんだづけも得意です。宮崎県在住、30代・2児の父親。

プロが教える!イチからわかるハンダ付けのコツ(工学社)の著者です。

カテゴリー