Esp32 sn65hvd230:我无法让它实时读取

问题描述 投票:0回答:2

我正在开发一个基于ESP32处理器和Arduino框架的项目,该项目通过CANBUS协议与另一块板进行通信。

比特率为 125k,所以大概是“快”。

我正在使用 Sandeep Mistry 库或也称为 adafruit_CAN,它与 Texas Instruments SN65HVD230 CAN 收发器兼容。

我使用 freeRTOS 作为一种方法,该方法将接收每个套接字的帧,并将它们写入板。

然后库本身提供附加到 ISR 的回调来接收响应。

这就是我的问题开始的地方,如果我每秒发送一帧,一切都很棒,但是当我开始每 200 毫秒发送一次时,我可以看到(使用从电脑连接到总线的 CAN 分析器)帧正在到达,他们正在卡上接收并且正在应答,但我的收发器没有触发回调。

我尝试忘记回调并使用另一种 RTOS 方法进行读取,结果相同。

此方法正在迭代任务,如果向量包含 CAN_message_t 对象,则将其写入 CAN,这可以正常工作。

void vTaskCANBUSWriteLoop(void *p)
{
  Serial.print("Writer Task");
 
  for (;;)
  {
    if (!my_global_vector.empty() )
    {
      response_broker_t myObject = my_global_vector.front();
      my_global_vector.pop();

      
      writePlot(myObject);
     
    }
    vTaskDelay(200 / portTICK_PERIOD_MS);
  }
}

另一种方法是根据文档,如果程序不超过每秒发送一次,则效果很好,如果超过,程序将继续写入,但不会触发回调。 检查它是否与 id 匹配,在解析器中我看到这个 id 就是要输入的 id。

void canCallback(int packetSize)
{
  static uint32_t lastTime = 0;
  if (can_reader.packetId() == BOARD_ANSWER1 || can_reader.packetId() == BOARD_ANSWER2)
  {

    if (packetSize)
    {
      uint8_t buf[8];
      
      while (can_reader.available())
      {
         CAN.readBytes(buf, sizeof(buf));
      }
      uint8_tArrayToHexString2(buf, sizeof(buf), rapidResponse);
     
    }
  }
}

这是我用来转换为十六进制字符串的方法,它不相关,但可能会带来更多清晰度

void uint8_tArrayToHexString2(uint8_t *data, size_t len, char *output)
{
  static const char hexChars[] = "0123456789ABCDEF";
  for (size_t i = 0; i < len; ++i)
  {
    output[i * 3] = hexChars[(data[i] >> 4) & 0xF];
    output[i * 3 + 1] = hexChars[data[i] & 0xF];
    output[i * 3 + 2] = ' ';
  }
  output[len * 3 - 1] = '\0';
}
c can-bus freertos arduino-esp32
2个回答
1
投票

虽然 Adafruit 库很棒,但问题在于它的使用。当你在公交车上快速拍摄很多消息时,公交车最终会变得不稳定。

我用过ESP32的IDF CAN库,和它没什么关系,就像黑夜和白天一样。

我为 Arduino 框架留下了一个最小的实现,以防它对某人有帮助。

#include <Arduino.h>
#include "driver/gpio.h"
#include "driver/can.h"

TaskHandle_t can_receive_task_handle;

void can_receive_task(void *arg)
{
  can_message_t rx_msg;
  for(;;)
  {
    if (can_receive(&rx_msg, pdMS_TO_TICKS(100)) == ESP_OK)
    {
      printf("Received message: ID = 0x%08X, Data: ", rx_msg.identifier);
      for (int i = 0; i < rx_msg.data_length_code; i++)
      {
        printf("%02X ", rx_msg.data[i]);
      }
      printf("\n");
    }
  }
}

void setup()
{

  Serial.begin(115200);

  //? Configure GPIO pins for CAN must be 4/5 or 16/17
  gpio_install_isr_service(0);
  gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT);
  gpio_set_direction(GPIO_NUM_16, GPIO_MODE_INPUT);

  //! Configure CAN controller
  can_general_config_t can_config = {
      .mode = CAN_MODE_NORMAL,
      .tx_io = GPIO_NUM_17,
      .rx_io = GPIO_NUM_16,
      .clkout_io = GPIO_NUM_NC,
      .bus_off_io = GPIO_NUM_NC,
      .tx_queue_len = 5,
      .rx_queue_len = 5,
      .alerts_enabled = CAN_ALERT_NONE,
      .clkout_divider = 0};
  can_timing_config_t timing_config = CAN_TIMING_CONFIG_125KBITS();
  can_filter_config_t filter_config = CAN_FILTER_CONFIG_ACCEPT_ALL();

  if (can_driver_install(&can_config, &timing_config, &filter_config) == ESP_OK &&
      can_start() == ESP_OK)
  {
    Serial.println("CAN controller initialized successfully");
  }
  else
  {
    Serial.println("Error initializing CAN controller");
    return;
  }

  //! Create RTOS task for receiving CAN messages
  xTaskCreate(can_receive_task, "can_receive_task", 2048, NULL, 5, &can_receive_task_handle);
}

void loop()
{
 
}

特别感谢ESP32 Arduino论坛:使用官方CAN驱动


0
投票

我正在我的大学开发一个与此相关的学位项目!我想问你一些关于这方面的问题。我正在使用 esp32 wrover e,但我还没有看到任何使用此型号 esp32 的 CAN 控制器的示例,您认为它有效吗?我可以使用哪些引脚来使用 CAN 控制器?

© www.soinside.com 2019 - 2024. All rights reserved.