Hello and a good morning from cold Germany!
So, I am not new to Arduino, been programming for about 4 Years or so but would not consider me an expert. If I ask anything stupid please let me know. I have done a lot of research on the following topic, I hope this is noticeable.
HARDWARE:
Arduino Uno with MCU2515 CANBus Shield
Later I will want to implement the project on a much faster NodeMCU32-S.
So, generally what I want to do is read out signals from a vehicle CAN-Bus.
All easy, I am receiving the Frames and Data.
My Problem more mathematical nature:
I receive Data in Hex Format. I know this is just a way of displaying it, as the processor is working binary anyway.
I need to convert the HEX Data into binary so I can then pick out the “interesting” bits, assemble them in a temporary variable and then convert that to DEC for display/logging.
I have the CAN-Database and know the Startbits, Lenghts and Faktor/Offset of the Signals I want to use – its just the problem of how to convert the incoming HEX Data to binary in a reasable way.
My Idea would be to use an array with a length 64. In this array I could then convert my HEX Data, then pick out the interesting bits ( For example: Startbit 12 Length 8), and save them in a variable.
If anyone could give me some advice on how this would be most efficient I would be very thankful.
I am not posting any code as the only working bit I have is to read out the Data from the Bus
EDIT:
I tried but guess I don't understand the syntax of this.
Here is my Code (from MCU_CAN.h library)
void loop()
{
if(!digitalRead(CAN0_INT)) // If CAN0_INT pin is low, read receive buffer
{
CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
if((rxId & 0x80000000) == 0x80000000) // Determine if ID is standard (11 bits) or extended (29 bits)
sprintf(msgString, "Extended ID: 0x%.8lX DLC: %1d Data:", (rxId & 0x1FFFFFFF), len);
else
sprintf(msgString, "Standard ID: 0x%.3lX DLC: %1d Data:", rxId, len);
Serial.print(msgString);
if((rxId & 0x40000000) == 0x40000000){ // Determine if message is a remote request frame.
sprintf(msgString, " REMOTE REQUEST FRAME");
Serial.print(msgString);
} else {
for(byte i = 0; i<len; i++){
sprintf(msgString, " 0x%.2X", rxBuf[i]);
Serial.print(msgString);
}
}
Serial.println();
}
}
Although "msgString" is declared as a char array of length 128 the example does not use any index to write to it. That's alone something I don't understand
Basically, if I understand this of your post
Or extract the subvalue of variable "value" at startbit 12, length 8 bit:
Code: [Select]
uint32_t detail = (value >> 12) & 0xFF;
I don't see any need for arrays or the like, the processor is able to handle the bit values.
I would be happy. Could you just throw it in my code, I will try to understand from there!
Although "msgString" is declared as a char array of length 128 the example does not use any index to write to it. That's alone something I don't understand
sprintf knows how to handle character arrays. A character array is also called C string if handled as in your sketch.
Basically, if I understand this of your post
Lets make an example. Say, the content of value is 0x684539Af, in binary b01101000010001010011100110101111
This line
uint32_t detail = (value >> 12) & 0xFF;
does first shift the bits to the right by 12 bits, so the binary value is b00000000000001101000010001010011.
Then that value is masked by the AND operator using a mask with the 8 lowest bits set. The resulting binary value is b00000000000000000000000001010011 or 0x53.
I hope that helps :-).