ESP32 arduino 串口同时收发的问题
Posted: Sun May 08, 2022 9:28 am
我用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 会不会影响同一个串口的 收和发行为。
下面是代码 ┭┮﹏┭┮
使用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 会不会影响同一个串口的 收和发行为。
下面是代码 ┭┮﹏┭┮
Code: Select all
#include <Arduino.h>
#include <WiFi.h>
#include <esp_now.h>
#include <esp_wifi.h>
//#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_BOARD
const uint8_t broadcastAddress[] = {0x44, 0x17, 0x93, 0xF9, 0x52, 0x34};
#else
const uint8_t broadcastAddress[] = {0x44, 0x17, 0x93, 0xF9, 0x2E, 0xC4};
#endif
const 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
}
}