首页 > 解决方案 > 如何通过蓝牙低功耗从 %8.5f 类型向我的 android 应用程序发送两个字节的浮点数

问题描述

我尝试将传感器数据从 stm32wb55 连续发送到我自己的 android 应用程序。我从加速度传感器接收两个字节,并在我的 stm32wb55 上将它们正确转换为具有格式的浮点数(XX.XXXXX,浮点数可以是负数)。

现在我想将这个浮点数准确地发送到我自己的 android 应用程序。

之前,我已经从类型“int 或 uint”向我的 android 应用程序发送了两个字节,并尝试以我在 stm32wb55 上已经完成的相同方式进行转换。但是我屏幕上的值高达 50% 的情况是错误的。所以现在我尝试直接发送浮点值,这样就不需要在我的手机上进行更多的转换了。


编辑:在您的贡献之后,我忘记了向我的 android 应用程序发送浮点数的坏主意。我再次尝试发送两个字节整数并在我的应用程序上以正确的方式转换它们。现在它应该如何工作。我在这篇文章中找到了我需要的解决方案:2 Chars to Short in C。通过将这两个字节组合成一个 16 位整数,我只需要0x00ff &我的 LSB,就像它在引用帖子的答案中使用一样。

标签: javaandroidcstm32

解决方案


格式为浮点数(XX.XXXXX,浮点数可以为负数)。

这是不可能的。

floats 是一个 32 位 IEEE754 浮点数。他们不像你(显然)认为他们那样工作

具体来说,它们是带有尾数系统的二进制结构。我将尝试解释为什么它不像您认为的那样工作:十进制的 1/3 是多少?您会发现无论您使用多少“位”(数字),都无法将其写成十进制。你永远不会完全明白。总是有另外 3 个要添加。

浮点的工作方式相同,但它是二进制(以 2 为底)而不是十进制(以 10 为底)。这意味着有些数字在十进制中效果很好(例如 1/10,在十进制中是 0.1,具有完美的精度)但在二进制中就像 1/3:无论你使用多少位,你永远不会得到它.

这是另一种思考方式:32 位,因此,只有 2^32(约 40 亿)个不同的值。换句话说,在所有存在的数字中(并且它们有无穷无尽:有无穷大的数字,并且在任意两个连续的数字中,还有另一个无穷大的数字),最多只有 40 亿得到祝福:所有的 40 亿存在的数字可以用浮点值表示。如果你试图用浮点数表示一个没有祝福的数字,那么 java / 你的 CPU 只会将它四舍五入到最接近的祝福数字,并且没有给你真正的机会来处理错误(毕竟,你将如何表示错误?它也不太可能被祝福)。

因此,比如说,“12.34567”?这不是一个幸运的数字 - 因此,您的浮点数不可能代表这一点。相反,它将是一个非常接近它的数字,如果你将它四舍五入到 5 位,它可能会四舍五入到 12.34567。

将这个浮点数准确地发送到我自己的 android 应用程序。

所以,不,你不想那样做。您想将 12.34567 发送到您的 android 应用程序,而不是代表它的 32 位。除非您打算让应用程序的 android 端进行舍入,否则您可能应该这样做。请注意,我敢打赌,有些数字符合“XX.YYYYY”模式,但不能作为浮点数“工作”(它们四舍五入,使您偏离 1)。如果这是一个问题,请不要使用浮点数(在我怀疑你会发现没有祝福数字的 XX.YYYYY 时使用双精度数,以便由于有更多位可以使用而正确舍入,或者使用字符串,或者使用 2 个 int,或者使用单个 int,并且有约定双方都知道 int 1234567 代表 12.34567)。

最后一个听起来对你来说是最方便的技巧,但很难说,因为你没有提供太多细节。

类似的东西(但请注意,浮动可能会偏离 1 左右!):

发送方:

double v = theFloat; // doubles have less error
int z = (int) (v * 100000);
sendToPhone(z);

接收方:

int z = getFromDevice();
double v = z;
v /= 100000;
float theFloat = (float) v;

以上将自动舍入(正数向下舍入,负数向上舍入)浮点数超出您想要的 5 之后的任何数字),并且可以处理高达正负 21473.99999 的数字。听起来这很容易满足您的需求。

注意:您必须为您的 stm32wb55 编写“乘以 100000 然后转换为 int32”代码,以上是如果 stm32wb55 是用 java 编程的,您将如何编写它,我认为它不是. '在乘以 100000 之前加倍可能是一个无关紧要的优化,如果你不能这样做,我不会太担心。请注意,CPU 不能保证对浮点数/双精度数使用与 java 完全相同的 IEEE754 表示形式,这就是为什么您绝对不应该尝试通过蓝牙通道将值作为浮点数/双精度数发送,但正如普遍同意的那样,例如“一个 2 的补码 32 位整数值”。


推荐阅读