Espressifの独自規格のESP-Nowは、ルーターを経由する必要がなく、1対1、1対多の通信ができます。
M5Stack間の通信といえば、BLEもありますが、こちらの方が高速です。センサー値を別のM5Stackに送りたい場合、コード的にもこちらの方が扱いやすいので試してみました。
参考)
ESP-NOW with ESP32: Receive Data from Multiple Boards (many-to-one)
過去記事)
送信側
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
#include <M5Unified.h> #include <esp_now.h> #include <WiFi.h> uint8_t broadcastAddress[] = {0x, 0x, 0x, 0x, 0x, 0x}; // Mac Address // Structure example to send data // Must match the receiver structure typedef struct struct_message { int id; // must be unique for each sender board int x; int y; } struct_message; // Create a struct_message called myData struct_message myData; // Create peer interface esp_now_peer_info_t peerInfo; // callback when data is sent void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { Serial.print("\r\nLast Packet Send Status:\t"); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); } void setup() { Serial.begin(115200); auto cfg = M5.config(); M5.begin(cfg); M5.Display.setTextSize(2); M5.Lcd.setRotation(1); M5.Lcd.print("espnow"); // Set device as a Wi-Fi Station WiFi.mode(WIFI_STA); // Init ESP-NOW if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; } // Once ESPNow is successfully Init, we will register for Send CB to // get the status of Trasnmitted packet esp_now_register_send_cb(OnDataSent); // Register peer memcpy(peerInfo.peer_addr, broadcastAddress, 6); peerInfo.channel = 0; peerInfo.encrypt = false; // Add peer if (esp_now_add_peer(&peerInfo) != ESP_OK){ Serial.println("Failed to add peer"); return; } } void loop() { // Set values to send myData.id = 1; myData.x = random(0,50); myData.y = random(0,50); M5.Lcd.print("*"); // Send message via ESP-NOW esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData)); if (result == ESP_OK) { Serial.println("Sent with success"); } else { Serial.println("Error sending the data"); } delay(1000); } |
受信側
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
#include <M5Unified.h> #include <esp_now.h> #include <WiFi.h> // Structure example to receive data // Must match the sender structure typedef struct struct_message { int id; int x; int y; }struct_message; // Create a struct_message called myData struct_message myData; // Create a structure to hold the readings from each board struct_message board1; struct_message board2; struct_message board3; // Create an array with all the structures struct_message boardsStruct[3] = {board1, board2, board3}; // callback function that will be executed when data is received void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) { char macStr[18]; Serial.print("Packet received from: "); snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); Serial.println(macStr); memcpy(&myData, incomingData, sizeof(myData)); Serial.printf("Board ID %u: %u bytes\n", myData.id, len); // Update the structures with the new incoming data boardsStruct[myData.id-1].x = myData.x; boardsStruct[myData.id-1].y = myData.y; Serial.printf("x value: %d ", boardsStruct[myData.id-1].x); Serial.printf("y value: %d \n", boardsStruct[myData.id-1].y); M5.Lcd.print("*"); } void setup() { //Initialize Serial Monitor Serial.begin(115200); auto cfg = M5.config(); M5.begin(cfg); M5.Display.setTextSize(2); M5.Lcd.setRotation(1); //Set device as a Wi-Fi Station WiFi.mode(WIFI_STA); char macAdr[24]; byte mac[6]; WiFi.macAddress(mac); sprintf(macAdr, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); Serial.println(macAdr); //Init ESP-NOW if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; } // Once ESPNow is successfully Init, we will register for recv CB to // get recv packer info esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv)); M5.Lcd.print("esp now many receive..."); } void loop() { delay(10000); } |
ここではM5Stickの1対1ですが、M5Stack Core2 / M5Stick x 2 の1対多でも確認しています。デバイスはMACアドレスで識別できます。
UIFlowでテストしたことは覚えていたのですが、Broadcastをテストしていたことは忘れていました。ブログは自分にとっても参考になりますね。