串口接收问题请指教
apMac=00:15:6D:04:BB:2EwlanOpmode=sta
wlanConnections=1
wlanUptime=996
essid=WJ4G
freq=2482
signal=-58
noise=-93
ccq=940
uptime=334028
loadavg=0
memTotal=29524
memFree=11584
memBuffers=1800
ackTimeout=25
distance=600
lanIpAddress=0.0.0.0
wlanIpAddress=0.0.0.0
wlanTxRate=58.5
wlanRxRate=58.5
wlanTxLatency=1
wlanPolling=1
wlanPollingQuality=85
wlanPollingCapacity=39
lanRxBytes=71908224
lanRxPackets=548976
lanRxErrors=0
lanTxBytes=447911534
lanTxPackets=899527
lanTxErrors=0
lanPlugged=1
lanSpeed=100Mbps-Full
wlanRxBytes=3950840
wlanRxPackets=6281
wlanRxErrors=0
wlanTxBytes=1964354
wlanTxPackets=10427
wlanTxErrors=1
wlanRxErrNwid=0
wlanRxErrCrypt=0
wlanRxErrFrag=0
wlanRxErrRetries=0
wlanRxErrBmiss=0
wlanRxErrOther=0
latitude=0.000000
longitude=0.000000
cfgCrc=d356978d
XM.v5.5.6#
上面就是每隔一定周期从通信模块接收的数据,而且每次都要全部接收,因为是通信模块打包发过来的,但我只用到signal=-xx这一项。
今天我问道您串口缓存一次能存多少字节的问题,因为我发现对于每次发过来的这么多数据使用不同的程序,得到的结果不同。
#include <Servo.h>
Servo myservo1;
Servo myservo2;
int pos1 = 90;
int pos2 = 90;
String comdata = "";
String comdata1 = "";
int rssi=0,lastrssi=0;
int mark = 0;
void setup()
{
Serial.begin(9600);
comdata.reserve(188);// reserve 188 bytes
myservo1.attach(10);
myservo2.attach(11);
myservo1.write(pos1);
myservo2.write(pos2);
}
void loop()
{
//int j = 0;
while (Serial.available() > 0)
{
comdata += char(Serial.read());
delay(8);
mark = 1;
}
if(mark == 0) return; // no data
if(mark == 1)
{
lastrssi=rssi;
int sIndex = comdata.indexOf("signal=-");
if(sIndex==-1)
{
mark = 0;
return;
}
String charRssi=comdata.substring(sIndex+8,sIndex+10);
rssi=charRssi.toInt();
Serial.println(rssi);
Serial.println(lastrssi);
comdata = String("");
Serial.flush();
mark = 0;
}
if(lastrssi!=0)
{
if(rssi>lastrssi)Serial.println("you");
if(rssi<lastrssi)Serial.println("zuo");
}
}
这是我今天的程序,利用OpenJumper™ Serial Assistant 1.3.6进行接收测试时没有任何显示,是不是通信痛快发来的数据太多,字符串放不下,所以没成功?但是我利用昨天的程序
String comdata = "";
int mark = 0;
void setup()
{
Serial.begin(9600);
while (!Serial);
}
void loop()
{
int j = 0;
while (Serial.available() > 0)
{
comdata += char(Serial.read());
delay(2);
mark = 1;
}
if(mark == 1)
{
int sIndex = comdata.indexOf("signal=-");
if(sIndex==-1){
return;
}
String rssi=comdata.substring(sIndex+8,sIndex+10);
Serial.println(rssi.toInt());
}
comdata = String("");
mark = 0;Serial.flush();
}
用这个程序就接收成功了,接收到了58,前辈,您知道这是为什么么?十分感谢!
不知道程序哪里出了问题,可以通过分段调试的方式,找出问题的原因。
本帖最后由 Super169 于 2015-1-14 00:36 编辑
這麼大的數據包, 時間上要控制得準確, 不容易.
arduino 的串口庫, 預設只有 64 個 byte 的 buffer, 如果不能及時處理, 很快要滿了.
你這裡的數據, 有數百個 byte, 一次過傳送出來, 必須及時處理, 太困難了.
如果你的程序不太大, 考慮把 serial 的 buffer 改成 1KB 吧, 讓它有足夠空間存放, 然後盡快處理好, 準備下一次傳送.
又或是每次接收完一個 byte 不做 delay, 在預知未完結時直接等待下一個 byte.
把 delay(2); 改為 while (!Serial.available()); 去等待下一個 byte, 然後直接處理.
當然, 這樣做要有明確的完成碼, 或其他完結的訊號.否則可以永遠只會不停地讀取數據.
但就可以省去 buffer 既消耗, 對大的數據包比較可行. Super169 发表于 2015-1-14 00:31 static/image/common/back.gif
這麼大的數據包, 時間上要控制得準確, 不容易.
arduino 的串口庫, 預設只有 64 個 byte 的 buffer, 如果不 ...
嗯嗯,测试发现arduino一次是可以接收到那么多信息的,但必须是delay(2),如果改为delay(4)或delay(8)就都不行了,不知道是为什么 毒师老白 发表于 2015-1-14 14:10 static/image/common/back.gif
嗯嗯,测试发现arduino一次是可以接收到那么多信息的,但必须是delay(2),如果改为delay(4)或delay(8)就都 ...
這就是時間上的問題.
你用的是 9600 bps, 發放一個 Byte, 在沒有 overhead 情況下, 大約是 8/9600 約 1 ms.
在接收了一個 byte 後加入 delay, 就是想把連續送來的資料一次過接收, 等待時間略比所需時間長一點就最好.避免因為下一個 byte 未送到, 而出現 Serial.available() 為 false.
細看一次你的程式, 原來已用了"signal=-" 作完成碼判斷, 資料可以分段接收, 而非要一次性接收.基本上 buffer 的問題可解決, 只是每次接收的長度可以會不同.
但另一個問題是 "signal=-" 並非資料的最尾, 當已接收了 "signal=-" 的一句後, 除非處理速度接近發送時間, 否則資料會被分斷, 未完全接收好就會嘗試放出來.不過, 你又用了最少 2ms 的 delay, 會變成分段接收的機會不大.
至於 delay(4) 及 delay(8), 有可能是處理速度太慢了, 每讀取一個 byte 就要等一段長時間, 幾乎是發送三個才處理一個.同一個 while loop 內已可以令 buffer 滿了.
由於你已用了 完成碼的判斷 (只是選擇的不太好), 反正不需要一次過完全讀取, 當中的 delay 意義就不大了, 太長反而令接收太慢而出問題.
而 delay(2) 也存在處理太慢的隱憂, 我也不太肯定, 為何你可以沒事.試想想, 每 1ms 發一個 byte, 你每接一個就等 2ms.你將用了 200 ms 等待時間 去接收 100 個 byte, 但 200ms 的時間, 對方已可以發送出 200 個 byte 了, 當中 100 個 byte 要放進 buffer, 我也不明白為何你可以沒問題, 難道是發送的時間也有 1ms 的 overhead?
建議改為 delay(1) (本來可以甚至取消 delay, 但又怕會出現使用 string function 太頻密的問題, comdata.substring 有一定的 overhead, 所以 delay(1) 可能更理想), 而 完成碼改為 "XM.5.5.6#" (這看似是最後結束的資料吧).可能會更有效率.
Super169 发表于 2015-1-14 14:44 static/image/common/back.gif
這就是時間上的問題.
你用的是 9600 bps, 發放一個 Byte, 在沒有 overhead 情況下, 大約是 8/9600 約...
真的是很详细,太感谢你了!
现在遇到了一个问题,我想通过RSSI的比较来控制舵机,比如说开始令舵机右转10度,接收一次signal=-xx,对当前时刻的与上一时刻的进行比较,如果大于则使舵机继续向右转10度,如果小于,则令舵机1转回到初始位置后再向左转10度,没运动一次,比较一次信号值,然后向信号大的方向转10度,因为通信通信模块的位置是在变化的,会引起signal的变化,我设计的舵机云台就是想去跟踪signal的极大值。
我看了下关于arduino的servo库,没有类似的控制程序,希望您能给点思路
页:
[1]