앞선 글들에서 ESP-NOW 통신으로 ESP32/esp8266 보드에서 1:1양방향 통신을 소개한 바 있었다.
https://blog.naver.com/mythee1/223291266342
그런데 이를 발전시켜 복수의 ESP 보드들과 ESP-NOW 방식으로 양방향 통신을 시도하기 위해, 다음과 같이 회로를 구성했다.
즉, 오른쪽 ESP32(=sender)에서 버튼을 누르면 ESP-NOW 메시지를 송신하는 의미의 백색 LED를 켜고,
왼쪽에 위치한 별도의 ESP32(Receiver 1) 및 ESP8266(Receiver 2) 보드에서 이 통신 메시지를 수신한 후, 잘 수신했다는 의미로 각각에 연결된 LED를(Receiver 1 – 백색, Receiver 2 – 청색) 켜게 된다.
그리고, 각각의 보드들은 메시지를 잘 수신했다는 내용의 메시지를 오른쪽에 위치한 ESP 보드(=Sender)에게 송신하데 되는데, Sender가 이를 수신하면, 전체적인 양방향 통신이 잘 이루어졌음을 확인해 주는 의미로 각기 Receiver 1의 확인용과, Receiver 2의 확인용에 할당된 노란색 및 녹색 LED를 각각 켜게 된다.
만일 Sender에서 버튼스위치가 떨어지면, 동일한 순서대로 통신이 이루어지면서 LED들이 꺼지게 된다.
이를 위하여 Sender 쪽 코드에서 달라지는 것은
먼저 Receiver ESP 보드들의 MAC 주소를 기재하고, 각각 add_peer 해주는 게 필요하다.
그리고, 버튼의 동작 이후, 반송되어 오는 확인 메시지를 수신하기 위해 메시지 수신 및 수신 메시지에 따른 동작을 선택하는 다음 문구 이하 부분의 추가가 필요하다. 수신확인 메시지를 보내는 receiver 보드들의 숫자만큼 이 동작이 필요하다.
_, msg = esp.recv()
최종적으로 Sender 쪽에서 사용한 최종 Code는 다음과 같다.
import network
from machine import Pin
import espnow
import utime
sta = network.WLAN(network.STA_IF)
sta.active(True)
sta.disconnect()
esp = espnow.ESPNow()
esp.active(True)
Noofreceiver=2
peer32 = b'$bxabxff(xdc'
peer8266 = b'xb4xe6-pDn'
esp.add_peer(peer32)
esp.add_peer(peer8266)
button = Pin(23, Pin.IN, Pin.PULL_DOWN)
led = Pin(22, Pin.OUT)
ledA = Pin(21, Pin.OUT)
ledB = Pin(18, Pin.OUT)
buttonwas = 0
while True:
buttonnow = button.value()
if buttonnow != buttonwas:
if buttonnow == 1:
message = "SWOn"
led.value(1)
else:
message = "SWOff"
led.value(0)
print("Sending command : ", message)
esp.send(peer32, message)
esp.send(peer8266, message)
for i in range(Noofreceiver):
_, msg = esp.recv()
if msg:
if msg == b'AOn':
utime.sleep(0.2)
ledA.value(1)
print("Rcvd message from A : AOn")
elif msg == b'AOff':
utime.sleep(0.2)
ledA.value(0)
print("Rcvd message from A : AOff")
elif msg == b'BOn':
utime.sleep(0.2)
ledB.value(1)
print("Rcvd message from B : BOn")
elif msg == b'BOff':
utime.sleep(0.2)
ledB.value(0)
print("Rcvd message from B : BOff")
else:
print("Unknown")
buttonwas = buttonnow
한편 Receiver 쪽에서 최종적으로 사용한 Code는 다음과 같은데, 과거 1:1 양방향 통신에서와 기본적으로 동일하나, 각 Receiver 보드들을 구분하기 위해 반송하는 메시지를 “AOn” “BOn” “AOff” “BOff” 등의 방식으로 다르게 지정해 주었다.
import network
import espnow
import utime
from machine import Pin
sta = network.WLAN(network.STA_IF)
sta.active(True)
sta.disconnect()
esp = espnow.ESPNow()
esp.active(True)
peer = b'xe4exb8rTxf4' #E4:65:B8:0D:54:F4
esp.add_peer(peer)
led = Pin(22, Pin.OUT)
while True:
_, msg = esp.recv()
if msg:
if msg == b'SWOn':
utime.sleep(0.2)
print("Turn on SW")
led.on()
msgback="AOn"
esp.send(peer, msgback)
elif msg == b'SWOff':
utime.sleep(0.2)
print("Turn off SW")
led.off()
msgback="AOff"
esp.send(peer, msgback)
else:
print("Unknown")
정상적으로 동작하면 각 보드별 출력 결과는 다음과 같으며,
실제 동작 모습은 다음과 같다.
코딩 시 한 가지 주의할 것은 Sender Code에서 상대측 확인 메시지를 받는 부분을 Receiver들의 수만큼 반복해 주어야 한다는 점이다.
위의 Sender 측 코드에서는 다음과 같이 for 문을 이용하여 해결하였다. range( ) 안에는 미리 지정해둔 Receiver들의 수값에 해당되는 변수를 지정했다.
만일 이 부분을 Receiver 수만큼 반복하지 않는 경우에는, 각각의 Receiver에서 보내온 확인 메시지들 중이 입력버퍼에 남아 오동작을 유발하기 때문으로, 실제 오동작 모습은 다음과 같다.

