CAN (Controller Area Network) — шина контроллеров — широко используется в автомобильной промышленности и других промышленных приложениях. В автомобилях блоки управления (ЭБУ) соединяются по шине CAN, которая выступает в качестве управляющей нервной системы. Блоки управления двигателем (ECU) могут включать в себя блок управления двигателем, блок управления подушками безопасности, систему Audi, блок управления положением дверей, тормозную систему, датчики и другие. Каждой функции может быть назначен отдельный узел (NODE) ​​или блок управления двигателем (ECU). В современном автомобиле может быть до 100 электронных блоков управления. Технология CAN позволяет блокам управления обмениваться данными друг с другом без сложной специализированной проводки между ними.

Любой блок управления двигателем (ЭБУ) может взаимодействовать со всей системой, не вызывая перегрузки управляющего компьютера.

Изображение 2

CAN — это многомастерская конфигурация. Любой узел может быть мастером. CAN работает по принципу обмена сообщениями, и для связи с узлом не используется адрес ведомого устройства. Каждый узел получает сообщение, а соответствующие данные обрабатываются узлом-получателем. Это как система оповещения в аэропорту. Сообщение услышат только заинтересованные пассажиры. Для балансировки шины CAN и снижения уровня шума в качестве оконечного резистора используется резистор 120 Ом. Это обязательно для конечных узлов. Узлам, добавленным между ними, этот резистор не требуется.

В этом проекте мы используем плату CAN2515. На этой плате установлены 2 микросхемы. Одна из них — контроллер CAN MCP2515, который взаимодействует с Arduino или любым другим микроконтроллером по протоколу SPI. MCP2515 выдает однополярный цифровой сигнал (высокий, низкий).

can2515_se

TX-CAN и RX-CAN работают на цифровом уровне и подключены к другой микросхеме — приемопередатчику.

Здесь используется трансивер TJ1050. Microchip MCP 2551 также является трансивером, обычно используемым с микроконтроллерами, имеющими встроенный CAN-контроллер. Например, модуль ESP32 имеет встроенный контроллер, но ему нужен трансивер, такой как MCP2551 или TJ1050. Не путайте эти цифры. 2515 — это контроллер, 2551 — это приемопередатчик. TJ1050 принимает цифровой сигнал от CAN2515 и преобразует его в дифференциальный сигнал, допустимый на шине CAN.

Обратите внимание на связь между TJA1050 и CAN 2515. TX-CAN к TXD, RX-CAN к RXD (не наоборот). В используемом нами модуле обе микросхемы уже установлены, поэтому нам не нужно беспокоиться об этом соединении.

Изображение 4

Формат CAN-сообщения представлен ниже:

Изображение 1

Идентификатор CAN может быть 11-битным или 29-битным. 11-битный адресный модуль может адресовать 2048 узлов (2 степени 11) в шестнадцатеричном формате от 0x000 до 0x7FF. Расширенная версия с 29-битной архитектурой может вмещать до 536 миллионов символов. Допустимая длина DAT-файла составляет максимум 8 байт или 64 бита.

Чтобы узнать больше о CAN-сообщениях, посетите эту страницу.

На следующем рисунке показан дифференциальный уровень сигнала CAN.

Изображение5

Когда на шине отсутствует информация, напряжение на каналах CAN-H и CAN-L составляет половину напряжения питания (в данном случае 2,5 вольта в 5-вольтовой системе).

Это рецессивное состояние или бит 1.

Когда напряжение на CAN-H достигает 5 В, а на CAN-L — 0 В, это состояние ДОМИНАНТНОЕ или БИТ 0.

Для начала работы над проектом подключите потенциометр (центральный контакт) к выводу A0 платы Arduino.

Один конец потенциометра подключен к 5 В, а другой — к земле.

На схеме показаны соединения платы CAN, а также SPI-соединения между Arduino и платой CAN.

Изображение22

Прежде чем начать, нам нужна хорошая библиотека для работы с CAN.

В SEEED Studio есть библиотека, которая отлично работает с их Shield.

Также модифицированная версия доступна на сайте Cryjfowler.

Я предпочитаю использовать один из вариантов от AUTOWP.

arduino-mcp2515

Этот метод использует структуру (STRUCT) для отправки сообщений. Он очень прост и удобен в использовании.

Изображение13

Обратите внимание, что библиотека Seed Studio и библиотека coryjfowler имеют одинаковое имя заголовочного файла mcp_can.h. Если вы установите обе эти библиотеки, возникнет конфликт при объявлении объектов, что приведет к ошибкам. Используйте только одну из них.

В этой демонстрации мы используем библиотеку arduino-mcp2515. Скачайте её в виде ZIP-файла.

Библиотека CAN

https://github.com/autowp/arduino-mcp2515

В Arduino IDE: Скетч -> Включить библиотеку -> Добавить ZIP-библиотеку

Перейдите к месту расположения загруженной библиотеки. Выберите её для установки.

Файл будет скопирован в папку Documents/Arduino/Libraries.

На стороне приемника мы используем ЖК-дисплей с интерфейсом I2C.

Библиотеку для этого можно скачать и установить по следующей ссылке:

Библиотека i2c:

https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library

Код для Arduino, используемый в этом проекте, можно скачать по ссылке:

http://www.alselectro.com/files/CAN_2515.zip

На следующем рисунке показаны соединения со стороны передатчика.

Подключение потенциометра к выводу A0 Arduino, платы CAN к интерфейсу SPI.

IMG_20200428_113532

Код для передающей стороны выглядит следующим образом:

tx

Здесь мы приводим заголовочный файл mcp2515.h.

Мы создаём неинициализированную переменную структуры can_frame с именем canMsg.

can_frame — это имя типа структуры.

canMsg — это имя переменной.

Присваивание значений членам структуры осуществляется с помощью точечного оператора.

Как видно из документации библиотеки, в ней три элемента: can_id, can_dlc и data[].

Изображение 3

Объект mcp2515 инициализируется из класса MCP2515 путем передачи в качестве аргумента вывода CS (контакт выбора микросхемы 10).

MCP2515 mcp2515(10);

В разделе setup мы вызываем функции объекта mcp2515.

Сначала вызывается функция reset().

Затем используйте функцию setBitrate(), чтобы установить скорость CAN на уровне 500 Кбит/с и частоту 8 МГц.

Функция setNormalMode() устанавливает режим работы модуля в обычном режиме.

mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ);

  mcp2515.setNormalMode();

С помощью оператора точки элементы добавляются в структуру.

can_id — это шестнадцатеричный идентификатор, предоставленный пользователем. Вы можете указать свой собственный идентификатор в шестнадцатеричном формате.

can_dlc — это длина данных. Максимально допустимая длина — 8 байт. Здесь мы указываем длину данных всего в один байт.

В функции loop() значение аналогового потенциометра сопоставляется со значением в диапазоне от 0 до 255.

и данные, передаваемые по шине CAN с помощью функции sendMessage() модуля mcp2515.

Ниже приведено изображение подключения со стороны приемника.

ЖК-дисплей с интерфейсом I2C имеет два контакта, помимо Vcc и Gnd.

SDA подключен к A4, SCL подключен к A5.

IMG_20200428_113556

Плата CAN передатчика подключена к плате CAN приемника.

CAN_H к CAN_H

CAN_L в CAN_L

Обычно используется витая пара проводов с экраном. Экран подключается к земле (GND).

Максимальная допустимая длина составляет 40 метров.

Ниже приведён код со стороны приёмника:

rx

Здесь мы добавили разъем I2C для ЖК-дисплея.

При создании объекта LCD мы передаем I2C-адрес и размер LCD (16 x 2).

Чтобы узнать I2C-адрес, вы можете использовать  сканер I2C, доступный здесь.

В пустом цикле

Для проверки входящего сообщения мы используем функцию readMessage() модуля mcp2515.

Затем мы сравниваем идентификаторы и извлекаем сообщение для отображения на ЖК-дисплее.

IMG_20200428_123314

В проект можно добавить больше датчиков.

В точке A3 можно установить датчик температуры LM35, а в точке D6 — выключатель включения/выключения двери.

SENSORS_CAN

Код для Arduino, используемый в этом проекте, можно скачать по ссылке:

http://www.alselectro.com/files/CAN_2515.zip

IMG_20200428_151048