ESP-NOW는 Espressif Systems에서 개발한 ESP32, ESP8266 기기 간의 통신 프로토콜이다. MAC 주소를 기반으로 한 peer-to-peer 방식으로, 보드 간 양방향 통신이 가능하다.
ESP-NOW의 특징은 각 보드가 송신자이자 수신자가 될 수 있고 기기가 같은 WLAN 네트워크에 연결되어 있지 않아도 데이터를 전송할 수 있다. raw 802.11 패킷을 직접 사용하여 데이터를 전송하는 구조라 간단하고 저전력으로 구동 가능하다.
ESP32에서 슬립 모드에서 ESP-NOW를 사용하여 스위치 상태를 전송하는 예제를 작성해보자. ESP32는 저전력 모드를 제공하는 다양한 슬립 모드를 지원하므로, ESP32가 슬립 모드에 들어가고 스위치를 누를때 깨어나서 ESP-NOW를 사용하여 데이터를 전송하는 예제를 작성해 보자.
마스터 보드
PC에 연결된 마스터 보드에서는 ESP-NOW로 전송되는 데이터를 시리얼 포트로 출력 하도록 했다.
#include <esp_now.h>
#include <WiFi.h>
void setup() {
Serial.begin(115200);
// Wi-Fi 초기화
WiFi.mode(WIFI_STA);
// ESP-NOW 초기화
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW 초기화 실패");
return;
}
// 데이터 수신을 위한 콜백 함수 등록
esp_now_register_recv_cb(OnDataRecv);
Serial.println("수신 대기 중...");
}
void loop() {
// 메인 루프에서는 아무 작업을 하지 않음 (수신 대기)
delay(1000);
}
// 데이터 수신 콜백 함수
void OnDataRecv(const uint8_t *mac, const uint8_t *data, int len) {
Serial.print("데이터 수신: ");
String receivedData = "";
for (int i = 0; i < len; i++) {
receivedData += (char)data[i];
}
Serial.println(receivedData); // 수신된 데이터 출력
}
슬레이브 보드
스위치를 누를때 슬립모드에서 깨어나서 데이터 전송후 다시 슬립모드로 진입 하는 코드
ESP32-C6 Deep Sleep Mode 테스트 코드 참고
#include <esp_now.h>
#include <WiFi.h>
#define BUTTON_PIN 0 // 스위치가 연결된 GPIO 핀
// 데이터를 받을 수신 측의 MAC 주소 설정 (수신 측 ESP32의 MAC 주소)
uint8_t peerAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
void setup() {
Serial.begin(115200);
// Wi-Fi 초기화
WiFi.mode(WIFI_STA); // ESP-NOW를 사용하려면 STA 모드여야 함
// ESP-NOW 초기화
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW 초기화 실패");
return;
}
// 수신 측의 MAC 주소를 peer로 추가
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, peerAddress, 6);
peerInfo.channel = 0; // 기본 채널 사용
peerInfo.encrypt = false; // 암호화 사용 안함
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Peer 추가 실패");
return;
}
pinMode(BUTTON_PIN, INPUT_PULLUP); // 스위치 핀 설정 (내부 풀업 저항 사용)
esp_deep_sleep_enable_gpio_wakeup(1 << INTERRUPT_PIN, ESP_GPIO_WAKEUP_GPIO_HIGH);
// 슬립 모드로 진입하지 않도록 설정
Serial.println("슬립 모드 진입...");
//esp_deep_sleep_start();
}
void loop() {
// 스위치가 눌렸는지 확인
if (digitalRead(BUTTON_PIN) == LOW) {
Serial.println("스위치 눌림, ESP-NOW 데이터 전송");
// 전송할 데이터 정의
String message = "SW0";
const char *msg = message.c_str();
// ESP-NOW를 통해 데이터 전송
esp_err_t result = esp_now_send(peerAddress, (uint8_t *)msg, message.length());
if (result == ESP_OK) {
Serial.println("데이터 전송 성공");
} else {
Serial.println("데이터 전송 실패");
}
// 5초 동안 스위치가 눌리지 않으면 슬립 모드로 진입
unsigned long startMillis = millis();
while (millis() - startMillis < 5000) {
if (digitalRead(BUTTON_PIN) == LOW) {
// 스위치가 눌린 상태이면 루프를 빠져나와서 다시 전송
Serial.println("스위치 계속 눌림, 데이터 전송 대기...");
return; // 다시 데이터를 전송하고 대기
}
}
// 1초 동안 스위치가 눌리지 않으면 슬립 모드로 전환
Serial.println("5초 동안 스위치가 눌리지 않음. 슬립 모드로 전환...");
esp_deep_sleep_start(); // 슬립 모드로 진입
}
}
반응형