본문 바로가기

카테고리 없음

(esp32) esp now 양방향 통신

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);
}