Arduino中Float变量转HEX值失败,求正确实现方案
Arduino Float转十六进制的正确实现方法
原代码的核心问题
- 错误的赋值逻辑:
(gyrox, HEX)是C语言的逗号表达式,实际只会把HEX的宏值(16)赋值给数组元素,完全没有实现float到十六进制的转换。 - 类型长度不匹配:Arduino中float是4字节数据类型,用单字节的
byte数组根本存不下float的完整数据。 - 错误的输出方式:
Serial.println((char*)ByteArray)把字节数组当作ASCII字符串输出,但float的原始二进制字节大多是不可打印字符,必然出现乱码。
两种正确实现方案
方案1:直接打印float对应的十六进制字符串(基于IEEE754标准)
通过共用体共享内存空间,提取float的原始字节,再逐个打印十六进制:
// 共用体:共享内存,用于提取float的字节 union FloatToBytes { float f; byte bytes[4]; }; float gyrox, gyroy, gyroz, accelx, accely, accelz, enlem, boylam, sicaklik, yukseklik, basinc; FloatToBytes converter; void setup() { Serial.begin(9600); // 初始化变量 gyrox = 1.5; gyroy = 2.5; gyroz = 2.0; accelx = 5.3; accely = 3.2; accelz = 6.1; enlem = 39.9250506; boylam = 32.8369756; sicaklik = 35.0; yukseklik = 103.0; basinc = 65.31455; } void loop() { // 逐个转换并打印 printFloatHex(gyrox, "gyrox"); printFloatHex(gyroy, "gyroy"); printFloatHex(gyroz, "gyroz"); printFloatHex(accelx, "accelx"); printFloatHex(accely, "accely"); printFloatHex(accelz, "accelz"); printFloatHex(enlem, "enlem"); printFloatHex(boylam, "boylam"); printFloatHex(sicaklik, "sicaklik"); printFloatHex(yukseklik, "yukseklik"); printFloatHex(basinc, "basinc"); delay(1000); Serial.println("-------------------"); } // 辅助函数:打印float的十六进制表示 void printFloatHex(float value, const char* name) { converter.f = value; Serial.print(name); Serial.print(": 0x"); // 从高位到低位打印(可根据字节序需求调整顺序) for (int i = 3; i >= 0; i--) { if (converter.bytes[i] < 0x10) Serial.print("0"); // 补零,确保两位十六进制 Serial.print(converter.bytes[i], HEX); } Serial.println(); }
方案2:提取float字节到数组,按需处理或发送
用内存拷贝将float的字节存入数组,再以十六进制格式输出:
float gyrox, gyroy, gyroz, accelx, accely, accelz, enlem, boylam, sicaklik, yukseklik, basinc; // 11个float,每个占4字节,共需44字节数组 byte floatBytes[44]; void setup() { Serial.begin(9600); // 初始化变量 gyrox = 1.5; gyroy = 2.5; gyroz = 2.0; accelx = 5.3; accely = 3.2; accelz = 6.1; enlem = 39.9250506; boylam = 32.8369756; sicaklik = 35.0; yukseklik = 103.0; basinc = 65.31455; // 将每个float的字节复制到数组 memcpy(floatBytes, &gyrox, 4); memcpy(floatBytes + 4, &gyroy, 4); memcpy(floatBytes + 8, &gyroz, 4); memcpy(floatBytes + 12, &accelx, 4); memcpy(floatBytes + 16, &accely, 4); memcpy(floatBytes + 20, &accelz, 4); memcpy(floatBytes + 24, &enlem, 4); memcpy(floatBytes + 28, &boylam, 4); memcpy(floatBytes + 32, &sicaklik, 4); memcpy(floatBytes + 36, &yukseklik, 4); memcpy(floatBytes + 40, &basinc, 4); } void loop() { Serial.println("所有float的十六进制字节:"); for (int i = 0; i < 44; i++) { if (i % 4 == 0) Serial.print("\n"); // 每4字节换行,对应一个float if (floatBytes[i] < 0x10) Serial.print("0"); Serial.print(floatBytes[i], HEX); Serial.print(" "); } Serial.println("\n-------------------"); delay(1000); }
补充说明
- Arduino采用小端字节序,共用体中
bytes[0]是float的最低位字节,bytes[3]是最高位字节,可根据需求调整打印顺序。 - 如果需要将float的数值转为十六进制(如1.5转成十六进制数值),需先将float转为整数(比如乘以1000保留小数)再转换,但会丢失精度,需按需选择。
内容的提问来源于stack exchange,提问作者Eren Özden
相关产品推荐
相关产品推荐

