본문 바로가기

ESP32

아두이노 Nano ESP32 빠른 가이드 6 - ESP-NOW

반응형

 

ESP-NOW를 사용한 장치 간 통신

 

ESP-NOW 프로토콜을 사용하여 ESP 기반 보드 간에 데이터를 전송하는 방법을 알아보세요. 

 

 

이 포스팅을 포함하여 작성한 전체 링크는 아래 리스트를 참고하세요. 배움을 절대로 멈추지 마세요.

 

아두이노 Nano ESP32 빠른 가이드 1 - 시작 & FAQ

아두이노 Nano ESP32 빠른 가이드 2 - 스펙과 튜토리얼

아두이노 Nano ESP32 빠른 가이드 3 - 치트시트

아두이노 Nano ESP32 빠른 가이드 4 - 클라우드

아두이노 Nano ESP32 빠른 가이드 5 - 디버깅

아두이노 Nano ESP32 빠른 가이드 6 - ESP-NOW

아두이노 Nano ESP32 빠른 가이드 7 - 시작하기

아두이노 Nano ESP32 빠른 가이드 8 - 핀 설정

아두이노 Nano ESP32 빠른 가이드 9 - SPIFFS 파티션

 

 

소개

 

ESP-NOW는 ESP32 마이크로컨트롤러(MCU)의 개발사인 Espressif에서 개발한 무선 통신 프로토콜입니다. 아두이노 나노 ESP32에는 해당 MCU가 장착되어 있으므로 ESP-NOW 프로토콜도 기본적으로 지원됩니다. 이 프로토콜은 최대 250바이트까지 전송할 수 있는 장치 간의 효율적이고 짧은 지연 시간 통신을 위해 설계되었습니다.

 

하드웨어 요구 사항

 

ESP-NOW는 다음 마이크로컨트롤러에서 지원됩니다:

 

  • 아두이노 나노 ESP32
  • 일반 ESP8266
  • 일반 ESP32
  • 일반 ESP32-S
  • ESP32-C 시리즈 SoC

 

ESP-NOW를 통해 통신하려면 두 개 이상의 보드가 필요합니다. 최소 한 개의 발신기와 한 개의 수신기가 필요합니다.

 

작동 방식

 

통신 프로토콜

 

ESP-NOW는 P2P(피어 투 피어) 프로토콜로 작동하므로 중앙 서버나 액세스 포인트(예: Wi-Fi® 라우터) 없이도 두 개의 ESP8266 또는 ESP32 장치 간에 직접 통신할 수 있습니다. 각 ESP 장치에는 수신 보드를 식별하는 데 사용되는 고유한 MAC 주소가 있습니다.

 

ESP-NOW는 다양한 방식으로 설정할 수 있습니다:

 

단방향 통신: 단방향 통신 모드에서는 한 장치(발신자)가 응답을 기대하지 않고 다른 장치(수신자)에게 데이터를 보낼 수 있습니다. 이 모드는 원격 센서 판독이나 제어 명령과 같이 한 장치가 다른 장치에 데이터나 명령을 제공하는 시나리오에 자주 사용됩니다.

 

양방향 통신: 양방향 통신 모드에서는 두 장치가 양방향으로 데이터를 교환할 수 있습니다. 이 모드를 사용하면 디바이스 간에 정보를 주고받을 수 있으므로 보다 상호 작용적이고 반응이 빠른 커뮤니케이션이 가능합니다. 원격 제어 시스템이나 대화형 IoT 디바이스와 같이 디바이스가 서로 데이터를 주고받아야 하는 애플리케이션에 적합합니다. 

 

 

ESP-NOW Communication

 

프로토콜 스택

 

ESP-NOW는 주로 OSI 모델의 데이터 링크 계층에서 작동합니다. 여러 계층을 포함하는 기존 네트워킹 프로토콜과 달리 ESP-NOW는 통신 스택을 압축하여 프로세스를 간소화합니다. 프로토콜 스택을 단일 계층으로 줄임으로써 ESP-NOW는 각 계층에 복잡한 패킷 헤더와 언패커가 필요하지 않습니다. 이렇게 단순화하면 응답 시간이 빨라져 혼잡한 네트워크에서 패킷 손실로 인한 지연이 줄어듭니다.

 

TCP/IP and ESP-NOW Protocol Stack

 

 

경량 설계

 

이 프로토콜은 통신 오버헤드를 최소화하여 리소스가 제한된 디바이스에서 더욱 효율적으로 사용할 수 있습니다. 또한 디바이스가 사전 구성되므로 핸드셰이크를 수행하지 않아 데이터 전송 속도가 빨라지고 전력 소비가 줄어듭니다.

 

제한된 데이터 양

 

ESP-NOW는 적은 양의 데이터(최대 250바이트)를 전송할 때 유용합니다. 통신을 위해 액션 프레임을 활용합니다. 액션 프레임은 수행 중인 작업에 대한 정보를 포함하는 특수 데이터 프레임입니다. 이러한 프레임을 통해 ESP-NOW 장치는 보다 일반적인 데이터 프레임과 관련된 오버헤드 없이 효율적으로 데이터를 교환할 수 있습니다.

 

 

Action Frames

 

짧은 지연 시간

 

제한된 데이터 양과 경량 설계 덕분에 ESP-NOW는 지연 시간이 짧아 디바이스가 데이터를 빠르게 교환할 수 있어 무선 자동차 등 다른 디바이스를 원격으로 제어하는 데 적합합니다.

 

제한 사항

 

제한된 범위

 

ESP-NOW의 신호 범위는 일반적으로 이상적인 조건에서 약 220미터로 제한됩니다. 실제 범위는 환경 간섭, 안테나 설계, 통신 경로의 장애물 등의 요인에 따라 달라질 수 있습니다.

 

간섭

 

2.4GHz 대역에서 작동하는 다른 무선 통신 기술과 마찬가지로 ESP-NOW는 다른 디바이스 및 Wi-Fi 네트워크의 간섭에 취약할 수 있습니다. 간섭을 최소화하고 안정적인 통신을 보장하려면 통신 채널을 신중하게 선택하는 것이 중요합니다.

 

네트워크 인프라 없음

 

ESP-NOW는 포인트 투 포인트 및 포인트 투 멀티포인트 통신을 위해 설계되었지만 복잡한 네트워크 토폴로지를 구축하기 위한 인프라는 제공하지 않습니다. 애플리케이션에 여러 장치가 상호 연결된 네트워크 또는 인터넷 연결이 필요한 경우 추가 네트워킹 솔루션으로 ESP-NOW를 보완해야 할 수 있습니다.

 

제한된 데이터 페이로드

 

ESP-NOW는 최대 페이로드가 약 250바이트인 소량의 데이터를 전송하는 데 최적화되어 있습니다. 애플리케이션에 고대역폭 데이터 전송이나 대용량 파일 교환이 필요한 경우 Arduino Cloud와 같은 다른 서비스가 더 적합할 수 있습니다.

 

보안 고려 사항

 

ESP-NOW는 어느 정도의 데이터 프라이버시를 제공하지만, 강력한 암호화를 사용하는 HTTPS 또는 MQTT와 같은 다른 통신 프로토콜만큼 안전하지 않을 수 있습니다. 프로젝트에 민감한 데이터가 포함된 경우 도청 및 무단 액세스로부터 보호하기 위해 추가 보안 조치를 구현하는 것을 고려하세요.

 

메시지 확인 기능 없음

 

ESP-NOW는 성공적인 메시지 전달을 확인하기 위한 기본 제공 승인 메커니즘을 제공하지 않습니다. 애플리케이션에 메시지 안정성이 중요한 경우 자체적인 승인 및 오류 처리 메커니즘을 구현해야 합니다.

 

호환성

 

ESP-NOW는 주로 ESP8266 및 ESP32 마이크로컨트롤러와 함께 사용하도록 설계되었습니다. 다른 ESP32 기반 디바이스와도 호환될 수 있지만, 다른 비 ESP 플랫폼에서는 원활하게 작동하지 않을 수 있습니다. 여러 유형의 디바이스로 시스템을 설계할 때는 호환성을 고려해야 합니다.

 

아두이노 클라우드

 

Arduino는 무선 통신을 처리하기 위한 자체 서비스인 Arduino Cloud를 제공합니다. 자세한 내용은 여기에서 확인할 수 있습니다. Arduino Cloud는 ESP-NOW 프로토콜과 유사한 기능을 제공하지만 크게 다르므로 특정 사용 사례에 사용해야 합니다. 자세한 내용은 아래 비교표를 참조하세요. 

 

  Arduino Cloud ESP-NOW
Range Depends on Internet connectivity, suitable for global reach. Approx. 220 m.
Security Secure communication with encryption and authentication. Basic security, may need additional measures.
Delay Network-related delays due to Internet communication. Low latency for local communication.
Data Size Unlimited data (min. Entry plan) max 250 bytes.
Device Compatibility Compatible with various Arduino boards and IoT devices. Primarily used with ESP8266 and ESP32 microcontrollers.
Protocol Uses MQTT for communication. Uses a custom ESP-NOW protocol.
Power Consumption May consume more power, especially when connected to the internet. Known for low power consumption.
Data Processing Allows for Cloud-based data processing and analytics. Primarily for direct device-to-device communication.
Use Cases IoT projects requiring global connectivity and Cloud-based data management. Applications needing low-latency, local communication.

 

참고: 여기에서 다양한 Arduino Cloud 요금제를 확인하세요. 

 

 

코드

 

아래에서 ESP-NOW 프로토콜을 통한 데이터 송수신 예시를 확인할 수 있습니다. 먼저 수신 보드의 MAC 주소를 식별하여 발신자에게 데이터를 전송할 위치를 알려야 합니다. 보드의 MAC 주소를 식별하려면 다음 코드를 업로드하세요: 

 

// Complete Instructions to Get and Change ESP MAC Address: https://RandomNerdTutorials.com/get-change-esp32-esp8266-mac-address-arduino/

#include "WiFi.h"

void setup(){
  Serial.begin(115200);
  WiFi.mode(WIFI_MODE_STA);
  Serial.println(WiFi.macAddress());
}
 
void loop(){

}

 

 

발신자 스케치 코드

 

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include <esp_now.h>
#include <WiFi.h>

// REPLACE WITH YOUR RECEIVER MAC Address
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
  char a[32];
  int b;
  float c;
  bool d;
} struct_message;

// Create a struct_message called myData
struct_message myData;

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() {
  // Init Serial Monitor
  Serial.begin(115200);
 
  // 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 Transmitted 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
  strcpy(myData.a, "THIS IS A CHAR");
  myData.b = random(1,20);
  myData.c = 1.2;
  myData.d = false;
  
  // 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(2000);
}

 

수신자 스케치 코드

 

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include <esp_now.h>
#include <WiFi.h>

// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
    char a[32];
    int b;
    float c;
    bool d;
} struct_message;

// Create a struct_message called myData
struct_message myData;

// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("Char: ");
  Serial.println(myData.a);
  Serial.print("Int: ");
  Serial.println(myData.b);
  Serial.print("Float: ");
  Serial.println(myData.c);
  Serial.print("Bool: ");
  Serial.println(myData.d);
  Serial.println();
}
 
void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);
  
  // 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 recv CB to
  // get recv packer info
  esp_now_register_recv_cb(OnDataRecv);
}
 
void loop() {

}

 

자세히 보기

 

코드 작동 방식에 대한 자세한 설명은 randomnerdtutorials.com의 글을 참조하세요. esp_now 라이브러리에 대한 자세한 내용은 https://docs.espressif.com/ 에서도 확인할 수 있습니다.

 

요약

 

이 글에서는 ESP-NOW 프로토콜의 기본 사항과 작동 방식에 대해 설명했습니다. 또한 프로젝트의 시작점으로 사용할 수 있는 예제 코드도 제공했습니다. 전반적으로 ESP-NOW는 로컬 및 저지연 애플리케이션을 위한 강력한 통신 프로토콜로, 특히 ESP8266 및 ESP32 마이크로컨트롤러를 사용할 때 유용합니다. 하지만 프로젝트를 설계할 때 알아두어야 할 몇 가지 제한 사항이 있습니다. 

 

 

반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^