我有一个连接了Bluesmirf Silver模块的Arduino Uno。我的Arduino有一个温度传感器,可以定期记录温度。 Arduino会侦听通过蓝牙发送给它的任何字符串,并使用最新数据进行响应。
我已经编写了一个C#应用程序来获取这些数据,但我看到了一些奇怪的行为。我使用以下代码进行连接,发送字符串并获取返回的数据。
mPort = new SerialPort(mPortName, 115200, Parity.None, 8, StopBits.One);
mPort.Open();
mPort.Write("download");
Thread.Sleep(1000);
while (mPort.BytesToRead > 0)
{
String data = mPort.ReadExisting();
this.BeginInvoke(new Action<String>(AddMessage), data);
}
我得到的数据如下:
在C#应用程序中本地添加的行:
Send: download
根据从Arduino收到的数据添加的行:
Read: d???+?
GotData
------
Total Readings, 1069
Num Readings, 360
Lost Readings, 709
Reading Interval, 240000
------
350,19.34
351,19.34
352,19.34
353,20.31
....
除了我发送给Arduino的回传字符串外,所有文本看起来都很好。我发送数据的方式有问题吗?
仅供参考 - 蓝牙模块的数据表如下:http://www.sparkfun.com/datasheets/Wireless/Bluetooth/rn-bluetooth-um.pdf
@Jeff - 这是我在Arduino上用来接收数据的代码:https://github.com/mchr3k/arduino/blob/master/tempsensor/StringReader.cpp
@Jeff - stringDataLen定义长度,我从这个文件调用整个函数:https://github.com/mchr3k/arduino/blob/master/tempsensor/tempsensor.ino
编辑:这是完整的源代码
由于某种原因,C#代码肯定会使流控制错误。我已经切换到在C#中使用以下代码,这会得到一个没有损坏的字符串。
private void write(SerialPort mPort, string str)
{
foreach (char c in str)
{
mPort.Write(new char[] {c}, 0, 1);
Thread.Sleep(10);
}
}
答案 0 :(得分:1)
编码错误?
mPort = new SerialPort(mPortName, 115200, Parity.None, 8, StopBits.One);
mPort.Encoding = System.Text.Encoding.ASCII; // Or System.Text.Encoding.UTF8
mPort.Open();
mPort.Write("download");
逐字节读取并逐个检查每个字节以调试较低级别的问题。 ReadExisting()
根据String
属性将字节转换为Encoding
。
答案 1 :(得分:0)
我的问题是由于我使用SoftwareSerial类与引脚2和2上的蓝牙模块进行通信而引起的。 3.我使用的波特率为115200声称此页面支持:http://arduino.cc/en/Reference/SoftwareSerial
然而,这个页面(http://arduino.cc/en/Reference/SoftwareSerialBegin)表明支持的最大波特率实际上是9600.我不确定这是否准确但是将波特率降低到9600已经解决了我的问题。
答案 2 :(得分:-2)
我建议你降低通信速度,因为没有理由使用115200bps(只有你的模块要求这个速度,那就没关系)。你也发送字符串“下载”,这是不好的,而是使用类似“#D”的标记,在你的Arduino设备内部意味着,将数据发送到计算机。通过这种方式,您只发送两个字节而不是八个,并且您将降低错误概率,并且Arduino代码将更好。
现在,让我们尝试解决问题。当您从Arduino设备读取数据时,首先尝试使用类似的东西:
ArayList dataReceaved=new ArrayList():
while(serialPort.BytesToRead>0 && serialPort.IsOpen){
dataReceaved.Add(serialPort.ReadByte());
}
所以我建议你以这种或类似的方式逐字节读取。如果你从Arduino设备发送号码,你也要小心。如果你是,那么使用这样的东西:
Serial.print(temperatureValue,BYTE);
使用此代码,您明确表示您发送的数据是字节长。如果这没有帮助,请告诉我,我们可以尝试别的。