我有一个arduino,在串行端口上发送一些通过类似引脚揭示的信息。无论如何,在Arduino代码(我无法修改)中,使用Serial.write()
而不是Serial.print()
,以打印char
的缓冲区。结果,如果在我的C#软件中,我使用"简单" ReadLine()
读取信息,则数据是无法理解的。如何使用C#读取此类数据?
这是Arduino代码:
#include <compat/deprecated.h>
#include <FlexiTimer2.h>
#define TIMER2VAL (1024/256) // 256Hz - frequency
volatile unsigned char myBuff[8];
volatile unsigned char c=0;
volatile unsigned int myRead=0;
volatile unsigned char mych=0;
volatile unsigned char i;
void setup() {
pinMode(9, OUTPUT);
noInterrupts();
myBuff[0] = 0xa5; //START 0
myBuff[1] = 0x5a; //START 1
myBuff[2] = 2; //myInformation
myBuff[3] = 0; //COUNTER
myBuff[4] = 0x02; //CH1 HB
myBuff[5] = 0x00; //CH1 LB
myBuff[6] = 0x02; //CH2 HB
myBuff[7] = 0x00; //CH2 LB
myBuff[8] = 0x01; //END
FlexiTimer2::set(TIMER2VAL, Timer2);
FlexiTimer2::start();
Serial.begin(57600);
interrupts();
}
void Timer2()
{
for(mych=0;mych<2;mych++){
myRead= analogRead(mych);
myBuff[4+mych] = ((unsigned char)((myRead & 0xFF00) >> 8)); // Write HB
myBuff[5+mych] = ((unsigned char)(myRead & 0x00FF)); // Write LB
}
// SEND
for(i=0;i<8;i++){
Serial.write(myBuff[i]);
}
myBuff[3]++;
}
void loop() {
__asm__ __volatile__ ("sleep");
}
这是从串行端口读取的C#方法
public void StartRead()
{
msp.Open(); //Open the serial port
while (!t_suspend)
{
i++;
String r = msp.ReadLine();
Console.WriteLine(i + ": " + r);
}
}
编辑:我将作为输出一个与Arduino输出数据相对应的string
数组。如果我将所有内容记录为字节数组,那么我就没有有关启动和数组结束的信息。我可以编辑代码为:
public void StartRead()
{
msp.Open(); //Open the serial port
ASCIIEncoding ascii = new ASCIIEncoding();
while (!t_suspend)
{
i++;
int r = msp.ReadByte();
String s = ascii.getString((byte)r); // here there is an error, it require an array byte[] and not a single byte
Console.WriteLine(i + ": " + r);
}
}
考虑到启动值是每次0xa5,而结束为0x01。
arduino发送几个字节的电报。您可以将其读取为字节数组:
byte[] telegram = byte[msp.BytesToRead];
msp.Read(telegram, 0, msp.BytesToRead);
要从字节数组中获取数据,您必须解释字节(请参见下面的示例)。当然,您可以从Telegram
类的属性创建一个字符串:
class Telegram {
public Telegram(byte[] tel) {
// Check start bytes ( 0xa5, 0x5a );
Info = tel[2];
Counter = tel[3];
Channel1 = BitConverter.ToInt16(new byte[] { tel[5], tel[4] }, 0); // Switch lo/hi byte
Channel2 = BitConverter.ToInt16(new byte[] { tel[7], tel[6] }, 0);// Switch lo/hi byte
// check tel[8] == 1 for end of telegram
}
public int Info { get; private set; }
public int Counter { get; private set; }
public int Channel1 { get; private set; }
public int Channel2 { get; private set; }
}