【问题标题】:Sending Ints as bytes from arduino to C# program fails将整数作为字节从 arduino 发送到 C# 程序失败
【发布时间】:2013-11-29 17:35:06
【问题描述】:

我正在使用 VS2010 C# 编写一个程序。它有一个 GUI,用于通过串行端口与 Arduino 进行交互。

我遇到的问题是从 arduino 向程序发送大于 128(???) 的字节值。我在 arduino 上得到一个整数值,把它分成 highBite 和 lowByte,然后分别发送,在另一边重新组装。 如果我发送 600,它将发送 2 的 highByte 和 88 的 lowByte,并通过 bitshiting 正确重组为 600

如果我尝试发送应该是 188 和 2 的 700,那么我在 C# 中看到 188 显示为 63。为什么? 一个字节在 arduino 和 C# 上都应该是无符号的,所以我不确定出了什么问题。

Arduino 代码(相关部分):(0x43 向 C# 发出信号,它正在接收哪个数据包)

byte bytesToSend[3] = {0x43, byte(88), byte(2)}; // 600 broken down to high and low bytes
Serial.write(bytesToSend, 3); // send three bytes
Serial.println(); //send line break to terminate transmission

byte bytesToSend[3] = {0x43, byte(188), byte(2)}; // 700 broken down to high and low bytes
Serial.write(bytesToSend, 3); // send three bytes
Serial.println(); //send line break to terminate transmission

C# 代码:(相关部分 - 自从我剪切/修剪和粘贴后可能遗漏了一两个语法...)

string inString = "";
inString = port.ReadLine(); // read a line of data from the serial port
inString = inString.Trim(); //remove newline

byte[] buf = new byte[15]; // reserve space for incoming data
buf = System.Text.Encoding.ASCII.GetBytes(inString); //convert string to byte array I've tried a block copy here, but it didn't work either...

Console.Write("Data received: H: {0}, L: {1}. =", buf[2], buf[1]); //display high and low bytes
Console.WriteLine(Convert.ToUInt32((buf[2] << 8) + buf[1])); //display combined value

这就是我在串行监视器中写出值的地方:

Data received: H: 2, L: 88. = 600
Data received: H: 2, L: 63. = 575

低字节值在过程中的某处从 188 更改或错误解释为 63。是什么原因造成的,我该如何解决?当字节值低于 128 时似乎可以正常工作,但高于 128 时就不行了。

【问题讨论】:

  • 你为什么从端口读取数据为text?它不是文本 - 它是二进制数据。 (为什么要分配一个 15 字节数组然后忽略它?GetBytes 创建一个新数组。)

标签: c# serial-port arduino bytearray bit-shift


【解决方案1】:

我认为这可能是您的 c# 端代码的问题。您应该通过在 port.ReadLine() 之后打印您正在读取的字符串来调试它,以查看您收到的内容。

我还建议使用 C# Read(Byte[], Int32, Int32),以便将您的数据读入字节数组,它是无符号字符数组。 ReadLine() 正在将数据读入字符串(char 数组)。

【讨论】:

    【解决方案2】:

    您的编码错误。换行:

    buf = System.Text.Encoding.ASCII.GetBytes(inString);
    

    buf = System.Text.Encoding.GetEncoding("Windows-1252").GetBytes(inString);
    

    更好的是,当您实例化您的 Port 对象时,只需将 encoder 属性设置为这种类型。

    ...
    SerialPort port = new SerialPort();
    System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("Windows-1252");
    port.Encoding = encoder;
    ...
    

    请记住 ASCII 是 7 位的,因此您将截断大于十进制 127 的值。1252 编码是 8 位的,非常适合二进制数据。 at MSDN 显示的表格显示了对编码的完整符号支持。

    【讨论】:

      【解决方案3】:

      为什么,在 C# 中,读取完整的字符串 - 这将迫使您处理编码,... - 并进行后处理而不是及时解析?

      System.IO.BinaryReader bin_port=new System.IO.BinaryReader(port); //Use binary reader
      int b;
      int data16;
      b=bin_port.ReadByte();
      switch (b) {
      case 0x43: //Read integer
          data16=bin_port.ReadUInt16();
          while (bin_port.ReadByte()!=0x0a); //Discard all bytes until LF
          break;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-19
        • 2014-05-10
        • 2012-01-11
        • 2019-10-20
        • 1970-01-01
        • 2017-05-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多