python - 使用结构将 float 从 Arduino 发送到 Python

标签 python c arduino bluetooth-lowenergy

我正在使用 Bluefruit Feather 通过 BLEUART 将信息从温度传感器发送到计算机上的 Python 脚本。

我有一个用于加速度计的代码的工作版本,唯一的区别是发送的信息是 4 个整数(对于加速度计:x、y、z、id),而对于温度传感器则有 2 个 float (temp、 float ID)。我已经检查了传感器通过串行监视器发送的值,它们是正确的。当在 Python 中解压浮点时,就会出现问题:它们大约相差 1.36*e-45 倍。

在这两种情况下,我都将变量存储在一个结构中,并通过 BLE 发送该结构。 Feather 代码如下所示:

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 之间 float 的表示方式有关,但尝试将值更改为 double /无符号长整型,但它要么崩溃,要么有类似的问题。

最佳答案

您提出的问题实际上是一个更广泛的问题,涉及对象在不同操作系统、机器架构、不同编译器等下如何序列化和反序列化。

具体应注意:

  • 结构如何映射到物理内存 - 不能保证您的结构占用内存中尽可能小的空间。事实上,编译器很可能会在字段之间引入间隙,以优化内存访问速度(请参阅 this SO question )。
  • 机器Endianess ,这是多字节基元(例如 float )在内存中存储的顺序

要解决您的问题,您可以设计自己的方案(例如,配置编译器以紧密打包内存中的结构 - 请参阅 gcc 的 packed 属性),并始终将 float 编码为大端字节序。更好的是,您可以使用诸如 Google 的 protocol buffers 之类的框架。它是跨语言、跨平台、跨任何东西来为您处理序列化的。

就我个人而言,我会选择选项 II,尽管它会带来一些开销。

关于python - 使用结构将 float 从 Arduino 发送到 Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58308581/

相关文章:

Python 通过蓝牙与 Arduino 通信

python - 大型嵌套列表与字典

c - C 中的稀疏矩阵乘法

python - AttributeError : dlsym(0x7fe512579830, EVP_CIPHER_CTX_reset): 找不到符号

c - C语言从文件读取输入

c++ - 是否有一个 GNU C 编译器选项可以生成运行速度比默认设置更快但精度更低的浮点程序?

c - 如何在arduino中创建嵌套对象JSON

memory-management - 检查 Arduino 中的内存占用

python - 如何在不使用 IDE 的情况下在 Python 中轻松找到类的 namespace ?

python - 如何在列表中附加最接近的值