我们正在开发一个应用程序,它使用蓝牙库通过HC-05模块与蓝牙的Arduino进行通信。我们制作了一个虚拟配置来测试延迟而不需要任何计算来收集Arduino或应用程序,我们在请求和答案之间有大约1秒的延迟...
协议看起来很简单:Android发送字节-2,如果收到的字节是-2,Arduino一次又一次地发送-6,-9和Android回答。
Android代码:
h = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case RECIEVE_MESSAGE: // if receive massage
byte[] readBuf = (byte[]) msg.obj;
for(int i=0;i < readBuf.length;i++)
{
if((int) readBuf[i] != 0) {
txtArduino.append(String.valueOf((int) readBuf[i]) + ", ");
}
}
byte[] msg = {-2};
mConnectedThread.writeByte(msg);
break;
}
};
};
Arduino代码:
const int receveidBuffLen = 8*4;
void setup() {
Serial.begin(115200);
}
void loop() {
if (Serial.available() > 0)
{
byte buff[receveidBuffLen];
Serial.readBytes(buff, receveidBuffLen);
for(int i=0; i < receveidBuffLen;i++)
{
if(buff[i] == (byte) -2) // 254
{
byte message[2] = {(byte) -6, (byte) -9};
Serial.write(message, 2);
Serial.flush();
}
}
}
delay(3);
}
有谁知道延迟来自哪里?
我们更改了HC05波特率(从9600到115 200):没有任何反应。我们用另一个改变了HC05:什么也没发生。我们之前使用Blue2Serial库(蓝牙作为SPP)和延迟相同......我们使用了另一个控制器(ESP8266),延迟仍然是1秒......
看起来这个字符串是一个问题:
Serial.readBytes(buff, receveidBuffLen);
receveidBuffLen
是32的地方。尽管你一次得到一个字节,但你正试图读取其中的32个字节。当然,如果没有更多的字节,代码将被卡住直到超时。
此外,在读取字节后,您永远不会检查实际读取的字节数,但是从下到上扫描整个数组:
for(int i=0; i < receveidBuffLen;i++)
相反,你必须做这样的事情:
int bytesAvailable = Serial.available();
if (bytesAvailable > 0)
{
byte buff[receveidBuffLen];
int bytesToRead = (bytesAvailable < receveidBuffLen) ? bytesAvailable : receveidBuffLen;
// Read no more than the buffer size, but not more than available
int bytesActuallyRead = Serial.readBytes(buff, bytesToRead);
for(int i=0; i < bytesActuallyRead;i++)
...
代码中存在一些可能导致延迟的问题:
loop()
- 您应该专注于最小的数据单元并处理每个Serial.readBytes()迭代。如果您尝试处理每个循环的多个消息,那么现在将减慢循环时间导致延迟。您可以尝试在Arduino上实现loop()
模式。我们将只从串行缓冲区一次读取一个字节,将SerialEvent函数的处理保持在最低限度。如果我们收到loop()
字节,我们将标记一个标志。如果标记标记,则-2
函数将调用loop()
函数,但不会阻止数据传输。这是一个简单的例子。
Serial.write()
我们只是自己找到一些解决方案,并希望分享它们:
初始情况:1050毫秒的答案。 Alls解决方案是独立的,并在初始情况下完成。
bool sendMessage = false;
byte message[2] = {(byte) -6, (byte) -9};
void loop()
{
if (sendMessage == true)
{
Serial.write(message, 2);
sendMessage = false;
}
}
/*
SerialEvent occurs whenever a new data comes in the hardware serial RX. This
routine is run between each time loop() runs, so using delay inside loop can
delay response. Multiple bytes of data may be available.
*/
void serialEvent()
{
while (Serial.available())
{
// get the new byte:
byte inChar = ((byte) Serial.read());
if (inChar == ((byte) -2))
{
sendMessage = true;
}
}
}
:95毫秒。哪种解决方案是最好的,我们不能说,但它现在有效...