-1

I need to send the value 115200 as a parameter over serial communication to an external device that which requires the parameter as a part of a byte array in the format: 0x00, 0x00, 0x00, 0x00 and I have no idea how to convert it into that format. I am doing this in Processing so a Processing/java solution would be handy for the future but ATM I am very happy if I can just send the message with this specific variable.

Here is the byte array:

byte[] tx_cmd = { 0x55, -86,             // packet header (-86 == 0xAA) 
                0x01, 0x00,              // device ID
                0x00, 0x00, 0x00, 0x00,  // input parameter NEEDS TO BE 115200
                0x04, 0x00,              // command code
                0x00, 0x01 };            // checksum

The parameter needs to be put in the 5th to the 8th position (byte[4] - byte[7]).

the message format is little endian this is the message structure:

0 0x55 BYTE Command start code1

1 0xAA BYTE Command start code2

2 Device ID WORD Device ID: default is 0x0001, always fixed

4 Parameter DWORD Input parameter

8 Command WORD Command code

10 Check Sum WORD Check Sum (byte addition) OFFSET[0]+…+OFFSET[9]=Check Sum

Any advice would be much appreciated. Thanks

  • is your question how to convert an `int` to a sizeof(int) sized byte array? or is it the value [115200](https://www.google.ch/search?q=115200+to+hex) exactly? – BeyelerStudios Nov 05 '15 at 17:12
  • Possible duplicate of [Converting an int into a 4 byte char array (C)](http://stackoverflow.com/questions/3784263/converting-an-int-into-a-4-byte-char-array-c) – mazhar islam Nov 05 '15 at 17:21
  • Clearly state the expected endian - does the least or most significant byte of the 115200 go into byte[4]? (The message appears little endian). Do you know how to calculate the checksum? if not, what algorithm is used and how is it applied here? Maybe this protocol/format has a name?? – chux - Reinstate Monica Nov 05 '15 at 17:24
  • @HannesAndersson : You have said the device you are controlling is little endian. The question now is - What is the endianness of the device doing the controlling? If it is big endian clearly you have to swap the bytes around (as the solutions provided have shown) If the device doing the controlling is a little endian architecture, and the one being controlled requires little endian values, then you don't have to do byte swapping. – Michael Petch Nov 05 '15 at 18:46
  • Please link between crossposts: https://forum.processing.org/two/discussion/13411/how-to-write-a-large-int-as-as-bytes – Kevin Workman Nov 05 '15 at 19:29

4 Answers4

1

You try to pack an int into bytes, you did not mention whether it is network order or not, so let's assume it is (e.g. the first byte, tx_cmd[4], is the highest byte of the number):

unsigned int baudrate = 115200;
tx_cmd[4] = (baudrate >> 24) & 0xff;
tx_cmd[5] = (baudrate >> 16) & 0xff;
tx_cmd[6] = (baudrate >> 8) & 0xff;
tx_cmd[7] = baudrate & 0xff;

In general, it is very handy to have functions like int_to_bytes and similar which do that in a generic way and make the code less messy.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
MByD
  • 135,866
  • 28
  • 264
  • 277
  • Thanks for the answer! although I dont get it to work as this results in: `[4] 0 [5] 1 [6] 194 [7] 0` so the [6] still is to big of number, any idea of what I am doing wrong? – Hannes Andersson Nov 05 '15 at 17:54
  • 194 is not too big - why do you say it is? – pm100 Nov 05 '15 at 18:04
  • @HannesAndersson 0, 1, 194, 0 (decimal) is 0x00, 0x01, 0xC2, 0x00 (hex) which is 0x0001C200 = 115200 in decimal. Clearly it is now in big endian form. Seems right to me. – Michael Petch Nov 05 '15 at 18:30
1

With the bytes expected to be in little-endian format, you would set them as follows:

uint32_t value = 115200;
tx_cmd[4] = value & 0xff;
tx_cmd[5] = (value >> 8) & 0xff;
tx_cmd[6] = (value >> 16) & 0xff;
tx_cmd[7] = (value >> 24) & 0xff;

It's important that the value you're working with is unsigned, otherwise you risk having 1's shifted in if the most significant bit is set.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

you need to mask and shift

int num = 115200
int b1 = (num & 0xff000000) >> 24
int b2 = (num & 0x00ff0000) >> 16
int b3 = (num & 0x0000ff00) >> 8
int b4 = (num & 0x000000ff) >> 0
pm100
  • 48,078
  • 23
  • 82
  • 145
0

Suggest creating a function to pack everything

#define byte_n(x, b) ((x >> (b*8)) & 0xFF)

void CreatePacket(byte tx_cmd[], uint16_t device_id, uint32_t param, uint16_t command) {
  #define HEADER 0xAA55
  tx_cmd[0] = byte_n(HEADER, 0);
  tx_cmd[1] = byte_n(HEADER, 1);
  tx_cmd[2] = byte_n(device_id, 0);
  tx_cmd[3] = byte_n(device_id, 1);
  tx_cmd[4] = byte_n(param, 0);
  tx_cmd[5] = byte_n(param, 1);
  tx_cmd[6] = byte_n(param, 2);
  tx_cmd[7] = byte_n(param, 3);
  tx_cmd[8] = byte_n(command, 0);
  tx_cmd[9] = byte_n(command, 1);
  unsigned checksum = 0;
  for (int i=0; i<10; i++) {
    checksum += tx_cmd[i];
  }
  tx_cmd[10] = byte_n(checksum, 0);
  tx_cmd[11] = byte_n(checksum, 1);
}

byte tx_cmd[12];
device_id = 1;
baud = 115200;
command = 4;
CreatePacket(tx_cmd, device_id,  baud, command);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256