MCP2515 CAN bus модуль с поддержкой SPI протокола + TJA1050 приемник HW-184.
Совместим с микроконтроллером Arduino.
Характеристики:
Поддержка V2.0B спецификации, скорость передачи данных 1 МБ/с.
Поле данных - от 0 до 8 байт.
Питание DC 5 В, SPI интерфейс управления протоколом
120 ohm резисторы нагрузки, соответствуют сопротивлению шины, обеспечивают компенсацию емкости привода, и передачу данных на большие расстояния от источника сигнала.
Размеры модуля 4.4x2,8 см
Рабочий ток 5ма и 1μA ток в режиме ожидания
Рабочая температура - (промышленный класс) -40°C...+ 85°C
CAN (Controller Area Network) был разработан компанией BOSCH и выпущено в середине 80-х годов. Сначала применялась в автобусах и грузовиках, но сейчас можно встретить в автомобилях, кораблях, промышленности, тракторов и так далее. Кто хочет почитать больше информации о CAN протоколу, можно ознакомится с этой статьей.

Так как контроллеры Arduino не содержит внутренний CAN, поэтому используется внешний контроллер MCP2515 (самая большая микросхема на модуле), для работы которого необходим кварц на 8 МГц и небольшая обвязка. Микросхема MCP2515 способна получать и передавать данные с CAN шины на микроконтроллер, через SPI наоборот. Так же, на модуле установлен трансивер TJA1050, которая физически соединяет MCP2515 с CAN шиной.
Для заметки, некоторые контроллеры, такие как ESP32, уже содержат внутреннюю периферию CAN, но им все равно нужен трансивер TJA1050 или MCP2551.

Модуль MCP2515 содержит три разъема, самый большой, это вывода интерфейса SPI, который состоит из 7 контактов, шагом 2.54 мм. Второй и третий, дублируются, и являются выводами шины CAN
Назначение контактов SPI:
► VCC и GND — выводы питания 5В;
► CS — вывод выбора ведомого устройства;
► SO — вывод SPI;
► SI — вывод SPI;
► SCL — тактовый вывод SPI;
► INT — вывод прерывания MCP2515.
Назначение контактов CAN:
► H — вывод CAN;
► L — вывод CAN.
Подключение MCP2515 к Arduino UNO
Необходимые детали:
► Arduino UNO R3 x 2 шт;
► Модуль MCP2515 x 2 шт:
► Провод DuPont, 2,54 мм, 20 см, F-M (Female — Male) x 1 шт:
► Кабель USB 2.0 A-B x 2 шт;
► Светодиод 5 мм x 1 шт;
► Тактовая кнопка х 1 шт;
► Резистор 330.
Описание:
В примере покажу, как реализовать связь между двумя контроллерами Arduino UNO, через CAN шину используя модуль MCP2515.
Подключение:
Сначала подключаем модуль MCP2515 и Arduino UNO, для этого вывода INT, SCK, SI, SO, CS, GND, VCC с MCP2515 подключаем к выводам 2, 13, 11, 12, 10, GND, 5B, аналогично для второй сборки Arduino UNO и MCP2515. Далее соединяем два модуля MCP2515, для этого вывод H и L, соединяем к H и L. Светодиод и кнопку подключаем по схеме показанной ниже.

Установка библиотек:
Для работы программы, необходимо дополнительно установить библиотеку «mcp2515«, скачать ее можно в конце статьи.
Программа №1 (передатчик):
Первый скетч, необходимо загрузить на Arduino UNO с кнопкой, она будет передавать данные ко второй Arduino UNO.
#include <mcp2515.h> // Подключаем библиотеку mcp2515
#define button 8 // Указываем к какому выводу подключена кнопка
struct can_frame canMsg;
MCP2515 mcp2515(10);
void setup()
{
pinMode(button, INPUT); // Устанавливаем вывод, как вход
digitalWrite(button, HIGH); // Включаем подтягивающий резистор
Serial.begin(115200); // Открываем последовательную связь
mcp2515.reset(); // Перегружаем mcp2515
mcp2515.setBitrate(CAN_125KBPS); // Устанавливается скорость на 125 кбит\с
mcp2515.setNormalMode();
canMsg.can_id = 0x0F6;
canMsg.can_dlc = 1;
}
void loop()
{
int buton_1 = digitalRead(button); // Считывает значение с кнопки
// Если HIGH выполняем функцию
if (buton_1 == HIGH)
{ canMsg.data[0] = 0x20;
mcp2515.sendMessage(&canMsg);
}
// Если LOW выполняем функцию
else if (buton_1 == LOW)
{
canMsg.data[0] = 0x10;
mcp2515.sendMessage(&canMsg);
}
delay(1000);
}
Программа №2 (приемник): Вторую программу необходимо загрузить во вторую Arduino UNO, к которой подключен светодиод.
#include <mcp2515.h> // Подключаем библиотеку mcp2515
#define led 8 // Указываем какому выводу подключен светодиод
struct can_frame canMsg;
MCP2515 mcp2515(10);
void setup()
{
Serial.begin(115200);// Открываем последовательную связь
pinMode(led, OUTPUT);// Устанавливаем вывод, как выход
digitalWrite(led, HIGH);; // Включаем подтягивающий резистор
mcp2515.reset(); // Перегружаем mсp2515
mcp2515.setBitrate(CAN_125KBPS);
mcp2515.setNormalMode();
}
void loop() {
if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK)
{
if(canMsg.can_id == 0x0F6)
{
int x = canMsg.data[0];
Serial.println(x);
if (x == 0x10){digitalWrite(led, HIGH);Serial.println("ON");}
if (x == 0x20){digitalWrite(led, LOW);Serial.println("OFF");}
delay(200);
}
}
}