如何在树莓派3B上通过I2C从Arduino从机读取浮点值(C语言)
解决树莓派WiringPi读取Arduino发送的float变量问题
我来帮你搞定这个问题!你已经走对了第一步——Arduino那边把float转成4字节数组发送的代码是正确的,问题出在树莓派这边只读取了1个字节,而float需要4个字节才能完整还原。下面给你两种可行的解决方案:
方案一:直接读取4字节并转换为float
因为WiringPi的wiringPiI2CRead()每次只能读取1个字节,所以我们需要循环读取4次,把所有字节存到缓冲区,再通过C语言的类型转换还原成float。
树莓派端C代码示例
#include <wiringPiI2C.h> #include <stdint.h> #include <string.h> int main() { int fd; wiringPiSetup(); fd = wiringPiI2CSetup(0x04); // 你的Arduino从机地址 uint8_t floatBytes[4]; // 循环读取4个字节,对应float的4个字节长度 for (int i = 0; i < 4; i++) { floatBytes[i] = wiringPiI2CRead(fd); } // 方法1:使用union进行类型转换(更安全直观) union { uint8_t bytes[4]; float value; } floatConverter; memcpy(floatConverter.bytes, floatBytes, 4); float result = floatConverter.value; // 方法2:直接通过指针强制转换(更简洁) // float result = *(float*)floatBytes; // 这里可以把result显示到LCD或者做其他处理 // ui->lcdNumber->display(result); // 注意LCD可能需要格式化输出 return 0; }
关键注意点
- Arduino和树莓派的float都是4字节IEEE754单精度浮点数,且两者都是小端字节序(AVR和ARM架构默认小端),所以不需要额外处理字节顺序,直接转换即可。
- 确保Arduino的I2C从机逻辑正确:需要在
setup()中注册onRequest回调,让树莓派发起读取请求时自动发送数据,比如:float floatNumber = 123.45; // 你的目标变量 void setup() { Wire.begin(0x04); Wire.onRequest(sendData); // 注册请求回调 } void sendData() { Wire.write((byte*)&floatNumber, 4); }
方案二:放大浮点值为整数后传输(适合对浮点转换敏感的场景)
如果担心浮点直接转换的兼容性,你可以把float放大为整数(比如乘以100保留两位小数),拆成多字节发送,树莓派端再还原。这种方式也能解决“数值超过255无法发送”的问题。
Arduino端代码调整
float floatNumber = 123.45; void sendData() { // 放大100倍转为32位整数,避免溢出(如果数值更大可以调整倍数或用64位整数) int32_t scaledValue = (int32_t)(floatNumber * 100); Wire.write((byte*)&scaledValue, 4); // 发送4字节整数 }
树莓派端还原代码
#include <wiringPiI2C.h> #include <stdint.h> int main() { int fd; wiringPiSetup(); fd = wiringPiI2CSetup(0x04); uint8_t intBytes[4]; for (int i = 0; i < 4; i++) { intBytes[i] = wiringPiI2CRead(fd); } // 转换为32位整数 int32_t scaledValue = *(int32_t*)intBytes; // 还原为浮点值 float result = scaledValue / 100.0; // 后续处理逻辑 return 0; }
关键注意点
- 选择合适的放大倍数:比如需要保留一位小数就乘10,三位乘1000,同时要确保放大后的数值不超过所选整数类型的范围(比如
int32_t最大能到2147483647)。 - 如果数值特别大,可以改用
int64_t(8字节),对应Arduino端也用int64_t类型,发送8字节即可。
两种方案都能解决你的问题,推荐先试试方案一,更直接省心。如果遇到字节序相关的问题(概率极低),再考虑手动调整字节顺序。
内容的提问来源于stack exchange,提问作者VapeKop
相关产品推荐
相关产品推荐

