串行端口的传入值有时已损坏或丢失



我在两个arduino nano v3板上编写了简单的蓝牙发射器和接收器。蓝牙模块是HM-10连接到硬件串行端口.它可以工作,但在接收器端,我经常收到损坏的值,并且缺少许多值。哪里有问题:

我是 arduino 的初学者。如果可能的话,需要深入解释。谢谢。

变送器代码:

const long waitingInterval = 20000;
unsigned long lastSend = micros();
void setup()
{
Serial.begin(19200);
Serial.println("Started");
}
bool delay() {
if(micros() >= lastSend + waitingInterval) {
lastSend = micros();
return true;
}
return false;
}
void loop()
{
if(delay()) {
String mil = String(millis());
String sendingText = mil + ";" + mil + ";" + mil + ".";
Serial.println(sendingText);
}
}

变送器串行监控接口输出:

10548;10548;10548.
10568;10568;10568.
10589;10589;10589.
10609;10609;10609.
10629;10629;10629.
10649;10649;10649.
10670;10670;10670.
10690;10690;10690.
10711;10711;10711.
10730;10730;10730.
10750;10750;10750.
10771;10771;10771.
10791;10791;10791.
10812;10812;10812.
10831;10831;10831.
10852;10852;10852.
10872;10872;10872.
10893;10893;10893.
10913;10913;10913.
10933;10933;10933.
10953;10953;10953.
10974;10974;10974.
10994;10994;10994.
11014;11014;11014.
11034;11034;11034.
11055;11055;11055.
11075;11075;11075.
11096;11096;11096.
11115;11115;11115.

接收方代码:


void setup() {
Serial.begin(19200);
Serial.println("Started");
}
void loop() {
if(Serial.available()) {
String incomingData = String();
char incomingChar = Serial.read();
if(incomingChar == '.') {
incomingData = bufferString;
Serial.print(bufferString);
bufferString = String();
} else {
bufferString += String(incomingChar);
return;
}
}

接收机串行监控接口输出:

10548;10548;10548
10568;10568;10568
10589;10589;10589
10609;10609;10609
10629;10629;10629
106410771
10791;10791;10791
10812;10812;10812
10831;10831;10831
10852;10852;10852
10872;10872;10872
10893;10893;11034;11034;11034
11055;11055;11055
11075;11075;11075
11096;11096;11096
11115;11115;11115

一个问题是简单地调用 Serial.available(( 只是返回缓冲区中可用读取的字节数;它可能正是您需要的字节数,也可能更少或更多。因此,您可能会读取额外的数据、太少或太多的数据。更重要的是,在更高级别的传输协议中,有时在设备收到数据后,它会向发送方发送一个ACK(确认(,表示它已准备好接收更多数据。

编辑**还应该注意的是,谈论互斥锁的评论是不正确的。互斥体通常用于在同一设备上跨多个执行线程同步代码。关键是它们是线程堆空间中的共享资源。使用两个不同的 arduino 设备时,情况并非如此;因此,即使您可以使用它们,它也毫无用处。

对于您的代码,我建议对发射器进行以下编辑:

#define MIN_TIMEOUT 3
void recieveAck(){
bool validAck = false;
uint8_t timeout_cnt = 0x00;
while(timeout_cnt < MIN_TIMEOUT){
//Wait for receiving device to respond with two bytes then send next
char incomingBytes[2];
Serial.readBytes(incomingBytes, 0x02);
if(incomingBytes[0] == 0xBB && incomingBytes[1] == 0xCC)
break;
timeout_cnt++;
}
}
void loop()
{
if(delay()) {
String mil = String(millis());
String sendingText = mil + ";" + mil + ";" + mil + ".";
Serial.println(sendingText);
recieveAck();
}
}

对接收者:

#define NEXT_INC_SIZE 2 //Expects one byte at a time
void sendAck(){
char outData[2];
outData[0] = 0xBB;
outData[1] = 0xCC;
Serial.write(outData, 2); //Write the ack data
}
void loop() {
if(Serial.available() >= NEXT_INC_SIZE){
char incomingBytes[2];
Serial.readByte(incomingBytes, NEXT_INC_SIZE); //Read exactly how many bytes you need
//Do stuff with the data here....
sendAck();
}
}

最新更新