我在两个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
答案 0 :(得分:1)
一个问题就是简单地调用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();
}
}