esp.irecv() 中的 ESPNOW ValueError - Micropython

ESPNOW ValueError in esp.irecv() - Micropython

提问人:Dries Vercauteren 提问时间:11/14/2023 最后编辑:Dries Vercauteren 更新时间:11/14/2023 访问量:24

问:

我是一个名为“比利时电动方程式”的学生组织的一员。作为项目的一部分,我必须在两个模块之间建立通信。在研究我的选择时,我偶然发现了 ESPNOW,这是为 ESP32 开发的通信协议。于是我给自己买了两块 ESP32 WROOM 开发板,开始实验。过了一会儿,我有了工作沟通。但是,每隔一段时间我就会遇到 ValueError(ValueError:ESPNow.recv():缓冲区错误)。这个错误是不可预测的,几乎是随机的。

起初,我尝试直接解决问题,并查看 espnow 库代码。但是,这段代码太复杂了,我找不到任何关于缓冲区的内容。所以我试图通过简单地避免它来解决这个问题。这种策略在 99% 的情况下都有效。但是我在这个项目上工作得越多,错误就越多。我认为解决问题比避免问题更有效。下面您将找到我为这两个微控制器编写的代码。

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.

python esp32 通信 micropython esp-now

评论

0赞 furas 11/15/2023
I don't see string in your code.ping_back
0赞 furas 11/15/2023
Maybe first use (and , , etc.) to see which part of code is executed and what you really have in variables. It is called and it helps to see what code is really doing.print()print(type(...))print(len(...))"print debuging"
0赞 furas 11/15/2023
maybe you should skip to see FULL error message - it can help to see problem.try/except

答: 暂无答案