蓝牙通讯延迟大

时间:2019-08-16 18:04:49

标签: c arduino

我尝试使用两个arduino nano v3板和两个蓝牙4.0模块编写无线伺服控制。第一个代码是发射机。非常简单它读取PPM信号并进行转换以分离每个通道的PWM值。我使用硬件串口。

#include <PPMReader.h>
#include <InterruptHandler.h> 

int ppmInputPin = 3;
int channelAmount = 2;

PPMReader ppm(ppmInputPin, channelAmount);

void setup()
{
  Serial.begin(9600);
  Serial.write("AT\r\n");
  delay(10);
  Serial.write("AT\r\n");
  Serial.write("AT+INQ\r\n");
  delay(5000);
  Serial.write("AT+CONN1\r\n");
}

void loop()
{
  unsigned long value1 = ppm.latestValidChannelValue(1, 0);
  Serial.println(value1);
}

接收器也很简单。它从蓝牙读取值并将其解析为整数值,并通过第7针发送到伺服。我再次使用了硬件串行端口。

#include <Servo.h>

int PWM_OUTPUT = 7;

Servo servo;

void setup() {
  servo.attach(PWM_OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int pwmValue = Serial.parseInt();

  if (Serial.available()) { 
    if(pwmValue > 900 && pwmValue < 2001) {
      servo.writeMicroseconds(pwmValue);
    }
  }
}

一切正常。但它会延迟2-3秒左右。可能在“垃圾邮件”串行端口中出现问题?

2 个答案:

答案 0 :(得分:0)

在实现设备到设备通信时,您需要问自己的第一件事是我应该以多快的速度发送?并且如果我以该速率发送:接收方是否能够跟上步伐(阅读,进行处理或执行其需要做的任何事情并回复)?

这显然与波特率无关,而与循环的作用有关。您正在使用两个不同的库: PPMReader Servo 。现在,请注意每个设备在各自的循环中正在做什么:

//Sending
void loop() {
  unsigned long value1 = ppm.latestValidChannelValue(1, 0);
  Serial.println(value1);
}

//Receiving
void loop() {
  int pwmValue = Serial.parseInt();
  if(pwmValue > 900 && pwmValue < 2001) {
  servo.writeMicroseconds(pwmValue);
  }
}

我真的不知道执行每一行代码要花多长时间(请看here上的一些注释),但是您不能真正期望两个循环都能神奇地自我同步。考虑到它们在处理不同的硬件方面做的事情非常不同(省去了串行部分),我希望其中一个比另一个花费更长的时间。想想如果是这样的话。

正如我所说,我不知道调用ppm.latestValidChannelValue(1, 0)会花费多长时间,但是出于我的观点,我们假设它花费0.1毫秒。要估算完成循环一次迭代所需的时间,您需要添加使用Serial.println(value1)将一个(或两个)字节打印到端口所花费的时间,但这更容易,也许在{{3左右}}是个不错的人物。通过这些估计,您最终每秒读取5000次。如果您不满意或不信任我的估计,我建议您使用计数器或计时器进行自己的测试。如果对链接的另一端进行相同的练习,并且假设它的速度快一倍,则每秒运行10000次,您如何看待通信?是的,没错:它将被阻塞并以蜗牛的速度运行。

在这里,您应该仔细考虑您是否真的需要那么多阅读材料(您没有详细说明自己在做什么,所以我不知道,但我倾向于认为您不需要)。如果不这样做,只需在发送方增加延迟,以将其降低到合理的速度(可能是每秒10-20次迭代)。

您的代码还有其他需要改进的地方:应在读取缓冲区之前(而不是之后)检查缓冲区中是否已接收到数据。而且您需要小心使用Serial.parseInt(),它有时会导致意外的结果,但是这个答案已经太长了,我不想进一步扩展它。

答案 1 :(得分:-1)

我发现了问题。这是在串行端口垃圾邮件中。我添加了检查当前值是否不等于上一个值,并且它已经开始工作并且下一个小问题在接收器中。我在价值可用之前就读过它。

#include <PPMReader.h>
#include <InterruptHandler.h> 

int ppmInputPin = 3;
int channelAmount = 2;

PPMReader ppm(ppmInputPin, channelAmount);

volatile unsigned long previousValue1 = 0;

void setup()
{
  Serial.begin(9600);
  Serial.write("AT\r\n");
  delay(10);
  Serial.write("AT\r\n");
  Serial.write("AT+INQ\r\n");
  delay(5000);
  Serial.write("AT+CONN1\r\n");
  Serial.println("Transmitter started");
}

void loop()
{
  unsigned long value1 = ppm.latestValidChannelValue(1, 0);

  if(previousValue1 != value1) {
    previousValue1 = value1;
    Serial.println(value1);
  }

}