Last active
October 13, 2024 11:31
-
-
Save ksasao/0431fb4e2eb8cdacd42427589632d41e to your computer and use it in GitHub Desktop.
M5Stack + LANモジュールでBLEビーコンのアドバタイジングパケットを受信してMQTTで送信するサンプル
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <M5Stack.h> | |
| //#include <M5_Ethernet.h> | |
| #include <Ethernet2.h> // Please also fix Server.h according to https://twitter.com/ksasao/status/1845423873313079331 | |
| #include <BLEDevice.h> | |
| #include <BLEUtils.h> | |
| #include <BLEScan.h> | |
| #include <PubSubClient.h> | |
| #include <WiFiClient.h> | |
| #include <ArduinoUniqueID.h> | |
| #define SCK 18 | |
| #define MISO 19 | |
| #define MOSI 23 | |
| #define CS 26 | |
| // MQTT Broker settings | |
| const char* mqtt_broker = "192.168.3.18"; // 接続先 MQTT Broker の IPアドレス | |
| String mqtt_topic; // MQTTのTopic名。setup()で初期化する。 | |
| IPAddress ip(192, 168, 3, 88); // M5Stack側の静的IPアドレス | |
| byte mac[] = { UniqueID[0], UniqueID[1], UniqueID[2],UniqueID[3], UniqueID[4], UniqueID[5] }; | |
| // M5StackのLANモジュールのMACアドレスは初期状態では未設定のため利用者が設定する必要がある。 | |
| // 他のデバイスとぶつからないようにするため、ここではESP32のUniqueIDを流用。 | |
| // arp -a などでIPアドレスとの紐づけを確認できる | |
| // MQTTのClientId生成用 | |
| const char hex[17]="0123456789ABCDEF"; | |
| char id[100]; | |
| String clientId; | |
| // ESP32のチップごとに割り当てられた固有のIDをclientIDとして利用 | |
| String createClientId(){ | |
| id[UniqueIDsize*2]='\0'; | |
| for(size_t i = 0; i < UniqueIDsize; i++){ | |
| id[i*2] = hex[UniqueID[i] >> 4]; | |
| id[i*2+1] = hex[UniqueID[i] & 0xF]; | |
| } | |
| String clientId = String((char*) id); | |
| return clientId; | |
| } | |
| EthernetClient ethClient; | |
| PubSubClient client(ethClient); | |
| void setup() { | |
| // M5Stack初期化 | |
| M5.begin(true, false, true); | |
| M5.Power.begin(); | |
| // LANモジュール初期化 | |
| SPI.begin(SCK, MISO, MOSI, -1); | |
| Ethernet.init(CS); | |
| Ethernet.begin(mac, ip); | |
| // MQTT初期化 | |
| clientId = createClientId(); | |
| mqtt_topic = "ble/" + clientId; | |
| client.setServer(mqtt_broker, 1883); | |
| // IPアドレスを表示 | |
| Serial.println(Ethernet.localIP()); | |
| M5.Lcd.clear(); | |
| M5.Lcd.setTextSize(2); | |
| M5.Lcd.print("Topic : "); | |
| M5.Lcd.println(mqtt_topic); | |
| M5.Lcd.print("IPAddr: "); | |
| M5.Lcd.print(Ethernet.localIP()); | |
| // BLE初期化 | |
| BLEDevice::init(""); | |
| } | |
| void loop() { | |
| // ネットワーク接続状態の確認と再接続 | |
| bool connected = true; | |
| if (!client.connected()) { | |
| connected = reconnect(); | |
| } | |
| client.loop(); | |
| // BLEビーコンのスキャン | |
| BLEScan* pBLEScan = BLEDevice::getScan(); | |
| pBLEScan->setActiveScan(true); | |
| BLEScanResults foundDevices = pBLEScan->start(1); // スキャン間隔1秒 | |
| // macアドレス順に結果がソートされている | |
| int pos = 0; | |
| for (int i = 0; i < foundDevices.getCount(); i++) { | |
| BLEAdvertisedDevice device = foundDevices.getDevice(i); | |
| String macAddress = device.getAddress().toString().c_str(); | |
| int rssi = device.getRSSI(); | |
| // 他のビーコンも飛んでいることが想定されるので適宜フィルタする | |
| if (macAddress.startsWith("c1:c0")) { // ビーコン本体にMACアドレズが印字されているのでそれを参照した | |
| // MQTTで受信したアドバタイジングパケットのMAC AddressとRSSIを送信 | |
| String payload = "{\"Id\":\"" + macAddress + "\",\"Value\":" + String(rssi) + "}"; | |
| Serial.print(mqtt_topic); | |
| Serial.print(" "); | |
| Serial.println(payload); | |
| // 画面表示の更新 | |
| String view = macAddress + " " + String(rssi) + " "; | |
| M5.Lcd.setCursor(0, (pos+2)*16); | |
| M5.Lcd.print(view); | |
| pos++; | |
| if(connected){ | |
| client.publish(mqtt_topic.c_str(), payload.c_str()); | |
| } | |
| } | |
| } | |
| } | |
| // MQTT Broker 再接続処理。再接続できない場合には false を返して続行する。 | |
| bool reconnect() { | |
| bool connected = client.connected(); | |
| if (!connected) { | |
| Serial.print("Attempting MQTT connection ("); | |
| Serial.print(clientId); | |
| Serial.println(")"); | |
| if (client.connect(clientId.c_str())) { | |
| Serial.println("connected"); | |
| connected = true; | |
| } else { | |
| Serial.print("failed, rc="); | |
| Serial.println(client.state()); | |
| connected = false; | |
| } | |
| } | |
| return connected; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment