Работа с CAN и CAN FD на Arduino
В этом разделе рассматриваются примеры программ для передачи данных по CAN и CAN FD
Last updated
В этом разделе рассматриваются примеры программ для передачи данных по CAN и CAN FD
Last updated
Напишем на ардуино программу, которая постоянно шлет в CAN пакет, состоящий из 4 байт, а также при получении сообщения извне (будем считать оно тоже состоит не более, чем из 4 байт) отображает его в Serial порт.
Сам файл с программой:
Начнем с классического протокола CAN.
Подключим необходимый файл к нашему скетчу и создадим переменную data - отправляемый пакет.
Класс CanFD - это управляющая структура. Он содержит следующие методы:
init() - метод, инициализирующий CAN
write_default_params_classic() - метод, который запишет параметры по умолчанию для CAN FD (настроены два битрейта 500000 и 4000000 если вы будете использовать raspberry для чтения/записи в can fd, то при запуске интерфейса используйте команду sudo ip link set can0 up txqueuelen 65535 type can bitrate
500000
dbitrate
4000000
fd on.
Подробно о том как работать с CAN на RPI написано в разделе VB Can FD Raspberry HAT)
write_default_params() - метод, который запишет параметры по умолчанию для обычного CAN( здесь по умолчанию настроен битрейт на 1000000. Запуск интерфейса на RPI: sudo ip link set can0 up txqueuelen 65535 type can bitrate 1000000
)
О том, как поменять тайминги и на что они влияют, здесь сказано не будет. Для целей обучения и простого использования мы предлагаем настройки по умолчанию. Если хотите углубиться - добро пожаловать в раздел Коммуникации-FDCAN
apply_config() - метод, который применит записанные ранее методы для нашего экземпляра класса
default_start() - метод, который запускает FD CAN на модуле, он обязателен.
get_hfdcan() - сохраняет всю конфигурацию и возвращает указатель на структуру FDCAN_HandleTypeDef
В setup() вызывем функцию SystemClock_Config() - она обязательна для настройки тактирования, методы класса CanFD - init() , инициализирующую can, методы для записи и подтверждения настроек, функцию, запускающую CAN FD и get_hfdcan(), возвращающую инициализированнную управляющую can-ом структуру типа FDCAN_HandleTypeDef. Также укажем в хидере нашего сообщения его ID, размер и тип ID сообщения - он может быть расширенным, а может стандартным.
Если тип ID расширенный, то ID 0x64 будет выглядеть: 00000064, если стандартный: 064. Мы советуем использовать расширенный.
В основном цикле loop() ставим условие: если в очереди на отправку сообщения есть место, тогда отправляем сообщение. Если пакет отправлен и все хорошо будем мигать светодиодиком.
Чтение пакетов из can происходит следующим образом: пока в очереди получаемых сообщений есть хотя бы одно, создаем хидер этого сообщения и массив, где будет лежать содержимое посылки. Если сообщение получено, выведем в Serial порт его ID, и само сообщение. Сейчас, для простоты, выведем первые 4 байта массива, считая, что больше отправлено не будет.
В конце цикла добавили задержку в 100 милисекунд.
Загрузите программу на плату. Проверить действительно ли все сообщения отправляются в can можно на Raspberry с помощью утилиты candump, а чтобы отправить сообщение воспользуйтесь утилитой cansend. О том как работают утилиты было расказано в главе Работа с CAN на Raspberry.
Также вы можете эту программу разделить на две части - отправку и чтение сообщения и загрузить на два модуля (для приемника закомментируйте часть с отправкой сообщения, для передатчика - часть с приемом), а потом проверить через сериал порт, что приемник действительно получает те сообщения, что отправляет ему второй модуль.
В целом код будет отличаться только настройками в setup() (названиями вызываемых функций):
Если у вас возникла ситуация, в которой одно устройство отправляет сообщения, а другое не принимает, почитайте как можно справиться с этой ошибкой здесь