ダイソーの新型Bluetoothシャッター

概要

みなさん大好きダイソーのBluetoothシャッターが新製品に入れ替わっていましたので確認してみました。

製品

こちらの製品になりますが。旧製品が330円だったのですが、こちらは220円となっています。

裏側です。

左の赤が旧製品で、右側が新製品になります。よく見ると技適番号が違っているので別の会社で製造しているものになります。

青が追加されていますが、ダイソーの330円モデルの初期モデルとなります。ちょっとボタンの表記が違いますね。あと赤は電源のところが印刷だったのですが、青と黒は金型によるでっぱりになっています。

裏側です。青だけカバーのところに滑り止め加工がされていますね。青と赤は同じ技適番号なので同じ製造工場だと思われます。

AliExpressで技適マーク無し商品が届いた
概要 技適マークを確認して購入したのですが、技適マークなしが届きました。。。結構面倒なので皆さん気をつけましょう。。。 商品 届いた商品です。技適マークがありません! 商品ページ こんな商品で、ちゃんと技適マークがあります。 ダイソーシャッ...

上記であった製品とも違う製造番号ですね。

ついでにダイソー以外で販売されているシャッターも購入してきました。右下に技適番号がありますが、こちらも違う番号です。

左側はネジがなくて、金型が全然違うことがわかります。

両方黒でわかりにくいですが、左側が330円の他店のものとなります。

動作確認

上記のものでそのまま動きましたが標準のBluetoothスタックではなく、軽量スタックであるNimBLEを使って動作確認してみました。

上記のライブラリで、NimBLEで検索することでライブラリマネージャーから入れることができます。特徴として中身がシンプルなスタックなのでファイルサイズなどもかなり小さくなります。

スキャン

#include "NimBLEDevice.h"

NimBLEUUID serviceUUID("1812");

NimBLEScan* pBLEScan;
BLEAdvertisedDevice* myDevice;

class MyAdvertisedDeviceCallbacks : public NimBLEAdvertisedDeviceCallbacks {
  void onResult(NimBLEAdvertisedDevice* advertisedDevice) {
    Serial.printf("Advertised Device: %s \n", advertisedDevice->toString().c_str());
    if (advertisedDevice->haveServiceUUID() && advertisedDevice->isAdvertisingService(serviceUUID)) {
      NimBLEDevice::getScan()->stop();
      myDevice = advertisedDevice;
    }
  }
};

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("Scanning...");

  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) {
    BLEClient* pClient = BLEDevice::createClient();
    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);
    for (int i = 0; i < vectorCharacteristics->size(); i++) {
      Serial.print(" - characteristic UUID : ");
      Serial.print(vectorCharacteristics->at(i)->getUUID().toString().c_str());
      Serial.print(" Broadcast:");
      Serial.print(vectorCharacteristics->at(i)->canBroadcast() ? 'O' : 'X');
      Serial.print(" Read:");
      Serial.print(vectorCharacteristics->at(i)->canRead() ? 'O' : 'X');
      Serial.print(" WriteNoResponse:");
      Serial.print(vectorCharacteristics->at(i)->canWriteNoResponse() ? 'O' : 'X');
      Serial.print(" Write:");
      Serial.print(vectorCharacteristics->at(i)->canWrite() ? 'O' : 'X');
      Serial.print(" Notify:");
      Serial.print(vectorCharacteristics->at(i)->canNotify() ? 'O' : 'X');
      Serial.print(" Indicate:");
      Serial.print(vectorCharacteristics->at(i)->canIndicate() ? 'O' : 'X');
      Serial.println();
    }

    // stop
    Serial.println("Stop!");
    while (1) {
      delay(1000);
    }
  }
  delay(1000);
}

標準のBluetoothスタックとよく似ているライブラリなのでBLEの部分をNimBLEに書き換えるだけでほとんどそのまま動きます。ただgetCharacteristics()とかでstd::mapで処理できていたものがstd::vectorに変更する必要があったりもします。

上記にマイグレーションガイドがあります。

キー取得

#include "NimBLEDevice.h"

NimBLEUUID serviceUUID("1812");

NimBLEScan* pBLEScan;
BLEAdvertisedDevice* myDevice;
boolean connected = false;

static void notifyCallback(NimBLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) {
  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: ");
  for (int i = 0; i < length; i++) {
    Serial.printf("%02X ", pData[i]);
  }
  Serial.println();
}

class MyClientCallback : public NimBLEClientCallbacks {
  void onConnect(NimBLEClient* pclient) {
  }
  void onDisconnect(NimBLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
  }
};

class MyAdvertisedDeviceCallbacks : public NimBLEAdvertisedDeviceCallbacks {
  void onResult(NimBLEAdvertisedDevice* advertisedDevice) {
    Serial.printf("Advertised Device: %s \n", advertisedDevice->toString().c_str());
    if (advertisedDevice->haveServiceUUID() && advertisedDevice->isAdvertisingService(serviceUUID)) {
      NimBLEDevice::getScan()->stop();
      myDevice = advertisedDevice;
    }
  }
};

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("Scanning...");

  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) {
    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);
    for (int i = 0; i < vectorCharacteristics->size(); i++) {
      if (vectorCharacteristics->at(i)->canNotify()) {
        Serial.print(vectorCharacteristics->at(i)->registerForNotify(notifyCallback));
      }
    }
    connected = true;
  }
  delay(1000);
}

こちらも前と大きな流れは変わっていません。Bluetoothスタックはとにかく機能が多く、中身も微妙な処理が残っているのでNimBLEを使ったほうが安定しているような気がします。

ボタンの違いがない?

iOS用とAndroid用のボタンが搭載されており、昔に確認したところちょっとだけ違うコードが飛んできました。しかし220円のリモコンを確認してみたところ、両方同じコードが飛んできています。

そして後期型の330円のリモコンでも同じコードが飛んできています。。。

家の中を探して初期型の330円リモコンを検証したところ、別のキーが飛んできています。このように初期のAndroidではボリュームアップだけではシャッターが降りなかったモデルがあったので、エンター押してからボリュームアップを飛ばしていたようです。

現状はほぼすべての端末がボリュームアップを飛ばすだけでシャッターになるので送信するコードを統一したようです。なので、ここ数年に製造したものは2つあるキーを個別に取得することはできなくなっているようですのでご注意ください。

まとめ

中身のチップや設計はほとんど同じなのですが、微妙に金型が違う製品があるのでいろいろな工場で作られているようです。せっかくボタンが2つあるのに制御が同じになってしまい残念です。。。

コメント