乐鑫技术交流
直播中

李华

7年用户 1328经验值
私信 关注
[问答]

ESP32 arduino串口同时收发的疑问求解

我用ESP NOW 开发一个无线串口穿透程序,将收到的ESP_NOW报文发送到串口,同时将串口收到的消息通过ESP NOW 发出。希望能实现串口的串流
使用ARDUINO IDE 进行的开发。
但是串口串流中间总是会中断,在 ESP NOW onRecive 里面将数据写到 TX fifo 中,在loop 中将rx 的数据通过ESP NOW 转发出去
串口转发的速率为600bit/s ,串口接收的速率也为600bit/s,理论上串口波特率已经远低于 ESP NOW onRecive 中填充 TX fifo 的速率了,应该不会停止
我发现串口的 TX RX fifo 是通过同一个 MUTEX 管理的,不知道这个MUTEX 会不会影响同一个串口的 收和发行为。

下面是代码 ┭┮﹏┭┮

#include #include #include #include //#define DEBUG#define RX_BOARD//#define BLINK_ON_RECV#define WIFI_CHANNEL 1#define BAUD_RATE 600#define BUFFER_SIZE 250 // max of 250 bytes#define mSerial Serial// TX 44:17:93:F9:52:34// RX 44:17:93:F9:2E:C4#ifdef RX_BOARDconst uint8_t broadcastAddress[] = {0x44, 0x17, 0x93, 0xF9, 0x52, 0x34};#elseconst uint8_t broadcastAddress[] = {0x44, 0x17, 0x93, 0xF9, 0x2E, 0xC4};#endifconst uint32_t timeout_micros = (int)(1.0 / BAUD_RATE * 1E6);uint8_t buf_recv[BUFFER_SIZE];uint8_t buf_send[BUFFER_SIZE];uint8_t buf_size = 0;void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len){#ifdef BLINK_ON_RECV  digitalWrite(LED_BUILTIN, HIGH);#endif  //memcpy(&buf_recv, incomingData, len);  mSerial.write(incomingData, len);#ifdef BLINK_ON_RECV  digitalWrite(LED_BUILTIN, LOW);#endif#ifdef DEBUG  mSerial.print("n Bytes received: ");  mSerial.println(len);#endif}void setup(){  //设置led 指示灯  pinMode(LED_BUILTIN, OUTPUT);  //设置波特率  mSerial.begin(BAUD_RATE);  mSerial.setRxBufferSize(50000);  Serial.begin(BAUD_RATE);  pinMode(16, INPUT_PULLUP);  pinMode(17, OUTPUT);  WiFi.mode(WIFI_STA);#ifdef DEBUG  mSerial.println();  mSerial.println(WiFi.macAddress());#endif  // ESP_NOW 初始化  if (esp_wifi_set_channel(WIFI_CHANNEL, WIFI_SECOND_CHAN_NONE) != ESP_OK)  {    mSerial.println("Error changing wifi channel");    return;  }  if (esp_now_init() != ESP_OK)  {    mSerial.println("Error initializing ESP_NOW");    return;  }  //添加peer  esp_now_peer_info_t peerInfo;  memcpy(peerInfo.peer_addr, broadcastAddress, 6);  peerInfo.channel = WIFI_CHANNEL;  peerInfo.encrypt = false;  if (esp_now_add_peer(&peerInfo) != ESP_OK)  {    mSerial.println("failed to add peer");  }  esp_now_register_recv_cb(OnDataRecv);}uint64_t start;void loop(){  // put your main code here, to run repeatedly:  // read up to BUFFER_SIZE from mSerial port  if (mSerial.available())  {    start = micros();    while (mSerial.available() && buf_size < BUFFER_SIZE)    {      buf_send[buf_size] = mSerial.read();      buf_size++;      if (micros() - start > timeout_micros)        goto WRITE;    }  }  // send buffer contents when full or timeout has elapsed  if (buf_size > 0)  {  WRITE:#ifdef BLINK_ON_SEND    digitalWrite(LED_BUILTIN, HIGH);#endif    // #ifdef RX_BOARD    //     Serial.write(buf_send, buf_size);    // #endif    esp_now_send(broadcastAddress, (uint8_t *)&buf_send, buf_size);    buf_size = 0;#ifdef DEBUG    if (result == ESP_OK)    {      mSerial.println("Sent!");    }    else    {      mSerial.println("Send error");    }#endif#ifdef BLINK_ON_SEND    digitalWrite(LED_BUILTIN, LOW);#endif  }}

回帖(1)

胡秋阳

2024-6-17 17:50:26


为了解决这个问题,您可以尝试以下方法:

1. 优化代码结构:尽量避免在ESP-NOW的onReceive回调函数中直接操作串口TX FIFO,而是将接收到的数据存储在一个单独的缓冲区中,然后在主循环(loop)中处理这些数据。这样可以减少MUTEX竞争的可能性。

2. 使用中断:考虑使用串口的中断功能来处理接收到的数据。当串口接收到数据时,中断服务程序(ISR)会被触发,您可以在ISR中将数据存储到一个缓冲区,然后在主循环中处理这些数据。这样可以避免MUTEX竞争,提高性能。

3. 调整波特率:虽然您已经将串口波特率设置得较低,但仍然可以尝试进一步降低波特率,以减少数据传输过程中的冲突。

4. 使用其他通信协议:如果ESP-NOW的性能仍然不能满足您的需求,您可以考虑使用其他通信协议,如蓝牙、LoRa等,以实现更高效的数据传输。

5. 硬件优化:如果可能的话,您还可以考虑使用具有更多串口或更高通信性能的硬件平台,以提高整体性能。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分