from your original code
unsigned char buf[8];
therefore all you need to do is replace 'sample_data' by 'buf', that is from reply #9 code:
memcpy(&temp_raw, &buf[2],2);
hope that helps...
from your original code
unsigned char buf[8];
therefore all you need to do is replace 'sample_data' by 'buf', that is from reply #9 code:
memcpy(&temp_raw, &buf[2],2);
hope that helps...
thx so mutch its working !
on my outpout :
14:38:19.039 -> Get data from ID: 0x18FF0AEB
14:38:19.039 -> DE AE F5 25 E5 1 79 0
14:38:19.039 -> 0x25F5
14:38:19.039 -> 9717
14:38:19.039 -> 27.64
i just have a last questions , for the temperature i want only the byte three four, here F5 25 , and if I understand correctly you use this to select them : memcpy(&temp_raw, &buf[2],2);
so if i want the bytes 5-6 for the CO2 ( my sensor datasheet ) here the values E5 01 , i just need to write: `memcpy(&temp_raw, &buf[3],3); ???
Thx for your help in my project !
almost...
you need to write:
memcpy(&temp_raw, &buf[4],2); //buf[4] is the fifth byte in buf, 2 because you want 2 bytes!
hope that helps...
Thx you so mutch
I just drop here the code completed :
#include <SPI.h>
#define CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 53;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
void setup() {
SERIAL_PORT_MONITOR.begin(115200);
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
void loop() {
unsigned char len = 0;
unsigned char buf[8];
if (CAN_MSGAVAIL == CAN.checkReceive()) { // check if data coming
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
unsigned long canId = CAN.getCanId();
uint16_t temp_raw;
memcpy(&temp_raw, &buf[2],2); //buf[2] is the third byte in buf, 2 because you want 2 bytes
Serial.print("0x");
Serial.println(temp_raw,HEX);
Serial.println(temp_raw,DEC);
float temp_degC = ((temp_raw * 0.3125) - 273)/100;
Serial.println(temp_degC,2);
uint16_t co2_raw;
memcpy(&co2_raw, &buf[4],2); //buf[4] is the fifth byte in buf, 2 because you want 2 bytes
Serial.print("0x");
Serial.println(co2_raw,HEX);
Serial.println(co2_raw,DEC);
float co2_true = ((co2_raw * 1) - 0)/100;
Serial.println(co2_tru,2);
SERIAL_PORT_MONITOR.println("-----------------------------");
SERIAL_PORT_MONITOR.print("Get data from ID: 0x");
SERIAL_PORT_MONITOR.println(canId, HEX);
for (int i = 0; i < len; i++) { // print the data
SERIAL_PORT_MONITOR.print(buf[i], HEX);
SERIAL_PORT_MONITOR.print("\t");
}
SERIAL_PORT_MONITOR.println();
}
}
outpout :
14:38:19.039 -> Get data from ID: 0x18FF0AEB
14:38:19.039 -> DE AE F5 25 E5 1 79 0
14:38:19.039 -> 0x25F5
14:38:19.039 -> 9717
14:38:19.039 -> 27.64 ( degree celcius )
That's a wordy way of saying this:
int y = 0x259C;
unsigned int myDec = y;
(And it fails on larger values like 0x2710 (10000 in decimal) because myDigit can't hold more than 4 decimal digits.)
The example is only for 0x259C.
y/myDec still holds : 0010010110011100 (259C) and not 1001011000101000 (9628)
0x259c is the same as 9628.
After the loop, the myDigit array contains the values 8, 2, 6, and 9. Substituting myDigit[n] for each of those values in the myDec calculation:
unsigned int myDec = 9 * 1000 + 6 * 100
+ 2 * 10 + 8 * 1;
which is the same as saying:
unsigned int myDec = 9000 + 600
+ 20 + 8;
which simplifies to:
unsigned int myDec = 9628;
which is the same as:
unsigned int myDec = 0x259c;
and since that value is already in y, it's the same as:
unsigned int myDec = y;
In other words, it's a lot of dividing by 10 just to multiply the digits by (powers of) 10 just to get back to the same value.
Edit: I see what you're trying to do (BCD). To get BCD you'd have to multiply the digits by powers of 16:
unsigned int myDec = 9 * 4096 + 6 * 256
+ 2 * 16 + 8 * 1;
But there's no indication from OP that that is what's needed. (A perhaps faster method to convert decimal to BCD is the Double dabble algorithm.)
int y1 =0x259C;
int y2 = 0x9628;
By your patient interaction, I have realized that there is a mistake in my sketch of post #8. The sketch should be as follows to transform this binary 259C (0010 0101 1001 1100) pattern into this BCD 9628 (1001 0110 0010 1000) pattern.
byte myDigit[4];
int i = 0;
void setup()
{
Serial.begin(9600);
int y = 0x259C;
do
{
myDigit[i] = y % 10; //getting the decimal digits of the target decimal number: 8 2 6 9
y = y / 10;
i++;
}
while (y != 0);
unsigned int myDec = myDigit[3]<<12 | myDigit[2]<<8
|myDigit[1]<<4 | myDigit[0];
Serial.println(myDec, HEX); //shows: 9628
}
void loop() {}
The following Horner Rule (Fast Method) can also be applied to convert any size (limited by memory) binary number into BCD form. This Rule will put this bit pattern 1001011000101000 (9628 = decimal number in BCD format) in memory for this bit pattern 0010010110011100 (259C = binary number).


Your two topics on the same subject have been merged.
Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.
Repeated duplicate posting could result in a temporary or permanent ban from the forum.
Could you take a few moments to Learn How To Use The Forum
It will help you get the best out of the forum in the future.
Other general help and troubleshooting advice can be found here.
Thank you.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.