2017-04-19 73 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

相關問題