1

I want to convert a raw array of unsigned shorts to a byte array, and then read it back. The purpose is to send the data through a SPI buffer and read it on another end.

Example:

Sender:

unsigned short array[10] = {65000, 0, 6000, 15000, 100, 50, 1000, 10, 5000, 2000};
const uint8_t *data = charArrayToByteArray(array); // <-- convert it ?
send(data, sizeof(data)); // send it

Receiver:

uint8_t buf[10];
uint8_t len = sizeof(buf);  
receive(buf, &len); 
unsigned short array[10] = arrayByteToCharArray(buf); // convert it back ?

Working functions:

send(const uint8_t* data, uint8_t len); //function that sends the data
receive(uint8_t* buf, uint8_t* len); // function that receives the data

I need help with charArrayToByteArray() and arrayByteToCharArray() and the data size can't be compromised. Thanks!

5
  • Use bit shifting and masking. Commented May 26, 2018 at 21:08
  • unsigned char low_byte = ushort & 0xff; unsigned char high_byte = (ushort >> 8) & 0xff; Commented May 26, 2018 at 21:09
  • 2
    What exactly does it mean to you to "convert" between these array types? Because the simplest thing to do is to just read the bytes of the original array, transmit them to the receiver, and have the receiver interpret them is short ints. This will work fine as long as sender and receiver use the same representation of unsigned short (which is a non-negligible consideration). No particular conversion is required for this, other than a couple of pointer casts. Commented May 26, 2018 at 21:11
  • Yes reading it into the buffer is okay but I don't really find any info on how to do it with an array and reading it back. Commented May 26, 2018 at 21:25
  • 1
    Btw making len be of type uint8_t in your send() and receive() functions means that you will never be able to send or receive more than 255 bytes in a single call, which seems a bit limiting. If you have the ability to change it, you might want to change it to uint32_t instead. Commented May 26, 2018 at 21:33

1 Answer 1

2

Since your array contains values like 65000 which can't be sent as a single byte, it's reasonable to assume you intend to send each value as two bytes.

Given that, the data-values don't need to be converted at all; rather only the type of the pointer does (so that the send() call will compile). So this should be sufficient:

unsigned short array[10] = {65000, 0, 6000, 15000, 100, 50, 1000, 10, 5000, 2000};
const uint8_t *data = reinterpret_cast<const uint8_t *>(array);
send(data, sizeof(array));

Note that the send() call is specifying sizeof(array) and NOT sizeof(data); since data is a pointer, its size is either 4 or 8 bytes (depending on your CPU architecture) and has nothing to do with the number of bytes of data you want to send!

The receiving side is similar:

uint16_t buf[10];
uint8_t len = sizeof(buf);  
uint8_t * data = reinterpret_cast<uint8_t *>(buf);
receive(data, &len); 

Note that after receive() returns, len will indicate the number of bytes received, so the number of uint16_t values received will be half that:

int numShortsReceived = len/sizeof(uint16_t);
for (int i=0; i<numShortsReceived; i++) printf("Received short #%i = %u\n", i, buf[i]);

Another note: the above code doesn't handle big-end/little-endian conversion. If you can guarantee that both the sender and the receiver will be running on a CPU with the same endian-ness, that's not a problem. If OTOH you need this code to work correctly across mixed-CPUs (i.e. with a big-endian sender sending to a little-endian receiver, or vice-versa), then you'll want to have your sending code convert your each of your uint16_t's to network/big-endian before sending them (via htons()) and also to have your receiving code convert each of the received uint16_t's from network/big-endian to its local endian-ness (via ntohs()) after receiving them (but before trying to use them for anything).

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your answer, it does explain the sending/receiving part. But I can't figure out how to get the uint16_t array using bit-shifting. I get weird values. example in for-loop: shortArray[i] = (data[i] << 8) | (data[i+1]);
my bad, should be shortArray[i] = (data[I*2 + 1] << 8) | (data[i*2]);
Bit-shifting shouldn't be necessary; the bytes are already in the correct format.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.