2017-04-19 130 views
-1

我正在创建轮速传感器的代码,作为更大组项目的一部分。该代码将使用霍尔效应传感器和附着在车轮上的磁铁来测量和显示自主陆地游艇的行驶速度和行驶距离。我已经编写了代码,并且它自己的工作非常好。但是,当我尝试将其添加到完整的项目代码时,它似乎根本无法工作。唯一的区别是在void loop()里面还有其他一些事情发生。我已经检查了所有的引脚和所有的代码并且进行了双重检查,我根本无法解决这个问题。它有时会产生对车轮的一个旋,然后似乎有点退出循环莫名其妙因为一旦车轮已经停止并再次启动速度则总是读0m/s无法弄清楚为什么这个Arduino代码不起作用?

这是对自己的代码:

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)以外的任何其他代码中。

有没有人有想法?

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

+0

是否有可能在主项目的循环内的其他代码中有条件返回? – isick

+0

感谢您的快速响应。主项目代码中没有任何回报。只需在一个主循环内计算数据并将其显示在LCD上即可。 @isick –

+1

当'rpmcount'大于1时会发生什么?也许你可以试试'if(rpmcount> 0)...' – Amadeus

回答

0

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

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

您应该能够通过只是测试了rpmcount >= 1

+0

谢谢你的回应,因为void loop()中包含了一堆代码,所以'If(rpmcount == 0)'指令中的rpmcount被重置为0,所以它真的永远不会超过1。 –

+1

@c_user,其中是'if(rpmcount == 0)'代码? –

+0

对不起,我的意思是'如果(rpmcount == 1)' –

0

其他人来解决这个问题已提出建议,if语句rpmcount == 1进行更新,以rpmcount> = 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被读取。所以它应该在设置功能中初始化为0。

fin_time也是如此,因为良好的实践代码应该初始化所有的全局变量。

未初始化的变量可能会导致一些不需要的行为...有时。

+0

谢谢为了回应!你可能举了一些millis()调用LCD的例子,我不太确定我会怎么做。 @Derek –

+0

上述响应中的代码块是如何计算代码段运行时间的示例。当前millis保存在temp中,允许正在分析的代码运行,然后通过串行连接输出从开始的时间差。为了看到生成的值,需要在arduino IDE中打开终端(串行监视器)。 – Derek

相关问题