Panel For Example Panel For Example Panel For Example

Serial Data Conversion Between Unions and Structs

Author : Adrian March 19, 2026

 

Background

Serial data transfers in embedded systems are byte-oriented. Some data types, such as a float like 231.5, are stored in memory as a sequence of bytes. For example, the float value a = 231.5 is represented in memory as 0x43678000. The processor reads the four bytes and interprets them according to the IEEE 754 float representation to present the decimal value 231.5.

If four bytes {0x43, 0x67, 0x80, 0x00} are received from a serial interface, how can they be converted into a float? Directly writing float a = 0x43678000 is not valid C. In serial communication, when the transmitted data includes floating-point values, unions or structs can be used to reinterpret the byte sequence as a float.

 

Using a union

A union lets the same memory region be accessed as either a float or a byte array. Example code:

#include <stdio.h> // union // float f; // 4 bytes // unsigned char s[4]; // 4 bytes typedef union { float f; unsigned char s[4]; } Union_test; typedef struct { float f1; } Struct_test; int main(void) { float a = 231.5f; Union_test x; Struct_test z; x.f = a; z = *(Struct_test*)(&(x.s)); printf("z=%.2f ", (double)z.f1); printf("End of this program\n"); return 0; }

The union field f and the array s[4] share the same memory. Setting f = 231.5 and then inspecting s[4] will show the four bytes that represent that float. The example above also demonstrates casting the byte array address to a struct pointer and reading the float back through the struct.

9d798758-e7ea-11ee-a297-92fbcf53809c.jpg

 

Using a struct

The same experiment can be done with a struct. For example, with an array s[4] = {0x00, 0x80, 0x67, 0x43}, casting the address of s[0] to a pointer to a struct containing a float and reading that float will produce 231.5 on a little-endian system.

 

Endianness

The observed byte order 00 80 67 43 instead of 43 67 80 00 is due to little-endian storage. For multi-byte objects, some architectures store the least significant byte at the lowest address (little-endian), while others store the most significant byte at the lowest address (big-endian).

For example, the 32-bit hexadecimal value 0x01234567 will be stored differently depending on machine endianness:

9d8c54d2-e7ea-11ee-a297-92fbcf53809c.png

 

Endianness test function

You can use a simple function to determine whether a system is little-endian or big-endian. Example:

void idtest(void) { int a = 1; unsigned char *start = (unsigned char *)&a; if (*start == 1) printf("little endding"); else if (*start == 0) printf("big endding"); }

Explanation: if the first byte equals 1, the system is little-endian; if it equals 0, the system is big-endian.