python - 使用结构将浮点数从 Arduino 发送到 Python
问题描述
我正在使用 Bluefruit Feather 通过 BLEUART 将信息从温度传感器发送到计算机上的 Python 脚本。
我有一个用于加速度计的代码的工作版本,唯一的区别是发送的信息是 4 个整数(对于加速度计:x、y、z、id),而温度传感器是 2 个浮点数(温度、浮点 id) . 我检查了传感器通过串行监视器发送的值,它们是正确的。当浮点数在 Python 中解包时会出现问题:它们是大约1.36*e-45
关闭的一个因素。
在这两种情况下,我都将变量存储在一个结构中并通过 BLE 发送这个结构。羽毛代码如下所示:
void sendData(){
int numVals = 2;
int vals[numVals];
vals[0] = temp;
vals[1] = id; //1.0
Serial.println(temp);
Serial.println(id);
int cnt = numVals * sizeof(float) ;
uint8_t buf[cnt];
for (int _i=0; _i<numVals; _i++)
memcpy(&buf[_i*sizeof(float)], &vals[_i], sizeof(float));
bleuart.write( buf, cnt );
}
在 Python 端,它看起来像:
def received(data):
floats = struct.unpack('ff', data)
print('Received:', floats)
这真的很神秘!我觉得这与浮点数在 C 和 Python 之间的表示方式有关,但尝试将值更改为双精度/无符号长整数,但它要么崩溃,要么有类似问题。
解决方案
您提出的问题实际上是一个更广泛的问题,关于对象如何在不同的操作系统、机器架构、不同的编译器等下进行序列化和反序列化。
具体应该注意:
- 结构如何映射到物理内存 - 不能保证您的结构占用内存中可能的最小空间。事实上,编译器很可能会在字段之间引入间隙,以优化内存访问速度(参见这个 SO question)。
- machine Endianess,这是多字节基元(例如浮点数)在内存中存储的顺序
要解决您的问题,您可以设计自己的方案(例如,将编译器配置为在内存中紧密打包结构 - 请参阅 gcc 的packed
属性),并始终将浮点数编码为大端。更好的是,您可以使用跨语言、跨平台、跨任何东西的框架(例如 Google 的协议缓冲区)来为您处理序列化。
就个人而言,我会选择选项 II,即使它引入了一些开销。
推荐阅读
- c++ - 循环中的自动变量和自动对象内存分配
- julia - 是否有一个方便的函数来计算 GLM.jl 的 lm 的 R^2?
- java - 基于数据的 RESTful shiro 权限
- mysql - 如何预处理使用 sqlx 获取的行?
- c# - 如何使用 sql server 身份验证模式从 .NET Webapi 执行 SSIS 包?
- javascript - 为什么 content.js 只执行最后一个命令
- javascript - 选择下拉选项后Laravel重复视图
- android - 如何仅通过 wifi 强制互联网连接?
- javascript - 设置多个`' 使用变量值的字段
- php - 我在我的代码中使用 Stripe API,但出现错误:您不能多次使用 Stripe 令牌:tok_1EIw1gKIAV9zC39qQnFXKzi6