【问题标题】:Bitwise operators and converting an int to 2 bytes and back again按位运算符并将 int 转换为 2 个字节并再次返回
【发布时间】:2011-03-03 03:56:54
【问题描述】:

我的背景是 php,因此进入 char 等低级事物的世界是字节、位、二进制值等,需要一些时间才能掌握。

我在这里尝试做的是将一些值从 Ardunio 板发送到 openFrameWorks(都是 c++)。

当被要求发送数据时,此脚本当前的作用(并且适用于我可能添加的一个传感器)是:

int value_01 = analogRead(0);  // which outputs between 0-1024

 unsigned char val1;
 unsigned char val2;

//some Complicated bitshift operation           
    val1 = value_01 &0xFF;
    val2 = (value_01 >> 8) &0xFF;  
    
    //send both bytes
    Serial.print(val1, BYTE);
    Serial.print(val2, BYTE);

显然,这是获取数据的最可靠方法。 所以现在它是通过串口发送的,字节被添加到一个 char 字符串中并通过以下方式转换回来:

int num = ( (unsigned char)bytesReadString[1] << 8 | (unsigned char)bytesReadString[0] );

所以回顾一下,我试图获取 4 个传感器的数据(我假设这将是其中的 8 个串行打印?)并在这一切结束时拥有 int num_01 - num_04...。

我假设这(与大多数事情一样)对于有这些概念经验的人来说可能很容易。

【问题讨论】:

  • 从您的问题来看,尚不清楚您遇到了什么问题...如果上面的代码有效,那么您可以按照您的说法进行更多 Serial.print 操作并获得您的其他索引中的值到另一端的 bytesReadString 中。是什么不工作?

标签: c++ bit-manipulation arduino openframeworks


【解决方案1】:

编写一个函数来抽象发送数据(我已经摆脱了你的临时变量,因为它们没有增加太多价值):

void send16(int value)
{
    //send both bytes
    Serial.print(value & 0xFF, BYTE);
    Serial.print((value >> 8) & 0xFF, BYTE);
}

现在您可以轻松发送所需的任何数据:

send16(analogRead(0));
send16(analogRead(1));
...

【讨论】:

  • 哇,这清理得相当好.. 现在它工作得很好,谢谢大家!与我之前所拥有的(当它不工作时)相比,我真的不确定它为什么不工作(我想我可能一直在发送错误的数据,这让我很困惑).. 如果这是使用 stackoverflow 的结果,我会回来!
  • @aKiwi:感谢作者提供适合您需要的答案的最佳方式是将答案标记为已接受:)
  • 啊想知道该怎么做。谢谢,正试图投票给他(显然需要更多的声誉;)
【解决方案2】:

一个接一个地发送。

请注意,串行驱动程序允许您一次发送一个字节(8 位)。介于 0 和 1023 之间的值(看起来就像你得到的)适合 10 位。所以 1 个字节是不够的。 2 个字节,即 16 位就足够了(有一些额外的空间,但除非传输速度是一个问题,否则您无需担心浪费的空间)。

因此,前两个字节可以携带您的第一个传感器的数据。接下来的两个字节携带第二个传感器的数据,接下来的两个字节用于第三个传感器,最后两个字节用于最后一个传感器。

我建议你使用 R Samuel Klatchko 在发送端建议的功能,希望你能弄清楚你需要在接收端做什么。

【讨论】:

  • 非常感谢您提供有关连载方面的信息,让我头脑中的一些事情变得清晰起来。谢谢
【解决方案3】:
   int num = ( (unsigned char)bytesReadString[1] << 8 | 
               (unsigned char)bytesReadString[0] );

该代码不会像您期望的那样。

当您移动一个 8 位无符号字符时,您会丢失额外的位。

11111111 << 3 == 11111000

11111111 << 8 == 00000000

即任何无符号字符,当移位 8 位时,必须为零。

你需要更多这样的东西:

typedef unsigned uint;
typedef unsigned char uchar;

uint num = (static_cast<uint>(static_cast<uchar>(bytesReadString[1])) << 8 ) |
           static_cast<uint>(static_cast<uchar>(bytesReadString[0]));

您可能会得到相同的结果:

typedef unsigned short ushort;
uint num = *reinterpret_cast<ushort *>(bytesReadString);

如果字节顺序正常。应该适用于 Little Endian(x86 或 x64),但不适用于 Big Endian(PPC、Sparc、Alpha 等)

【讨论】:

    【解决方案4】:

    稍微概括一下“发送”代码 --

    void SendBuff(const void *pBuff, size_t nBytes)
    {
        const char *p = reinterpret_cast<const char *>(pBuff);
        for (size_t i=0; i<nBytes; i++)
            Serial.print(p[i], BYTE);
    }
    
    template <typename T>
    void Send(const T &t)
    {
        SendBuff(&t, sizeof(T));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-19
      • 2013-02-18
      • 1970-01-01
      • 2011-01-13
      • 2013-10-14
      • 2011-10-30
      • 2010-11-28
      • 2011-06-23
      相关资源
      最近更新 更多