【问题标题】:Converting 3 shuffled bytes to two 12bit Integers in C#在 C# 中将 3 个混洗字节转换为两个 12 位整数
【发布时间】:2019-02-21 16:05:09
【问题描述】:

我正在尝试使用 C# 从串行端口读取数据。

整数或浮点数和布尔值的普通字节不是问题。 但是,有一个 3 个字节的序列被打乱了,我无法正确解析它。

这 3 个字节代表 2 个无符号 12 位整数,一个用于 MainSupplyDC,一个用于 Motor Power。 它们以需要在解析之前重新排序的方式进行混洗。

我上次的尝试以这样的方式结束,但现在我再次意识到这不可能是正确的。

    // Main Supply DC
    int MainSupplyDCval = (byte2 >> 4 | byte1);

    // MotorPower
    int MotorPowerVal = (byte3 << 4 | byte2);

我不知道如何正确地转换它。

这是字节序列布局:

文本相同:

    Byte1    |         Byte2            |    Byte3
------------------------------------------------------
  Lowbyte    |  4 Lowbit | 4 Highbit    |   Highbyte
MainSupplyDC | MotorPower| MainSupplyDC |  MotorPower

字节序列示例:

E5-00-00
MainSupplyDC expected around 230
MotorPower expected 0

E4-A0-06
MainSupplyDC expected around 230
MotorPower expected about 97

E5-90-0F
MainSupplyDC expected around 230
MotorPower expected about 190

2 天以来一直在敲我的头,只是无法让它工作......

编辑

似乎有两种方法可以解释给定的表格。就我而言,@canton7 有正确的答案,但我认为如果供应商/制造商以另一种方式编码,@dumetrulo 将有正确的答案。

【问题讨论】:

  • 您是否有示例输入和相应的输出,以便我们判断何时正确?
  • 我用 3 字节序列和预期结果扩展了示例部分
  • 当 byte2 的 4 个低位假定为 MainSupplyDC 值的第 8..12 位(或但 7. .11,如果您更喜欢从零开始的位位置)?如果您在纸上可视化整个位移的东西(也许图形化为图表),这可能是一个好主意;它可以帮助您相对轻松地弄清楚如何在不丢失的情况下移动和组合字节......
  • 在您的示例中“E5-00-00”电机功率如何 18?没有设置电机功率位总是导致 0
  • 没错,这种情况会导致 0。

标签: c# arrays serial-port byte bit


【解决方案1】:

我猜这两个 12 位值有这种结构?

MainSupplyDC (low byte) | MainSupplyDC (4 Highbit)
MotorPower (4 lowbit) | MotorPower (Highbyte)

在这种情况下:

var bytes = new byte[] { 0xE4, 0xA0, 0x06 };
int mainSupplyDc = bytes[0] | ((bytes[1] & 0x0F) << 8);
int motorPower = (bytes[1] >> 4) | (bytes[2] << 4);
Console.WriteLine("MainSupplyDC: {0}, MotorPower: {1}", mainSupplyDc, motorPower);

打印:

MainSupplyDC: 228, MotorPower: 106

这样看起来对吗?

【讨论】:

  • 我试过你的解决方案,值似乎是正确的。谢谢!我会将其标记为已解决。
  • 也看看@dumetrulo 的回答——他在做不同的数学,得到的结果略有不同
  • 是的,我刚刚意识到这一点。我将不得不更深入地挖掘哪些价值观是正确的并进行报告。
  • 我仔细检查了一下,这些值似乎在预期范围内。 Dumetrulo 的答案产生了类似的结果,但是您的答案的值更接近我应该拥有的值,因此我将其保留为正确答案。我认为这最终取决于位布局,如果我理解正确,给我的表格并不是 100% 清楚地说明如何读取这些值。
【解决方案2】:

如果我正确阅读了表格,以下方法应该可以解决问题:

public static (int, int)
Get12BitValues(byte d1, byte d2, byte d3) =>
    ((int)d1 | ((int)d2 >> 4),
    ((int)d3 << 4) | ((int)d2 & 0x0f));

那么你的两个值会得到如下:

var (v1, v2) = Get12BitValues(byte1, byte2, byte3);
float MainSupplyDCval = (float)v1 / 10.0f;
float MotorPowerVal = (float)v2 / 10.0f;

【讨论】:

  • 谢谢,我认为您的解决方案也有效,但我被困在较旧的 C# 版本上,所以我不得不接受 canton7 的回答。
  • @Heilandzack 我认为这与我的解决方案不同 - 它们产生相似的结果,并且它们都基于同一张表,但我认为它们不一样.在决定哪个是正确的之前,您可能希望将它们与其他输入/输出值进行检查。
  • 对于 MainPowerSupply,如何将 D2 4 位向右移动产生 12 位值的位 7..11?这是什么魔法?
  • @elgonzo 你是对的,这不可能是对的。
  • 从 d2 的低 4 位中提取 MotorPowerVal 位肯定也是错误的吗?该表说它是高 4 位
猜你喜欢
  • 2011-12-27
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
  • 2018-12-01
相关资源
最近更新 更多