ESP32-Arduino-CAN
ESP32-Arduino-CAN copied to clipboard
This library is outdated!
You shouldn't use this library as it was written in the early days when the ESP-IDF was different. Since then the Arduino core for ESP32 has a very good AND reliable interface. Even on a 125 kbps bus this library isn't reliable and you are going on a wild goose chase with mysterious errors on your CAN bus.
You need only a few lines of code to have CAN working. Please read the official ESP32 documentation here: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html#examples
If that is TL;DR, then here is the gist of it:
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#include "driver/can.h"
SemaphoreHandle_t canSemaphore;
void InitCAN(uint8_t rxPin, uint8_t txPin)
{
canSemaphore = xSemaphoreCreateMutex();
can_general_config_t g_config = {.mode = CAN_MODE_NORMAL,
.tx_io = (gpio_num_t)txPin, .rx_io = (gpio_num_t)rxPin,
.clkout_io = CAN_IO_UNUSED, .bus_off_io = CAN_IO_UNUSED,
.tx_queue_len = 10, .rx_queue_len = 10,
.alerts_enabled = CAN_ALERT_NONE, .clkout_divider = 0,
.intr_flags = ESP_INTR_FLAG_LEVEL1};
can_timing_config_t t_config = CAN_TIMING_CONFIG_125KBITS();
can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL();
esp_err_t result = can_driver_install(&g_config, &t_config, &f_config);
}
uint8_t SendMessage(uint16_t canId, uint8_t ext, uint8_t sizeOfByteArray, uint8_t *byteArray)
{
can_message_t message;
message.identifier = canId;
message.flags = CAN_MSG_FLAG_NONE;
message.data_length_code = sizeOfByteArray;
for (int i = 0; i < sizeOfByteArray; i++) {
message.data[i] = byteArray[i];
}
uint8_t result = 0;
if (xSemaphoreTake(canSemaphore, portMAX_DELAY) == pdTRUE)
{
if (can_transmit(&message, pdMS_TO_TICKS(10)) == ESP_OK) {
result = 1;
} else {
result = 0;
}
xSemaphoreGive(canSemaphore);
}
return result;
}
void ReadMessage(uint16_t *canId, uint8_t *len, uint8_t *buf)
{
can_message_t message;
if (can_receive(&message, pdMS_TO_TICKS(10)) == ESP_OK) {
if (message.flags == CAN_MSG_FLAG_NONE || message.flags == CAN_MSG_FLAG_SS)
{
*canId = message.identifier;
*len = message.data_length_code;
for (int i = 0; i < message.data_length_code; i++)
{
buf[i] = message.data[i];
}
}
} else {
return;
}
}
Usage:
InitCan(4,5);
uint16_t canId = 0;
uint8_t canLength = 0;
uint8_t canMessage[8] = {0};
ReadMessage(&canId, &canLength, canMessage);
if(canId > 0){
//we have something in the canMessage array
}
//send the content of the canMessage array to the CAN bus
SendMessage(canId, 0, canLength, canMessage)