我目前正在尝试使用 ESP32 Rev3 读取现有的 canbus(汽车)。 我使用默认库让它与外部 MCP2515 屏蔽一起正常工作。
但是当我连接收发器并尝试使用 ESP32 内置的内部 TWAI 控制器时,我开始遇到麻烦。当接收周期至少 > 5 毫秒的消息时,它工作正常,但一旦周期低于 5 毫秒,它就会迅速填满 RX 缓冲区,一旦填满,它就会开始丢弃数据包。当我将 RX 缓冲区设置为更高的值时,这只会延长出现第一个错误的时间。看起来收发器工作正常,但 twai_receive() 函数无法跟上。有谁知道我在这里能做什么。
对于接收,我使用以下内容,这对于 ESP32 Wroom Rev3 来说效果很好。 https://github.com/halfroad/TWAIMessager
之前,我使用此文档直接访问 API,但这具有相同的行为: https://docs.espressif.com/projects/esp-idf/en/release-v4.4/esp32/api-reference/peripherals/twai.html#examples
如果内部限制为每个消息周期 >5 毫秒,则 CAN 控制器几乎毫无用处,因为在大多数现代汽车 CANBUS 中,每条消息的周期低至 0.4 毫秒。
为了验证我没有遗漏任何东西,我设置了两个 ESP32 并从 A 发送到 B。
接收部分的代码/设置是这样的:
#include "driver/twai.h"
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(GPIO_NUM_33, GPIO_NUM_32, TWAI_MODE_LISTEN_ONLY);
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
//Install TWAI driver
if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
Serial.println("Driver installed\n");
} else {
Serial.println("Failed to install driver\n");
return;
}
//Start TWAI driver
if (twai_start() == ESP_OK) {
Serial.println("Driver started\n");
} else {
Serial.println("Failed to start driver\n");
return;
}
loop()函数中传入消息的处理是这样的:
twai_message_t message;
void loop() {
while (twai_receive(&message, 0) == ESP_OK) {
// process message (which will only arrive every 5ms
Serial.printf(msgString, "STD CAN-ID: 0x%.3lX DLC: %1d Data:", message.identifier, message.data_length_code);
for(byte i = 0; i<message.data_length_code; i++){
Serial.printf(" 0x%.2X", message.data[i]);
}
Serial.println();
}
return;
}
在左侧,您可以看到本消息与上一条消息之间的时间间隔。 右侧的绿色 ID 确认该消息是上一条消息(数据)的有效后续消息。
我一想去<5ms, 3ms in this example it looks like this:
这里,一旦 RX 缓冲区填满,它就开始丢弃消息。
在最后一张图片中,您将看到使用 ESP32 和外部 MPC2515 控制器的 2013 VAG 汽车的传动系统 CANBUS 日志。
每个包之间的周期在 0.41 到 9 毫秒之间,并且没有丢失任何一个包。
我希望这里有人能真正帮助解决这个问题,或者以前经历过同样的行为。
快速 TWAI 响应的关键是 a) 在设置驱动程序时使用配置和特殊标志将 ISR 放入 IRAM,b) 运行一个高优先级任务,该任务会阻塞
twai_receive
并仅将读取的帧放入具有足够槽位的队列(例如,如果您使用 ISOTP,则为 587)。