无法弄清楚为什么这个Arduino代码不起作用?

时间:2017-04-19 21:16:47

标签: c++ arduino

我正在为车轮速度传感器创建一个代码,作为更大的团队项目的一部分。该代码将使用霍尔效应传感器和连接到车轮的磁铁来测量和显示自主陆地游艇的地面速度和行驶距离。我已经编写了代码,并且它自己完全正常。但是,当我尝试将其添加到完整的项目代码时,它似乎根本不起作用。唯一的区别是在void loop()内部发生了许多其他事情。我检查并仔细检查了所有的引脚和所有代码,我根本无法解决它。它有时可以用于车轮的一次旋转然后它似乎有点退出一个循环,因为一旦车轮停止并再次启动,速度总是会读取0m/s

以下是代码:

int sensorPin1 = 2; // hall effect
float revs;
float rpm;
volatile byte rpmcount;

long fin_time;
long current_time;
long stop_time;
float distance;
const float circumference = 0.31416;
float groundspeed;
const float Pi = 3.14159;

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 13);


void setup() 
{
  Serial.begin(9600);
  pinMode(sensorPin1, INPUT);
  attachInterrupt(0, RPM, RISING);  
}

void RPM()
{
  rpmcount++;
  revs++;
} 

void loop() 
{
  lcd.clear();
  lcd.begin(16,2);
  lcd.setCursor(0,0);
  lcd.print("GS=");
  lcd.setCursor(3,0);
  lcd.print(groundspeed,1);
  lcd.print("m/s");
  lcd.setCursor(10,0);
  lcd.print("D=");
  lcd.print(distance,0);
  lcd.print("m");

  if(rpmcount == 1)
  {
    current_time = time - fin_time;
    rpm = ((60000)/current_time);
    groundspeed = ((rpm * circumference) / 60);
    distance = revs*circumference;
    rpmcount = 0;
    fin_time = millis();
  }

  stop_time = millis() - fin_time;
  if(stop_time >= 2000)
  {
    rpm = 0;
    groundspeed = 0;
    delay(20);
  }
}

主项目中的代码采用完全相同的结构,唯一的区别是void setup()void loop()在船上的所有其他传感器旁边都有一堆其他东西。我检查了代码,代码中的主要算术不包含在任何其他if循环或if (rpmcount == 1)以外的任何内容中。

有人有想法吗?

我可以上传完整的项目代码,但它已经有数百行,这个问题已经足够长了。

2 个答案:

答案 0 :(得分:0)

我不是Arduino专家,但在我看来,rpmcount执行loop()时有可能(实际上可能)有时大于1。变量rpmcount正在通过中断递增,并且似乎没有任何方法可以确保为每个中断调用一次循环。换句话说,如果在调用loop()之间存在多轮转动会发生什么?

如果整个项目中的loop()有很多其他任务需要执行,这可能会导致您看到的问题,并且可能解释为什么它有时会在一开始就正常工作。

您应该只需测试rpmcount >= 1

即可解决问题

答案 1 :(得分:0)

其他人建议将if语句rpmcount == 1更新为rpmcount&gt; = 1.我同意他们的原因,这就是原因:

当LCD代码添加到您的项目时,它使循环()调用比不存在时更长。由于循环调用花费的时间太长,因此在rpmcount = 0代码甚至有机会运行之前,轮子将会出现几次。尝试删除rpm代码并在LCD代码周围调用millis()调用以查看更新LCD所需的时间。然后作为测试替换LCD更新代码,延迟测量间隔。

  unsigned long temp = millis();

  lcd.clear();
  lcd.begin(16,2);
  lcd.setCursor(0,0);
  lcd.print("GS=");
  lcd.setCursor(3,0);
  lcd.print(groundspeed,1);
  lcd.print("m/s");
  lcd.setCursor(10,0);
  lcd.print("D=");
  lcd.print(distance,0);
  lcd.print("m");

  Serial.println(millis()-temp); // println can take a while too, 
                                 // so don't add to many in parts 
                                 // of the code that are timing critical.

还有几点需要注意:

在为其分配值之前读取rpmcount。所以它应该在setup函数中初始化为0。

fin_time也是如此,好的做法是代码应初始化所有全局变量。

未初始化的变量可能会导致某些不良行为......有时候。