Converting CAN-Bus (HEX) values to binary to sort out interessting Bits

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 

You don’t have to convert anything as you already wrote yourself. To check for bit 12 on value just use:

if (value & (1 << 12)) ...

Or extract the subvalue of variable “value” at startbit 12, length 8 bit:

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.

Thanks Pylon, I will try this out right now :slight_smile:

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 :frowning:

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 :-).