Converting and adding HEX values together

Hello all,

I'm trying to read a value received over modbus and also re-transmit an altered value.

So far I have been successful in decoding the value being sent. It consists of up to 8 digits. the value is divided into 4 bytes. Each byte represents a column of two numbers. So if sent value is 99887766 then I get it as Byte0 = 66 HEX, Byte 1 = 77 HEX, Byte 2 = 88 HEX, Byte 3 = 99 HEX.

I would need to convert the incoming value to a 32 bit value for display / logging on external device.

I also need to be able to send out a 32 bit value correctly. Eg send 12345678 = Byte0 = 4E HEX, Byte 1 = 38 HEX, Byte 2 = 22 HEX, Byte 3 = 0C HEX.

Any suggestions to make this work?

I have moved this topic to Programming Questions.... General Discussion is suited to general discussion about the community/forum.

The first, building your 32 bit int, is a simple matter of add a value, shift 8 bits right, add a value, shift 8 bits right, add a value, shift 8 bits right, and add a value.

The second, is simply masking, shifting, and conversion to 8-bit value, then send, done 4 times.

As an aside, I think your interpretation of 12345678 as 0C22384E is incorrect; best check it, or you'll be chasing a non-existent error in your processing.

I won't attempt to write the code, but I'll give you an outline...

It doesn't matter if they are "hex" because everything in the computer is binary. Things usually only get tricky when you mix-and-match numerical values and the ASCII (text) representation of values.

Make a type long variable to hold the new-combined 32-bit value and a temporary (or 4 temporary) type-long variables.

Copy the least significant "hex" byte into the new "final" variable.

Copy the next byte into a temporary long variable and shift left 8 places.

Use bitwise-and to combine the bytes in the final variable.

Shift the next byte 16-bits, and "and" again, then shift the last byte 24-bits and "and" again.

Assuming you need to send one byte at a time, you can "reverse the process", right-shifting. This time you can use bitwise-or with 0xFF to "mask" (zero out) zero-out the higher-order bytes, leaving an 8-bit value, which you can copy to a separate byte or char.

better make that unsigned long

I have been testing the with shifting the bytes before. But then I was thinking in decimal values and could not get it right.

// Testcode
unsigned long finalValue ;
unsigned long tempValue1 = ( Byte1 << 8 ) ;
unsigned long tempValue2 = ( Byte2 << 16 ) ;
unsigned long tempValue3 = ( Byte3 << 24 ) ;
finalValue = ( Byte0 + tempValue1 + tempValue2 + tempValue3 ) ;

Input data is 00887766. ( Byte0 = 66 HEX, Byte1 = 77 HEX, Byte2 = 88 HEX, Byte3 = 0 HEX. )
finalValue is 8943462 in decimal, and 887766 in hex. (Using Decimal to Hexadecimal converter online)

was experimenting with bitwise-and and the result got zero. But I need to read more on that.

If you initialize the binary input variable using hexadecimal representation, you get back the expected result when printing out the binary value using hexadecimal representation.

It is pointless to post incomplete snippets.

Is that possibly what you want:

void setup() {
  Serial.begin(115200);
  byte values[4] {0x00,0x88,0x77,0x66};
  unsigned long result;
  for(auto &value : values) { result = (result << 8) | value;  }
  Serial.println(result,HEX);
  Serial.println(result);
}

void loop() {}

?

The above won't do what you expect on an 8-bit Arduino like the Uno, because the right hand side defaults to a 16 bit integer.

This will work:

unsigned long tempValue2 = ( ((unsigned long)Byte2) << 16 ) ;
unsigned long tempValue3 = ( ((unsigned long)Byte3) << 24 ) ;

Yes, and it got the same results as I have now when I'm testing.

Printing the result with HEX gave me the results I wanted, and that's how I found out it was hex data. But, I'm still trying to get the result readable outside print and as readable 32 bit value.

I don't understand this.

You packed a value that was split into four individual bytes into a memory (unsigned long) that can take out 32 bits.

So you have a variable (result) with the desired value. This is always the same. It doesn't matter whether it is displayed as a hex, oct, bin or decimal value.

What do you mean by readable outside print?

The data are binary. Unfortunately, you seem to be confused by different human readable representations of binary data.

1 Like

The value is stored in memory as:

00000 0000 1000 1000 0111 0111 0110 0110  Bin
  0     0    8    8    7    7    6    6   Hex

And this is also:

42 073 546 as Oct
8.943.462 as Decimal

It is always the same value

I do know that the value is the same, but I wanted it 'human' readable.

The unit sends out the value 00887766, witch is also that value in decimal that is shown on that display. It sends the data through a RS485 modbus connection. I want to store that value in decimal form as well on the sd card and display it on an other display. (It's a long distance between the units.).

So when the unit sends out it's data (00887766), the decimal value 8943462 is stored on the sd card and displayed on my screen, and that's not the desired result.

First you write that you want the value to be shown in decimal form on the SD card and display, and then you say that this is exactly what happens but that this is not the desired result.

It may be because English is not my first language that I don't understand what your desired result should be.

But at least I tried :wink:

Finally, print/println writes to a file and to a display where you can specify the base for the desired number system:

For the display it depends on the library used, how it is solved in detail.

1 Like

No, it sends binary values.

You have chosen to represent the data in human readable form as " 00887766", which can be interpreted differently, depending on whether that is decimal or hexadecimal representation.

I feel that I need to read a little more so that I myself understand what I want.

When I have achieved the desired result I will post an update with a solution. I thank you for the information I have received so far. It always feels easy to think of a solution, but harder to execute. But it's the kind of thing that gives you experience for future projects.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.