Arduino UNO R4 Minima — шина CAN

В этом руководстве вы узнаете, как использовать CAN-контроллер на плате Arduino UNO R4 Minima. CAN-контроллер встроен в микроконтроллер UNO R4 Minima (RA4M1). CAN — это последовательный протокол, который в основном используется в автомобильной промышленности.

Важно

Обратите внимание, что для работы CAN-контроллера требуется внешний трансивер. Инструкции и примеры оборудования приведены в этом руководстве.

Цели

Цели данного руководства:

  • Получить обзор встроенной библиотеки CAN

  • Научиться подключать плату к модулю CAN-трансивера

  • Отправить CAN-сообщение между двумя платами Arduino

Необходимые аппаратные и программные средства

* В этом руководстве мы используем модуль SN65HVD230 на плате-адаптере.

Контроллерная сеть (CAN)

Шина CAN использует два провода: CAN high и CAN low. На Arduino UNO R4 Minima эти выводы:

  • D5/CANRX0 (приём)

  • D4/CANTX0 (передача)

Однако для связи с другими CAN-устройствами вам потребуется модуль трансивера. В этом руководстве мы будем использовать модуль SN65HVD230. Для его подключения вы можете воспользоваться схемой, приведённой в разделе ниже.

В данном руководстве мы будем использовать простой пример, который отправляет CAN-сообщение между двумя устройствами UNO R4 Minima. При желании вы также можете подключить существующее CAN-устройство к UNO R4 Minima.

Схема подключения

Для подключения CAN-трансивера следуйте таблице и схеме ниже:

UNO R4 Minima

CAN-трансивер

D5 (CANRX0)

CANRX

D4 (CANTX0)

CANTX

3.3 V

VCC

GND

GND

Затем между CAN-трансиверами подключите следующее:

CAN-трансивер 1

CAN-трансивер 2

CANH (HIGH)

CANH (HIGH)

CANL (LOW)

CANL (LOW)

Примеры кода

Следующие примеры кода необходимо загрузить на каждую из плат UNO R4 Minima — одна будет отправлять сообщение, другая будет его принимать. Эти примеры доступны в пакете плат UNO R4, и с помощью Arduino IDE вы можете получить к ним доступ, перейдя в File > Examples > Arduino_CAN > CANWrite/CANRead.

Библиотека встроена в пакет плат, поэтому нет необходимости устанавливать её отдельно, если у вас уже установлен пакет плат.

Для инициализации библиотеки используйте CAN.begin(CanBitRate::BR_250k), где указывается битовая скорость CAN. Выберите одну из:

  • BR_125k (125000)

  • BR_250k (250000)

  • BR_500k (500000)

  • BR_1000k (1000000)

CAN Write (Отправка)

Для отправки CAN-сообщения вы можете создать объект CanMsg, который должен содержать CAN_ID, размер и данные сообщения. Ниже приведён пример создания такого объекта.

uint8_t const msg_data[] = {0xCA,0xFE,0,0,0,0,0,0};
memcpy((void *)(msg_data + 4), &msg_cnt, sizeof(msg_cnt));
CanMsg msg(CAN_ID, sizeof(msg_data), msg_data);

После формирования CAN-сообщения мы можем отправить его с помощью метода CAN.write(). Следующий пример создаёт CAN-сообщение, которое увеличивается при каждом выполнении void loop().

Исходный код на Github

/*
  CANWrite

  Write and send CAN Bus messages

  See the full documentation here:
  https://docs.arduino.cc/tutorials/uno-r4-wifi/can
*/

/**************************************************************************************
 * INCLUDE
 **************************************************************************************/

#include <Arduino_CAN.h>

/**************************************************************************************
 * CONSTANTS
 **************************************************************************************/

static uint32_t const CAN_ID = 0x20;

/**************************************************************************************
 * SETUP/LOOP
 **************************************************************************************/

void setup()
{
  Serial.begin(115200);
  while (!Serial) { }

  if (!CAN.begin(CanBitRate::BR_250k))
  {
    Serial.println("CAN.begin(...) failed.");
    for (;;) {}
  }
}

static uint32_t msg_cnt = 0;

void loop()
{
  /* Assemble a CAN message with the format of
   * 0xCA 0xFE 0x00 0x00 [4 byte message counter]
   */
  uint8_t const msg_data[] = {0xCA,0xFE,0,0,0,0,0,0};
  memcpy((void *)(msg_data + 4), &msg_cnt, sizeof(msg_cnt));
  CanMsg const msg(CanStandardId(CAN_ID), sizeof(msg_data), msg_data);

  /* Transmit the CAN message, capture and display an
   * error core in case of failure.
   */
  if (int const rc = CAN.write(msg); rc < 0)
  {
    Serial.print  ("CAN.write(...) failed with error code ");
    Serial.println(rc);
    for (;;) { }
  }

  /* Increase the message counter. */
  msg_cnt++;

  /* Only send one message per second. */
  delay(1000);
}

CAN Read (Приём)

Для чтения входящего CAN-сообщения сначала используйте CAN.available(), чтобы проверить, доступны ли данные, а затем используйте CAN.read() для чтения сообщения.

Исходный код на Github

/*
  CANRead

  Receive and read CAN Bus messages

  See the full documentation here:
  https://docs.arduino.cc/tutorials/uno-r4-wifi/can
*/

/**************************************************************************************
 * INCLUDE
 **************************************************************************************/

#include <Arduino_CAN.h>

/**************************************************************************************
 * SETUP/LOOP
 **************************************************************************************/

void setup()
{
  Serial.begin(115200);
  while (!Serial) { }

  if (!CAN.begin(CanBitRate::BR_250k))
  {
    Serial.println("CAN.begin(...) failed.");
    for (;;) {}
  }
}

void loop()
{
  if (CAN.available())
  {
    CanMsg const msg = CAN.read();
    Serial.println(msg);
  }
}

Заключение

В этом руководстве показано, как использовать шину CAN, доступную на UNO R4 Minima, а также как отправлять и получать данные с помощью библиотеки Arduino_CAN.

Подробнее об этой плате читайте в документации Arduino UNO R4 Minima.