Arduino CanBus Communication

Salve a tutti,

spero di aver inserito il post nella sezione corretta....in caso contrario chiedo scusa ma questa è la prima volta che scrivo sul forum.

Il mio problema è questo: sto tentando di interpretare i dati ricevuti da un motore elettrico con interfaccia canbus utilizzando arduino uno e una scheda MCP2515. Il messaggio di stato motore è composto da 8 byte (es. 0D 00 00 A0 05 45 04 54) devo estrarre il valore della temperatura motore in °C che da specifiche ha lungheza 8 bit ed inizia al bit 34 del messaggio, quindi allocata all'interno del byte 5 (che nell'esempio sopra riportato ha valore 05) e nel byte 6 (nell'esempio ha vaore 45).
Quello che vorrei sapere è come estrapolare gli 8 bit dai dei 2 byte?

Per completare il quadro: il messaggio di esempio riportato si riferisce ad una temperatura motore di 28°C, inoltre al valore estratto dal messaggio andrà sottratto un offset pari a -40.

Spero di essere stato abbastanza chiaro....

Grazie!

Buonasera,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

Io prenderei i 2 bytes e li copierei in un unsigned int (16 bit), farei un AND binario per azzerare i bit che non costruiscono il valore, dopo di che, con un semplice shift right, del giusto numero di bit, hai numero cercato.

Guglielmo

Buonasera Guglielmo,

grazie della ripsosta, adesso provo e seguire la tua dritta e vi farò sapere com'è andata....

Arenato già al primo step…

combino i due byte su unsigned Int in questo modo:

unsigned int tempRaw = rxBuf[5];
tempRaw =  tempRaw << 8;
tempRaw  |= rxBuf[4];

dove:

rxBuf è stato dichiarato come array di 8 valori unsigned char

rxBuff[4] = 0D (hex)
rxBuff[5] = 65 (hex)

tempRaw assume il valore 650D, in binario: ‭0110010100001101‬.

Ora, prima di azzerare i bit non necessari ed eseguire lo shift, avrei voluto localizzare gli 8 bit all’interno di tempRaw, dato che il motore ha temperatura di 30 °C e considerando l’offset di 40 mi aspetterei di trovare all’interno di tempRaw la sequenza di 8 bit equivalente a 70: ‭01000110‬…ma niente.

Dove sto sbagliando?

Beh, con i due bytes che riporti 0000 1101 e 0110 0101, girali come vuoi ma non arrivi ad avere 0100 0110 ::slight_smile:

Sicuro dei valori letti ed aspettati ?

Guglielmo

Ora ricontrollo il tutto…

mmmm c'è qualche cosa di strano

0D 00 00 A0 05 45 04 54

0000 1101 0000 0000 0000 0000 1010 0000 0000 0101 0100 0101 0000 0100 0101 0100
        |         |         |         |  |
        8        16        24        32 34

8 bit ed inizia al bit 34

0000 1010 =0A = 10

Per completare il quadro: il messaggio di esempio riportato si riferisce ad una temperatura motore di 28°C, inoltre al valore estratto dal messaggio andrà sottratto un offset pari a -40.

28-40= -12
-12 (16 bit) = 1111 1111 1111 0100 = FFF4

a meno che il risultato non debba essere 68 al quale sottrarre 40
0110 1000 = 68
e.... questo valore c'è :wink: da bit 4 al 12...

nel qual caso

byteA = 0000
byteB = 1101
byteC = 0000

//con il primo byte fai un and 1 e shifti di 3 posti
byte byte1 = (byteA & 1)<<3
//e ottieni il valore del bit 3 (MSB) in questo caso 0---
//del secondo byte lo shifti di 1
byte byte2 = byteB >>1  // quindi -110
//poi fai un or con byte1 e ottieni il valore del primo byte
byte1 = byte1 | byte2  // 0110 --------------------------------------------primo valore                
//poi  sempre del secondo byte fai and 1 e shifti di 3 posti
byte2 = (biteB & 1)<<3 // quindi 1---
//in ultima con il terzo byte shiftato di 1 fai l'or con il secondo
byte2 = byte2 | (byteC>>1) // quindi 1000  --------------------------------secondo valore

… se non ho fatto errori :wink:

Ciao Patrick,

intanto ti ringrazio per la risposta, ma sono sicuro che il valore da leggere sia contenuto all’interno del byte 5 e del byte 6, infatti al variare della temperatura del motore vedo che i valori contenuti in questi due byte cambiano mentre i primi tre byte rimangono invariati. Probabilmente sto sbagliando nell’interpretazione delle specifiche di comunicazione, anche se in realtà non ho molte informazioni a parte la lunghezza del dato e il bit di start.
Comunque le info del tuo secondo post mi saranno utilissime quando troverò i dati da decodificare.
Per oggi getto la spugna, domani faccio altre prove e vi terrò agiornati.

Grazie 1000!!!