从Arduino到C#程序将字节作为字节发送失败

时间:2013-11-29 17:35:07

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

我正在研究VS2010 C#中的程序。它有一个GUI,用于通过串口与Arduino进行交互。

我遇到的问题是从arduino向程序发送大于128(???)的字节值。我在arduino上得到一个整数值,将其分解为highBite和lowByte,然后发送每个值,重新组合在另一侧。 如果我发送600,它将发送2的highByte和88的lowByte,并通过bitHiting<< 8 of highByte正确地重新组装到600.

如果我尝试发送700应该是188和2,那么我看到在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时,它似乎不能正常工作。

3 个答案:

答案 0 :(得分:0)

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

我还建议使用C#Read(Byte [],Int32,Int32),以便将数据读入Byte Array,这是一个unsigned char数组。 ReadLine()将数据读入字符串(char数组)。

答案 1 :(得分:0)

您的编码错误。更改以下行:

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显示了对编码的完整符号支持。

答案 2 :(得分:0)

为什么,在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;
}