Serial ouptut interpretation of HEX

Hello everyone,

I am working on my RS485 bustelegram and reserved 2 bytes as command word stored as short. To send the telegram as whole package 'transform' the short to fit into an char array.

short command = 0xABCD;
char DATA[16] = {};

DATA[0] = (command>>8) & 0xFF;
DATA[1] = (command) & 0xFF;

Sending the telegram to the slave yields in this output on the serial monitor

FFFFFFAB FFFFFFCD

which I have received via RS485. This data is stored in an char array on the slave. There I rebuilt the command short.

char DATA_RECEIVED = {RECEIVEDVALUE1,RECEIVEDVALUE2,...};

short RECEIVE_COMMAND = (DATA_RECEIVED[1] & 0xFF) + (DATA_RECEIVED[0] << 8);

Serial.print("DEC "); Serial.println(RECEIVE_COMMAND ,DEC);
Serial.print("HEX "); Serial.println(RECEIVE_COMMAND ,HEX);
Serial.print("BIN "); Serial.println(RECEIVE_COMMAND ,BIN);

This results in

DEC -21555
HEX FFFFABCD
BIN 11111111111111111010101111001101

This would mean, the short needs 4 bytes, but only 2 bytes are send via RS485. Where are the additional bytes come from?

I wrote a quick running example which should outline my problem better

#include <Arduino.h>

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

  Serial.println("--Setup--");
}

void loop() {
  
  short var = 0xABCD;

  char DATA[2];

  DATA[0] = (0xABCD >> 8) & 0xFF;
  DATA[1] = (0xABCD) & 0xFF;

  Serial.print("VAR: "); Serial.println(var,HEX);

  Serial.print("DAT: "); Serial.print(DATA[0],HEX); Serial.print(" "); Serial.println(DATA[1],HEX);


  short rec_var = (DATA[1] & 0xFF) + (DATA[0] << 8);

  Serial.print("REC: "); Serial.print(rec_var,HEX);


  delay(10000);


}

can you post the transmit and receive code?

Your signed integer values (char, short, int, long) get sign-extended when converted to a longer type.

Serial.print() prints all signed integers as 'long'. For DECimal it isn't a problem since all those sign-extended bits just show up as a minus-sign. For HEXadecimal and BINary the sign extension is sorely visible. I recommend casting your signed values to unsigned values of the same length:

Serial.print("DEC "); Serial.println(RECEIVE_COMMAND ,DEC);
Serial.print("HEX "); Serial.println((unsigned short)RECEIVE_COMMAND ,HEX);
Serial.print("BIN "); Serial.println((unsigned short)RECEIVE_COMMAND ,BIN);
1 Like

This means that the process data only holds the value I intend?

short RECEIVE_COMMAND = 0xABCD;

and is only represented as per definition of the print method

'FFFFABCD'

Thanks for the clarification. Since my telegram has a fixed length and a short only has 2 bytes no additional bytes can be smuggled in. I just was not sure why I am seeing seemingly wrong data.

would unsigned short have the same problem? or would it produce 0x000ABCD?

#include <Arduino.h>

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

  Serial.println("--Setup--");
}

void loop() {
  
  // short var = 0xABCD;
  unsigned short var = 0xABCD;

  char DATA[2];

  DATA[0] = (0xABCD >> 8) & 0xFF;
  DATA[1] = (0xABCD) & 0xFF;

  Serial.print("VAR: "); Serial.print(var,HEX); Serial.print(" | "); Serial.println(var,BIN);

  Serial.print("DAT: "); Serial.print(DATA[0],HEX); Serial.print(" "); Serial.println(DATA[1],HEX);


  unsigned short rec_var = (DATA[1] & 0xFF) + (DATA[0] << 8);
  // short rec_var = (DATA[1] & 0xFF) + (DATA[0] << 8);

  Serial.print("REC: "); Serial.println(rec_var,HEX);


  delay(10000);


}

with unsigned short the values are correctly displayed.

No, because Serial.print() doesn't put in the '0x' prefix and suppresses leading zeroes. An 'unsigned short' or 'uint16_t' containing 0xABCD would print out as ABCD. If it had the value 0x0123 it would print out as 123.

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