CAN-bus R4 Minima

RISOLUZIONE!

Ciao a tutti, finalmente ho risolto il problema, spero che il mio lavoro sia di aiuto per coloro che vorranno ripetere lo stesso progetto.

Innanzi tutto ogni elemento della rete CAN deve avere un ID, da dichiarare in questo modo prima del setup:

static uint32_t const CAN_ID = 0x01;  //Indirizzo CAN, cambiare a piacimento

Successivamente, nel setup, bisogna inizializzare la comunicazione cosi:

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

In questo caso, come nell'esempio della libreria, ho aggiunto uno statement di controllo che ritenta la connessione nel caso questa non vada a buon fine.

Ed infine, per facilitare le operazioni di lettura/scrittura, ho scritto delle funzioni apposite:

void sendCanFloat(float msg_cnt) {
  uint8_t const msg_data[8] = {};                                       //Buffer messaggio
  memcpy((void*)(msg_data), &msg_cnt, sizeof(msg_cnt));                 //Copia contenuto messaggio nel buffer
  CanMsg const msg(CanStandardId(CAN_ID), sizeof(msg_data), msg_data);  //Spedisce messaggio

  if (int const rc = CAN.write(msg); rc < 0) {
    Serial.print("CAN.write(...) failed with error code ");
    Serial.println(rc);
  }
}

void sendCanChar(char msg_cnt) {
  uint8_t const msg_data[8] = {};                                       //Buffer messaggio
  memcpy((void*)(msg_data), &msg_cnt, sizeof(msg_cnt));                 //Copia contenuto messaggio nel buffer
  CanMsg const msg(CanStandardId(CAN_ID), sizeof(msg_data), msg_data);  //Spedisce messaggio

  if (int const rc = CAN.write(msg); rc < 0) {
    Serial.print("CAN.write(...) failed with error code ");
    Serial.println(rc);
  }
}

char readCanChar(int address) {
  if (CAN.available()) {
    CanMsg const msg = CAN.read();
    const uint8_t* buffer = msg.data;
    char res;
    memcpy(&res, buffer, sizeof(buffer));
    if (msg.getStandardId() == address) {
      return res;
    }
  }
}

float readCanFloat(int address) {
  if (CAN.available()) {
    CanMsg const msg = CAN.read();
    const uint8_t* buffer = msg.data;
    float res;
    memcpy(&res, buffer, sizeof(buffer));
    if (msg.getStandardId() == address) {
      return res;
    }
  }
}

Chiaramente si possono creare altre funzioni simili per decodificare altri tipi di dati. L'utilizzo di queste nel codice principale avviene così:

sendCanChar('a'); //carattere da inviare
char risposta = readCanChar(0x00); //indirizzo da cui leggere
sendCanFloat(123.45); //valore da inviare
float risposta = readCanFloat(0x00); //indirizzo da cui leggere

Di nuovo, spero che questo post sia di aiuto.

Un saluto,
Lucio