🛒
0 товаров
0 руб.

Интернет-магазин «Неглупый Дом»


🚌 Проект: обмен данными между двумя Arduino по шине CAN

Два модуля MCP2515

Два модуля MCP2515, соединённые всего двумя проводами CAN-H/CAN-L, передают короткие кадры данных между платами — та же помехоустойчивая шина, что используется в бортовых сетях автомобилей.

Как это работает

CAN — дифференциальная шина: данные передаются не абсолютным уровнем напряжения на одном проводе, а разницей напряжений между CAN-H и CAN-L, что делает её устойчивой к электромагнитным помехам — поэтому её и выбрали для автомобилей, где рядом работают моторы и системы зажигания. MCP2515 — это отдельный контроллер CAN-протокола, который берёт на себя формирование кадров, арбитраж шины и проверку целостности, а Arduino общается с ним через обычный SPI (как с SD-картой или RFID-модулем).

Каждый кадр CAN имеет идентификатор (в примере `0x100`) — в реальных сетях он используется не просто как "адрес", а как приоритет: если два узла пытаются передать одновременно, тот, у кого численно меньший идентификатор, автоматически получает приоритет без коллизии (это встроено в сам протокол на уровне физического уровня, а не требует отдельной логики в коде).

Пошаговая сборка

Так как реализации данного модуля бывают разные, если у вас на плате нет тех контактов, что указаны ниже — сориентируйтесь по названиям контактов на своей плате.

  1. MCP2515 (SPI): CS → D10, SCK → D13, MOSI → D11, MISO → D12, VCC → 5V, GND → GND (на обеих платах).
  2. CAN-H и CAN-L соединяют оба модуля напрямую двумя отдельными проводами, не перепутав полярность.
  3. Резистор-терминатор 120 Ом нужен на каждом конце линии — если на обоих модулях уже есть встроенный терминатор, включённый перемычкой, ставить третий резистор не нужно.
  4. Важно: параметр `MCP_8MHZ` в `CAN.begin()` должен совпадать с реальной частотой кварца на конкретном модуле — на части китайских плат стоит кварц 16 МГц, тогда нужно указывать `MCP_16MHZ`.

Скетч (плата-отправитель)

// ВНИМАНИЕ: рекомендую отладить код через монитор порта, я языковая
// модель, а не специализированный кодер, могу что-то упустить.

#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) {
    Serial.println("Ошибка инициализации MCP2515, повтор...");
    delay(500);
  }
  CAN.setMode(MCP_NORMAL);
  Serial.println("CAN готов к отправке");
}

void loop() {
  byte data[1] = {42};
  CAN.sendMsgBuf(0x100, 0, 1, data);
  Serial.println("Отправлено: 42");
  delay(1000);
}

На второй плате тот же модуль запускается в режиме приёма: `CAN.readMsgBuf(&len, buf)` внутри `if (CAN.checkReceive() == CAN_MSGAVAIL)` — принятое значение `buf[0]` будет равно отправленным 42.

Частые проблемы

Как улучшить проект

Товары по теме

Ещё модули для Arduino: Электронные модули.

← 📝 логгер температуры в энергонезависимую пам…🔗 обмен данными между Arduino на большом рас… →

Остались вопросы? Проконсультируйтесь с ИИ-инженером — он уже в курсе темы статьи и сразу ответит, ничего вводить не нужно.

Корзина


Поиск



Пример: понижающий или DC-DC или mini360 или aw-023 или арт. OZ/WB/YA