Dries Vercauteren
Dries Vercauteren

Reputation: 1

ESPNOW ValueError in esp.irecv() - Micropython

I am part of a student organization called "Formula Electric Belgium". As part of my project, I must establish communication between two modules. While researching my options, I stumbled upon ESPNOW, a communication protocol developed for the ESP32. So I bought myself two ESP32 WROOM developerboards and started experimenting. After a while, I had working communication. However, every once in a while I had a ValueError (ValueError: ESPNow.recv(): buffer error). This error is unpredictable and almost seems random.

At first, I tried to directly solve the problem and take a look in the espnow library code. However, this code was too complex and I couldn't find anything concerning a buffer. So I tried to solve the problem by simply avoiding it. This tactic works 99% of the time. But the more I work on the project, the more the error keeps returning. I think it would be more efficient to solve the problem instead of avoiding it. Following you'll find the code I've written for both microcontrollers.

ESP32-1:

### set-up ###
import network
from machine import Pin, Timer, reset
import espnow
from time import sleep

sta = network.WLAN(network.STA_IF)
sta.active(True)

esp = espnow.ESPNow()
esp.active(True)

peer = b'\xa0\xb7e\xdd\x13\x14'
esp.add_peer(peer)

### variables ###
time_now = 0
time_start = 0
time_stop = 0
time_delta = 0
timer = Timer(1)
button = Pin(13, Pin.IN)
x = False

### functions ###
def time(timer):
    global time_now
    time_now += 1

### main ###
timer.init(period=1,mode=Timer.PERIODIC, callback=time)

while True:
    if button.value():
        sleep(0.2)
        if not button.value():
            esp.send(peer, 'start')
            time_start = time_now
            Pin(2, Pin.OUT).on()
            x = True
    try:
        while x:
            _, msg = esp.irecv()
            if msg == b'stop':
                time_stop = time_now
                Pin(2, Pin.OUT).off()
                x = False
                time_delta = float((time_stop - time_start)/1000)
                esp.send(peer, str(time_delta))
    except ValueError:
        print("ValueError")
        reset()

ESP32-2:

### set-up ###
import network
from machine import Pin, Timer, SoftI2C
import espnow
from time import sleep
import sh1106

sta = network.WLAN(network.STA_IF)
sta.active(True)

esp = espnow.ESPNow()
esp.active(True)

peer = b'|\x9e\xbda\x81\xcc'
esp.add_peer(peer)

i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
oled = sh1106.SH1106_I2C(128, 64, i2c, Pin(16), 0x3c)

### variables ###
time_now = 0
time_start = 0
time_stop = 0
time_delta = 0
timer = Timer(1)
button = Pin(13, Pin.IN)
x = True
a = 0

### functions ###
def time(timer):
    global time_now
    time_now += 1

def display(time, a, error):
    oled.sleep(False)
    oled.fill(0)
    if error:
        oled.text("ValueError", 0, 32, 1)
    oled.text('time:'+ str(time)+"s", 0, 0, 1)
    oled.text('acc:'+ str(a)+" m/s^2", 0, 16, 1)
    oled.show()

### main ###
timer.init(period=1,mode=Timer.PERIODIC, callback=time)

while True:
    while x:
        _, msg = esp.irecv()
        if msg == b'start':
            time_start = time_now
            Pin(2,Pin.OUT).on()
            x = False
    while not x:
        if button.value():
            sleep(0.2)
            if not button.value():
                esp.send(peer, 'stop')
                time_stop = time_now
                Pin(2,Pin.OUT).off()
                x = True
                time_delta = round(float((time_stop - time_start)/1000),3)
    _, msg = esp.irecv(1000)
    if msg:
        time_delta = round((time_delta + float(msg))/2,3)
        a = round(float(150/((time_delta)**2)),2)
        display(time_delta, a, False)
    else:
        a = round(float(150/(time_delta**2)),2)
        display(time_delta, a, True)
        print("ValueError")
        
    print(round(time_delta,3))
    print(round(a, 2), 'm/s²')

EDIT: I wrote a program that constantly sends ping messages and added a function that it prints the message when the error occurs. The last message was: "b'ping_back\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'"

While it should've just been 'ping_back'. Also note that once this error occurs, the error is given on all the next messages until the microcontroller is rebooted.

Upvotes: 0

Views: 174

Answers (0)

Related Questions