Код: Выделить всё
#include
typedef struct {
uint8_t start_seq[2];
uint8_t body_size;
uint8_t type;
uint8_t unknown;
uint8_t entity_id;
uint8_t reserved[3];
float value;
uint8_t end_seq[2];
} Packet;
void printRawPacket(const char* message, const uint8_t* packet, size_t length) {
Serial.print(message);
for (int i = 0; i < length; i++) {
Serial.printf("%02X ", packet[i]);
}
Serial.println();
}
// Packet interceptor function
void handlePacket(uint8_t* raw_packet, size_t length) {
// Create a pointer to the packet structure
Packet* packet = (Packet*)raw_packet;
printRawPacket("Original bytes: ", raw_packet, sizeof(raw_packet));
// Correctly Prints: "Original bytes: BE EF 08 03 00 09 00 00 00 00 00 C0 40 EF BE"
// Access the float value without creating a copy of the 4 bytes
Serial.print("Original value: ");
Serial.println(packet->value);
// Incorrectly prints a random value or "ovf" instead of 6.00
// Modify the float value without creating a copy of the 4 bytes
packet->value = -120.0f; // little endian would be 00 00 F0 C2; big endian would be C2 F0 00 00
Serial.print("Modified value: ");
Serial.println(packet->value); // Prints -120.0 correctly
printRawPacket("Modified bytes: ", raw_packet, sizeof(raw_packet));
// Incorrectly Prints: "Modified bytes: BE EF 08 03 00 09 00 00 00 00 00 C0 00 00 F0"
// Showing the float value was not stored correctly and the footer was overwritten
// Expected output would have been: "Modified bytes: BE EF 08 03 00 09 00 00 00 00 00 00 00 F0 C2 EF BE"
}
void setup() {
Serial.begin(115200);
// Example packet
uint8_t raw_packet[] = {
// ------ HEADER ------
0xBE, 0xEF, // start sequence
0x08, // body size uint8_t
0x03, // type uint8_t
0x00, // unknown
// ------ HEADER ------
// ------ BODY ------
0x09, // entity id uint8_t
0x00, 0x00, 0x00, // reserved
0x00, 0x00, 0xC0, 0x40, // value (float, little-endian) // 6.0f
// ------ BODY ------
// ------ FOOTER ------
0xEF, 0xBE // end sequence
// ------ FOOTER ------
};
handlePacket(raw_packet, sizeof(raw_packet));
}
void loop() {
// Nothing to do here
}
Я могу легко обойти эту проблему, сделав поле значения uint8_t value[4], а затем используя функцию получения и установки, например:
Код: Выделить всё
typedef struct {
uint8_t start_seq[2];
uint8_t body_size;
uint8_t type;
uint8_t unknown;
uint8_t entity_id;
uint8_t reserved[3];
uint8_t value[4];
uint8_t end_seq[2];
// Function to get the float value from the raw packet in little-endian format
float getFloatLeValue() const {
// reverse byte order and return as float
uint32_t temp = (value[3] > 16) & 0xFF;
value[3] = (temp >> 24) & 0xFF;
}
} Packet;
Есть ли более простой и элегантный способ ?
(Я пишу свой код на C++ на PlatformIO для ESP32 с использованием Arduino Framework.)
Подробнее здесь: https://stackoverflow.com/questions/787 ... dian-float