Ciao a tutti!
Sto lavorando ad un progetto con 3 (anche se saranno probabilmente di più alla fine) UNO R4 Minima collegati insieme attraverso la rete CAN (pilotata dal chip dell'Arduino e collegata ad un transceiver SN65HVD230). Sto attendendo che mi arrivino tutti i componenti ma stavo intanto pensando al funzionamento.
Allora, io vorrei che due Arduino leggessero dei dati dai sensori ad essi collegati e li inviassero sulla rete CAN in continuazione, sempre mantenendo lo stesso ID su ogni pacchetto (per identificarne la provenienza). L'Arduino "main" dovrebbe occuparsi di scrivere i dati in arrivo su di una SD, ciclando tra i vari messaggi in arrivo e prendendo soltanto quelli provenienti dal sensore desiderato.
Dal momento che nella documentazione della libreria non mi pare di aver visto che si possa passare l'ID alla funzione .read() come posso riuscire a filtrare i dati in arrivo? E ci sarebbe un conflitto tra dati se questi viaggiano contemporaneamente sulla linea? (non credo dato che il CAN è usato nelle automobili dove viaggiano molti pacchetti diversi allo stesso tempo).
EDIT: Per comunicare tra le varie schede, secondo voi, è meglio il CAN o l'I2C?
Non puoi paragonarli. I2C è pensato per dialogo tra dispositivi elettronici mooooolto vicini, di solito MCU con sensori. Ma sempre molto vicini. Infatti esistono dei chip I2C extender.
Esatto, è quello che ho visto anche io. Dato che @nid69ita citava un'altra libreria volevo rendermi conto di cosa fosse ma, come avevo già constatato, la R4 vuole la sua.
Quello che non sono riuscito a capire dalla libreria nativa è se la funzione .read() accetti un valore ID per filtrare i messaggi...sai consigliarmi qualcosa @gpb01 ?
Negli esempi che fanno di lettura NON lo vedo mai usato ed il metodo read() non lo prevede, però, leggendo i sorgenti, trovo questi due commenti (mi sembrano un po' poco chiari):
, _can_mailbox_mask
{
CAN_DEFAULT_MASK,
CAN_DEFAULT_MASK,
CAN_DEFAULT_MASK,
CAN_DEFAULT_MASK,
0, /* Use no id filtering -> a CAN frame with any ID will be stored in receive mailbox group #0. */
CAN_DEFAULT_MASK,
0, /* Use no id filtering -> a CAN frame with any ID will be stored in receive mailbox group #2. */
CAN_DEFAULT_MASK
}
Beh, no, l'esempio CANReadFilter è piuttosto chiaro, fa vedere esattamente come filtra i due ID di demo, sia quello standard (usa il valore 0x10) che quello extended (usa il valore 0x100).
Ciao a tutti,
ho montato i componenti e gli esempi funzionano alla grande.
Ora, prima di filtrare i messaggi, dovrei capire come mandare sulla linea CAN testi e valori float...avete idee?
Ni.
Occhio che i messaggi CANbus sono al massimo di 8 byte !! MAX_DATA_LENGTH = 8
quando crei o ricevi la variabile msg, essa è un oggetto che contiene:
Allora forse ci sono... uint8_t const msg_data[] = {0,0,0,0,0,0,0,0}; con questo alloco la memoria con un array di 8 byte che se stampo mi ritornerà una stringa di 8 zeri.
Ora quello che sono riuscito a fare è spedire una stringa dichiarandola come uint8_t const msg_data[] = "ciao"; e passandola direttamente a CanMsg. Ora quello che non mi torna è: a cosa mi serve la dichiarazione di prima? (direi a nulla).
In ogni caso l'output che ottengo è sempre hex...come lo ritrasformo in dato leggibile? usando string()?
Se usi la Serial.print del msg, l'oggetto CanMsg stampa i singoli byte che compongono il messaggio
Al link del mio post #19 hai il codice della classe CanMsg e guarda la printTo() che è quella incaricata di stampare in generale un CanMsg con un print
Ad un certo punto stampa i singoli byte in esa con snprintf(buf, sizeof(buf), "%02X", data[d])
Prova a fare Serial.println(msg.data); essendo data un array di byte (unsigned 8 bit) dovrebbe stamparlo come una stringa classica del C
string() credo sia un metodo della classe String, evitale su queste piccole MCU. Dobbiamo parlare di stringhe classiche del C ovvero array di unsigned char o array di byte terminati da null (valore 0)
uint8_t msg_data[] = "ciao"; è una stringa classica del C di 5 elementi, ovvero hai un array di byte con dentro i valori ascii dei caratteri esempio 'c' è 99 (in esadecimale 0x63)
msg_data[0] = 99
msg_data[1] = 105
msg_data[2] = 97
msg_data[3] = 111
msg_data[4] = 0