Combine 2 Values of Array in new Var + Missing leading "0"

Hi there!

I am quite new to the Arduino scene and my coding skills are quite … dusty over the years (don’t know what’s the right term in english for that :D)

So currently I am trying to catch CAN-BUS messages and working with the bytes 0 and 1 and also with 2 and 3.

The catching is working fine so far (tried a bit with existing libs). Also I stored the values in an array.

But know:

How can I combine the Values of the Array on Index 7 and 6 / 5 and 4 and store them in a new variables.

First here is the Code:

#include <CAN.h>

void setup() {
  
  Serial.begin(9600);
  while (!Serial);

  Serial.println("CAN Receiver");

  // Start the CAN bus at 250 kbps
  
  if (!CAN.begin(250E3)) {
    Serial.println("Starting CAN-BUS failed!");
    while (1);
  }
}

void loop() {

  int i_Byte;
  int a_Buffer[8];
  int i_NOx;
  int i_O2;

  // Try to parse packet
  int i_PacketSize = CAN.parsePacket();

  if (i_PacketSize) {
    
    // Received a packet
    Serial.print("Received ");

    if (CAN.packetExtended()) {
      Serial.print("extended ");
    }

    if (CAN.packetRtr()) {
      
      // Remote transmission request, packet contains no data
      Serial.print("RTR ");
    }

    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);

    if (CAN.packetRtr()) {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    } else {
      Serial.print(" and length ");
      Serial.println(i_PacketSize);

      // Only print packet data for non-RTR packets
      while (int i_Index = CAN.available()) {

        i_Index--;
        byte b_ByteValue = CAN.read();
        
        //Serial.print(b_ByteValue, HEX);
        //Serial.print(" ");
        //Serial.println();

        a_Buffer[i_Index] = b_ByteValue;

        Serial.print(a_Buffer[i_Index], HEX);
        Serial.print(" ");
        
      }
      Serial.println();
      Serial.println();

      for (int i = 0; i < 8; i = i + 1) {
        Serial.println(a_Buffer[i], HEX);
      }

      
    }

    Serial.println();    
  }
}

So and this is my serial console output:

09:23:55.861 → Received extended packet with id 0x18F00F52 and length 8
09:23:55.861 → AF F 32 81 45 1F 1F 1F
09:23:55.861 →
09:23:55.861 → 1F
09:23:55.861 → 1F
09:23:55.861 → 1F
09:23:55.861 → 45
09:23:55.861 → 81
09:23:55.861 → 32
09:23:55.861 → F
09:23:55.861 → AF
09:23:55.861 →

So quite nice so far.

Now I want to combine Index 6 and 7 of the array to 0FAF and there is my second problem with the missing leading 0 (think this is wy the values is <16, right?)

Can anybody can give me a hint, to an function, or says “Na ur code is sh*t!”?

Would be kind :slight_smile:

If the value is < 16 you can print your own zero.

keyschpert:
09:23:55.861 → Received extended packet with id 0x18F00F52 and length 8
09:23:55.861 → AF F 32 81 45 1F 1F 1F

Now I want to combine Index 6 and 7 of the array to 0FAF

In the data you have posted the values in places 6 and 7 are both 1F so shouldn’t they combine to give 1F1F

The simple way to combine two bytes to make an int is as follows

int bigVal = (int) highByte << 8 + lowByte;

…R

What exactly do you want the combined variable to contain ?

Should it be an int, char array or what ?
Does it actually need to be in HEX ?

If you want it to be an int then 16 * high byte + low byte will do the job

The missing leading zero when printing HEX is just an artefact of the print command. The actual data will be in the array which, by the way, is of type int anyway (why ?). Printing in HEX is just a way for humans to interpret the data easier than 16 individual bits

Hi,

first thx for the replies.

I need to combine the High and Low Byte to calculate the actual values sent by the NOx sensor.

So for example:

Low Byte: AF
High Byte: 0F

Combined: 0FAF

And with this values I can calculate the ppm of the NOx sensor with:

0FAF * 0.05 -200 = ppm NOx

Low Byte: AF
High Byte: 0F

Combined: 0FAF

No

Low byte 175
High byte 15

Combined (16 * 15) + 175 = 415 which 0x019F in HEX

Man then I have a knowledge problem with CAN-BUS Values.

The doc of the NOX sensors says the following:

0 L-Byte NOx

1 H-Byte NOx

2 L-Byte O2

3 H-Byte O2

4 Status Byte

5 Error Heater

6 Error NOx

7 Error O2

Signal of NOx and O2 are unsigned int. So how do they calculate the NOx or O2 in ppm out of the 2 Bytes? I think I am quite missunderstanding something =O

Calculation for the NOx is: value (unsigned int) * 0,05ppm NOX/bit -200

and then u have the ppm of NOx

Calculation for the O2 is: value (unsigned int) * 0.000514%/bit -12%

So I thought they are combining the High and Low Byte the way i mentioned =O

Man quite diffucult for me to understand this CAN-BUS stuff ^^

Again me.

So this is a real trace of the NOx sensor here (standing engine, so 0ppm Nox but around 21% O2)

EC 0E 2B EE 45 1F 1F 1F

The data of 2B and EE "combined" to EE2B in Hex = 60971 in integer and so with calculation formula around 19,33% oxygen.

Or is that wrong?

OK OK OK,

got it working. I was thinking the wrong way. Don’t know.

Thx for your help.

int combined = ((int) a_Buffer[6] << 8) | a_Buffer[7];

As mentioned was the right way.

Don’t know what I was thinking :slight_smile:

Again THX.

Great support here

I am glad that you got there in the end. Use of HEX often confuses people but unless you receive say "FF" or need to send "FF", both of which are character arrays then the underlying data will always be in bytes combined together to make larger sized data types when necessary