esp32의 esp-now 프로토콜을 작년에 아주 흡족해하면서 공부했는데, 이번에 nRF24l01과 비교하면서 다시 정리하고 있다. 실내에서도 esp32가 nRF24l01보다 통신 거리도 잘 나오고 끊기지 않고 더 좋아 보인다. esp now 통신은 아래 사이트에서 아주 잘 설명하고 있다.
https://randomnerdtutorials.com/esp-now-two-way-communication-esp32/
여기서 나온 양방향 통신 코드에서 중복되는 부분을 좀 줄이고, 센서 없이 그냥 난수를 발생시켜 송수신하는 코드로 단순화시켜 보았다. 이 코드를 esp32 두 대에 똑같이 넣고 업로드하면 되는데, broadcastAddress만큼은 반드시 상대방 맥 어드레스로 바꾸어주어야 한다.
#include <esp_now.h>
#include <WiFi.h>
uint8_t broadcastAddress[] = {0x14, 0x2B, 0x2F, 0xC6, 0x47, 0xC0};
String success;
typedef struct struct_message {
float temp;
float hum;
float pres;
} struct_message;
struct_message BME280Readings;
struct_message incomingReadings;
esp_now_peer_info_t peerInfo;
void OnDataSent(const uint8_t *mac_address, 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 OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
Serial.print("Bytes received: ");
Serial.println(len);
}
void updateDisplay() {
Serial.println("INCOMING READINGS");
Serial.print("Temperature: ");
Serial.print(incomingReadings.temp);
Serial.println(" ºC");
Serial.print("Humidity: ");
Serial.print(incomingReadings.hum);
Serial.println(" %");
Serial.print("Pressure: ");
Serial.print(incomingReadings.pres);
Serial.println(" hPa");
Serial.println();
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
}
void loop() {
srand(millis());
// 센서 읽어서 저장하는 게 좋지만, 여기서는 간단히 난수 발생하여 저장.
BME280Readings.temp = (rand() % 100000) / (float) 100000;
BME280Readings.hum = (rand() % 100000) / (float) 100000;
BME280Readings.pres = (rand() % 100000) / (float) 100000;
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &BME280Readings, sizeof(BME280Readings));
if(result == ESP_OK) {
Serial.println("Sent with successs");
} else {
Serial.println("Error sending the data");
}
updateDisplay();
delay(1000);
}