2017-04-19 4 views
-1

Ich erstelle einen Code für einen Raddrehzahlsensor als Teil eines größeren Gruppenprojekts. Der Code misst und zeigt die Bodengeschwindigkeit und die zurückgelegte Entfernung für eine autonome Landyacht mit Hilfe eines Hall-Effekt-Sensors und eines am Rad befestigten Magneten. Ich habe den Code geschrieben und es funktioniert vollkommen einwandfrei. Wenn ich jedoch versuche, es dem vollständigen Projektcode hinzuzufügen, scheint es überhaupt nicht zu funktionieren. Der einzige Unterschied ist, dass innerhalb von void loop() eine Menge anderer Dinge passiert. Ich habe alle Pins und den ganzen Code überprüft und doppelt überprüft, und ich kann es einfach nicht verarbeiten. es wird für eine Drehung des Rades manchmal arbeitet dann scheint es irgendwie, irgendwie eine Schleife zu beenden, wenn die Geschwindigkeit dann 0m/s immer liest, wenn das Rad und begann wieder zum Stillstand gekommen ist,Kann nicht herausfinden, warum dieser Arduino-Code nicht funktioniert?

Hier ist der Code auf seinem eigenen ist:

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); 
    } 
} 

der Code innerhalb des Hauptprojekt die exakt gleiche Struktur einnimmt, ist der einzige Unterschied, dass void setup() und void loop() ein paar andere Dinge in Seite haben sie für alle anderen Sensoren auf dem Schiff. Ich habe den Code überprüft und die Hauptarithmetik in meinem Code ist nicht in anderen if Loops oder irgendetwas anderes als if (rpmcount == 1) enthalten.

Hat jemand eine Idee?

Ich könnte den vollen Projektcode hochladen, aber es ist Hunderte von Zeilen und diese Frage ist schon lang genug.

+0

Ist es möglich, dass eine bedingte Rückgabe innerhalb des anderen Codes in der Schleife des Hauptprojekts stattfindet? – isick

+0

Vielen Dank für Ihre schnelle Antwort. Es gibt keine Rückgaben innerhalb des Hauptprojektcodes. Einfaches Berechnen von Daten und Anzeigen auf einem LCD innerhalb einer Hauptschleife. @isick –

+1

Was passiert, wenn 'rpmcount' größer als 1 ist? Vielleicht könntest du 'if (rpmcount> 0) versuchen ...' – Amadeus

Antwort

0

Ich bin kein Arduino-Experte, aber es scheint mir, dass es möglich (in der Tat wahrscheinlich) für rpmcount manchmal größer als 1 sein könnte, wenn loop() ausgeführt wird. Die Variable rpmcount wird durch einen Interrupt inkrementiert, und es scheint keine Möglichkeit zu bestehen, sicherzustellen, dass die Schleife für jeden Interrupt einmal aufgerufen wird. Mit anderen Worten, was passiert, wenn zwischen den Aufrufen von loop() mehrere Radumdrehungen auftreten?

Dies würde besonders wahrscheinlich das Problem verursachen, das Sie sehen, wenn loop() in Ihrem vollständigen Projekt eine Menge anderer Aufgaben zu erfüllen hat und erklären kann, warum es manchmal gleich zu Beginn funktioniert.

Sie sollten in der Lage sein, das Problem zu beheben, indem nur die Prüfung auf rpmcount >= 1

+0

Vielen Dank für die Antwort, es würde Sinn machen, da es Stapel von Code in void loop() gibt, rpmcount wird auf 0 in den 'If (rpmcount == 0)' Anweisungen zurückgesetzt, so dass es wirklich nie über 1 erreicht. –

+1

@c_user, wo ist der 'if (rpmcount == 0)' Code? –

+0

Sorry, ich meinte 'if (rpmcount == 1)' –

0

Andere Leute haben empfohlen, dass die if-Anweisung rpmcount == 1> = 1. ich mit ihnen und hier stimme rpmcount aktualisiert werden soll, warum:

Wenn der LCD-Code zu Ihrem Projekt hinzugefügt wird, dauert der Aufruf von loop() wesentlich länger als wenn er nicht vorhanden ist. Da der Schleifenaufruf so lange dauert, wird das Rad einige Male herumkommen, bevor der rpmcount = 0-Code sogar eine Chance bekommt, zu laufen. Versuchen Sie, den RPM-Code zu entfernen und millis() -Aufrufe um den LCD-Code herum zu setzen, um zu sehen, wie lange es dauert, das LCD zu aktualisieren. Dann als Test ersetzen Sie den LCD-Update-Code mit einer Verzögerung des gemessenen Intervalls.

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. 

Ein paar andere Punkte zu beachten:

rpmcount, bevor ein Wert zugewiesen wurde, gelesen wird. Daher sollte es in der Setup-Funktion auf 0 initialisiert werden.

Dasselbe gilt für fin_time. Als gute Praxis sollte der Code alle globalen Variablen initialisieren.

Nicht initialisierte Variablen können zu einem Teil des unerwünschten Verhaltens führen ...Manchmal.

+0

Danke für die Antwort! Könnten Sie vielleicht ein Beispiel für die Millis() - Aufrufe für das LCD geben, ich bin mir nicht ganz sicher, wie ich das machen würde. @Derek –

+0

Der Codeblock in der obigen Antwort ist ein Beispiel dafür, wie man herausfinden kann, wie lange ein Codeabschnitt benötigt, um ausgeführt zu werden. Der aktuelle Millis wird in temp gespeichert, der Code, der gerade analysiert wird, darf laufen, und dann wird die Zeitdifferenz vom Start über die serielle Verbindung ausgegeben. Um den produzierten Wert zu sehen, muss man das Terminal (Serial Monitor) in der arduino IDE öffnen. – Derek

Verwandte Themen