본문 바로가기
Firmware_/아두이노

[ESP8266] ESP8266 NOW "WiFi 사용하지 않고, 보드끼리 컨트롤 해보자"

by Cocopop 2022. 4. 6.
반응형

ESP-NOW는 WiFi를 사용하지 않고, 기기안에 MAC 주소를 이용해서 서로 통신하는 방식입니다.

 

즉, WiFi는 서버와 클라이언트로 연결해서 사용하는데 그런 부분을 제외하고

MAC로 이용해서 지그비 통신 처럼 서로 양방향으로 통신을 하는 겁니다.

 

 

 

 

 

 

 

 

 

밑에 연결 도면

오늘 ESP-NOW 코드를 가지고, 두 개 ESP8266 보드에서 통신을 보내 시간에 맞춰

LED를 켜고 끄는 동작을 시킬 거에요.

 

 

컴파일러는 아두이노 프로그램으로 사용할 것이며, ESP8266에 데이터를 업로드 하는

프로그램 중에 아두이노가 제일 편한 것 같아요.

 

 

 

<준비물>

- ESP8266 보드 2개 준비.

- LED 2개 준비.

- 브래드 보드 2개 준비.

- 저항 10k옴, 330옴 준비.

- 연결 선 준비.

 

 

 

 

 

 

 

<동작 방법>

 

1. 각 보드에 MAC 주소를 찾는다.

#include <ESP8266WiFi.h>

void setup(){

	Serial.begin(115200);
    Serial.println();
    Serial.print("ESP8266 MAC Address : ");
	Serial.println(WiFi.macAddress());
    
}

void loop(){


}

위와 같은 코드를 작성해서 ESP8266 안에 업로드를 합니다.

(ESP8266 업로드 할때, GPIO0핀은 꼭 GND에 연결 하셔야 합니다.)

 

 

 

업로드가 끝나면, GPIO0핀은 GND에서 빼주시고 RESET 해주면서 시리얼을 보면

위와 같은 MAC 주소가 나올거에요.

(이 부분을 따로 적던가 저장을 합니다.)

 

이걸 두 번 작업해서 두 보드의 MAC 주소를 찾아 냅니다.

 

 

 

 

 

 

2. 양방향 통신으로 LED를 시간에 맞춰 켜고 끄기.

 

#include <ESP8266WiFi.h>	// ESP8266 헤더파일
#include <espnow.h>			// ESP-NOW 헤더파일
#include <Ticker.h>			// ESP8266 인터럽트 헤더파일

Ticker flipper;				

#define GPIO2 2				// LED PIN

// 통신으로 데이터를 송신, 수신으로 받고, 보낼 변수
String Rx_buf;
String RX_DATA;
String TX_buf;

// 타이머 인터럽트에 사용 될 변수
int count = 0;
char timer_cnt = 0;

//==============================================================================


// 데이터를 보낼 ESP8266 보드 MAC 주소를 입력합니다.
//uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};



// 데이터를 보내고, 잘 보내졌는지 확인 유무를 시리얼 통신으로 보여주는 부분입니다.
void onDataSent(uint8_t *mac_addr, uint8_t sendStatus){

  Serial.print("Last Packet Send Status: ");
  if(sendStatus == 0){
    Serial.println("Delivery Success");  
  }
  else{
    Serial.println("Delivery fail");  
  }

}


// 데이터 수신이 왔을때, 이 함수에 들어가 데이터를 변수에 저장 시킵니다.
void OnDataRecv(uint8_t *mac, uint8_t *incomingData, uint8_t len){

  memcpy(&Rx_buf, incomingData, sizeof(Rx_buf));
  Serial.print("Bytes received: ");
  Serial.println(len);
  RX_DATA = Rx_buf;  
  
}


// 수신 받은 변수 데이터를 비교하여, 원하는 값이 올 경우 LED를 켜고 끄게 코드를 적었습니다.
void printlncomingReadings(){
  
  Serial.print(RX_DATA);
  if(RX_DATA == "on0"){
    RX_DATA = "";
    digitalWrite(GPIO2, 1);
  }
  else if(RX_DATA == "off0"){
    RX_DATA = "";
    digitalWrite(GPIO2, 0);
  }
  
}


// 타이머 인터럽트 함수
void flip(){

  timer_cnt = 1;
  
}

//==============================================================================

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  pinMode(GPIO0, OUTPUT);
  digitalWrite(GPIO0, 0);
  pinMode(GPIO2, OUTPUT);
  digitalWrite(GPIO2, 0);

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }  

  // Set ESP-NOW Role
  esp_now_set_self_role(ESP_NOW_ROLE_COMBO);

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(onDataSent);
  
  // Register peer
  esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
  
  // Register for a callback function that will be called when data is received
  esp_now_register_recv_cb(OnDataRecv);

// 타이머 인터럽트 설정인데, 앞에 숫자는 sec를 의미
  flipper.attach(1,flip);
}



void loop() {
  // put your main code here, to run repeatedly:

  // 타이머 인터럽트 설정을 1초마다 들어가게 하여, 1초에 한번씩 if문에 들어가 데이터를 보냅니다.
  if(timer_cnt == 1){
    timer_cnt = 0;
   
    if(count == 0){
      count = 1;
      TX_buf = "on1";  
      Serial.print(TX_buf);
    }
    else{
      count = 0;
      TX_buf = "off1"; 
      Serial.print(TX_buf);      
    }

   // 위에 데이터 변수가 채워졌을 경우, 상대방에게 데이터를 보냅니다. 
    esp_now_send(broadcastAddress, (uint8_t *) &TX_buf, sizeof(TX_buf));
  }
  
  // 수시로 확인 : 수신으로 받은 데이터가 맞으면 이 함수에서 LED를 켜고 끄고 합니다.
  printlncomingReadings();
  
}

위에 코드는 1초마다 상대방 보드에게 "on1", "off1" 데이터를 보냅니다.

그러면 상대방 보드는 1초 마다 위에 데이터를 받고, 자신의 LED를 켜고 끕니다.

 

다른 보드에 코딩을 했을때도 위와 같은 방식으로 코드를 작성하고, 보내는 데이터와 시간만 수정해서 업로드 하면 됩니다. (MAC 주소두요)

 

 

 

 

 

 

 

저 같은 경우는 보드 1은 1초마다 데이터를 보내고, 보드 2는 3초마다 데이터를 보내는 코드를 작성했습니다.

실제 테스트 한 영상은 밑에 영상으로 보시면 될 것 같아요. ㅎㅎ

 

 

 

보통 STM이나 AVR에 작성할 경우는 작성해야할 드라이버들이 많을 텐데, 아두이노로 작업해보니

그렇게 어렵지 않게 테스트를 할 수 있었습니다.

 

 

 

 

300x250

'Firmware_ > 아두이노' 카테고리의 다른 글

[아두이노] MPU-6050 자이로센서 TEST  (0) 2021.09.30
[아두이노] 블루투스 HC-06 TEST  (0) 2021.09.29