본문 바로가기

ESPRESSIF/ESP32-C6

[ESP32-C6 SSM] ESP-NOW를 이용한 리모컨 데이터 전송

 

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();  // 슬립 모드로 진입
  }
}

 

반응형