
Интернет-магазин «Неглупый Дом»
В другом проекте на сайте два одинаковых модуля MCP2515 обмениваются данными по CAN. Здесь — важная особенность самого стандарта CAN на практике: на одной физической шине CAN-H/CAN-L могут работать узлы на совершенно РАЗНЫХ чипах с разным интерфейсом подключения к Arduino — в этом проекте один узел подключён через SPI (MCP2515), а другой — через I2C (модуль на TJA1050 с управлением по I2C).
CAN — это стандарт именно физического и канального уровня: любой корректно согласованный по электрическим параметрам узел может участвовать в одной шине независимо от того, через какой внутренний интерфейс (SPI, I2C или что-то ещё) конкретный Arduino-модуль подключён к своему CAN-контроллеру — сама шина CAN-H/CAN-L не "знает" и не заботится о том, как именно хост-контроллер каждого узла получает и отправляет данные внутри себя. MCP2515 — отдельный CAN-контроллер, общающийся с Arduino по SPI (как и в проекте с двумя одинаковыми узлами). Модуль на TJA1050 с управлением по I2C устроен иначе — I2C-интерфейс к CAN-контроллеру менее стандартизирован между производителями, чем хорошо документированный MCP2515, поэтому точные имена функций его библиотеки стоит уточнять по документации конкретно вашего экземпляра платы.
Логика кадра (идентификатор, приоритет при коллизии, проверка целостности) одинакова для обоих узлов — именно поэтому они и могут обмениваться данными, несмотря на разные внутренние интерфейсы подключения к своим Arduino.
Так как реализации данного модуля бывают разные, если у вас на плате нет тех контактов, которые указаны ниже — сориентируйтесь по названиям контактов на своей плате.
// ВНИМАНИЕ: рекомендую отладить код через монитор порта, так как я языковая
// модель, а не специализированный кодер, и могу что-то упустить. Основу
// и идею я накидал, но проверьте под свою схему.
#include <SPI.h>
#include <mcp_can.h>
MCP_CAN CAN(10);
void setup() {
Serial.begin(9600);
while (CAN.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) != CAN_OK) { // проверьте частоту кварца на своей плате
delay(500);
}
CAN.setMode(MCP_NORMAL);
}
void loop() {
byte data[1] = {42};
CAN.sendMsgBuf(0x100, 0, 1, data);
Serial.println("Отправлено: 42");
delay(1000);
}
// ВНИМАНИЕ: точные имена функций библиотеки для вашего конкретного модуля
// TJA1050-I2C могут отличаться — это менее стандартизированный интерфейс,
// чем MCP2515. Ниже показана ОБЩАЯ логика приёма, а не гарантированно
// точный API — сверьтесь с документацией/примерами именно вашей платы.
#include <Wire.h>
// #include <ваша_библиотека_для_TJA1050_I2C.h> — замените на реальную библиотеку вашего модуля
void setup() {
Serial.begin(9600);
Wire.begin();
// инициализация CAN-контроллера модуля по документации конкретной платы
}
void loop() {
// псевдокод общей логики — замените на реальные вызовы вашей библиотеки:
// if (canMessageAvailable()) {
// byte receivedId = getCanId();
// byte receivedData[8];
// getCanData(receivedData);
// Serial.println(receivedData[0]); // ожидаем получить 42 от узла на MCP2515
// }
delay(100);
}
Библиотека mcp_can для MCP2515 — реальная, хорошо документированная и уверенно используется. Для TJA1050-I2C модуля используйте библиотеку, идущую в комплекте именно с вашей платой, или уточните у продавца — единого стандарта для таких I2C-CAN мостов нет.
Ещё модули для Arduino: Электронные модули.
🎁 Купить весь комплект со скидкой 10%
Все 2 товара сразу в корзину: 223 ₽ 201 ₽ (экономия 22 ₽)
Скидка применяется автоматически при оформлении заказа, если в корзине именно этот комплект.
Остались вопросы? Проконсультируйтесь с ИИ-инженером — он уже в курсе темы статьи и сразу ответит, ничего вводить не нужно.