2016-03-31 15 views
0

Ich benutze ein Arduino Uno und ATMega328P, um einfach ein paar LEDs mit Schaltern durch den Benutzer gesteuert zu steuern. Nach etwa 56 Iterationen durch meine Hauptschleife (oder ~ 16 Sekunden) wird mein Programm zurückgesetzt. Ich vermute, dass es etwas mit dem Watchdog-Timer zu tun hat, aber sogar mit deaktiviert über wtd_disable(); In meinem Setup bleibt das Problem bestehen. Das Programm tritt in eine Schleife ein, die es nur verlassen kann, wenn der Benutzer einen Schalter umlegt. Irgendwelche Vorschläge?Arduino Programm Reset Bug

//Don't worry, I have all necessary libraries and variables set up. 

void setup() 
{ 
    Serial.begin(9600); // start serial for output 
    Serial.println(i2c_init()); 

    wdt_disable(); 

    //pinMode(22,INPUT_PULLUP); 
    //pinMode(23,INPUT_PULLUP); 
    pinMode(wakePin, INPUT); 
    pinMode(ACPin, INPUT); 
    pinMode(PowerPin, INPUT); 

    pinMode(PowerLED, OUTPUT); 
    pinMode(ACLED, OUTPUT); 
    pinMode(Battery1LED, OUTPUT); 
    pinMode(Battery2LED, OUTPUT); 
    pinMode(WifiLED, OUTPUT); 
    pinMode(TesterLED, OUTPUT); 
    pinMode(EnableLED, OUTPUT); 
    attachInterrupt(0, wakeUpNow, LOW); 


}   

void loop() 
{ 

    digitalWrite(PowerLED, LOW); 
// digitalWrite(ACLED, LOW); Exclude AC Power LED 
    digitalWrite(Battery1LED, LOW); 
    digitalWrite(Battery2LED, LOW); 
    digitalWrite(WifiLED, LOW); 
    digitalWrite(TesterLED, LOW); 
    digitalWrite(EnableLED, LOW); 

    Enable = 0; 

    Serial.println("Reset Complete"); 


    int ACPower = digitalRead(ACPin); 
    digitalWrite(ACLED, ACPower); 

    int v1 = fetchWord(deviceAddress1, VOLTAGE); 
    int v2 = fetchWord(deviceAddress2, VOLTAGE); 
    int BatteryVoltage = max(v1,v2); 
    Serial.print("Highest Battery Voltage: "); 
    Serial.println(BatteryVoltage); 

    delay(250); 

    if((BatteryVoltage >= 7000) | (ACPower == 1)){ 
    int PowerOK = digitalRead(PowerPin); 
    if (PowerOK == 0){ 
     loop(); 
    }else { 
     bulk(); 

    } 
    }else{ 
    loop(); 
    } 

} 

//This is the main part of my code that is constantly looped through, 
//and after 16 seconds, the program resets, going back to loop() 

void bulk() 
{ 

    Enable = 1; 
    digitalWrite(EnableLED, HIGH); 

    int ACPower = digitalRead(ACPin); 
    digitalWrite(ACLED, ACPower); 

    //int Battery1State = BatteryState(deviceAddress1); 
    int Battery1State = 2; // Simulating low battery 
    switch (Battery1State){ 
    case 1: 
     digitalWrite(Battery1LED, HIGH); 
     break; 
    case 2: //I can't run parallel code to control the blinking LED, 
//so I toggle the LED every pass through. Case 2 blinks slowly 
    if(i >= 4){ 
     toggleLED(Battery1LED); 
     i = 0; 
    } else { 
     i++; 
    } 
     break; 
    case 3: //case 3 blinks quickly 
    toggleLED(Battery1LED); 
     break; 

    } 
    int Battery2State = 3; // simulating a very low battery 
    switch (Battery2State){ 
    case 1: 
     digitalWrite(Battery2LED, HIGH); 
     break; 
    case 2: 
    if(j >= 4){ 
     toggleLED(Battery2LED); 
     j = 0; 
    } else { 
     j++; 
    } 
     break; 
    case 3: 
    toggleLED(Battery2LED); 
     break; 

    } 




    buttonState = digitalRead(wakePin); //button is HIGH by default 
    if(buttonState == HIGH){ 


    Serial.println(count); 
    if(count == 0){ 
     starttime = millis(); 
    } else if (count == 54){ 
     endtime = millis(); 
     runtime = endtime - starttime; 
     Serial.print("System Run Time: "); 
     Serial.println(runtime); 
    } 

    count++; 
    int PowerOK = digitalRead(PowerPin); 

    digitalWrite(PowerLED, PowerOK); 
    delay(250); 
//Repeat this code if power switch is on, restart if power is turned off 

    if(PowerOK == 0){ 

     loop();  
    }else { 

     bulk(); 
    } 
+0

Würden Sie in der Lage sein, Um den Code für die Schleife bereitzustellen? – cchapman

Antwort

0

Ich vermute - wie geeignet für einen Fehler auf dieser Website - einen Stapelüberlauf. Ich habe nicht wirklich versucht, den gesamten Code zu verstehen, aber von dem, was ich sehe, rufen beide Funktionen (loop und bulk) entweder loop() oder bulk() an ihrem Ende auf. Im Wesentlichen wird das Ende dieser Funktionen nie erreicht.

Für den Anfang versuchen, jeden Anruf Schleife zu entfernen() in Ihrem Code:

Ändern Sie den Code am Ende der Loop-Funktion aus:

if((BatteryVoltage >= 7000) | (ACPower == 1)){ 
    int PowerOK = digitalRead(PowerPin); 
    if (PowerOK == 0){ 
     loop(); 
    }else { 
     bulk(); 

    } 
    }else{ 
    loop(); 
    } 

zu:

if((BatteryVoltage >= 7000) | (ACPower == 1)){ 
    int PowerOK = digitalRead(PowerPin); 
    for (; PowerOK != 0 ;) 
     bulk(); 
    } 

und entfernen Sie den folgenden Code am Ende Ihrer Bulk() - Funktion vollständig:

delay(250); 
//Repeat this code if power switch is on, restart if power is turned off 

    if(PowerOK == 0){ 

     loop();  
    }else { 

     bulk(); 
    } 

Hintergrund:

Wenn Sie eine Funktion in C, C++ aufrufen und die meisten anderen Sprachen, die Absenderadresse (d die Stelle in Ihrem Code, an der die Ausführung fortgesetzt werden soll, nachdem die aufgerufene Funktion beendet wurde), wird auf einen speziellen Teil des Speichers gelegt, der Stack genannt wird. Wenn die aufgerufene Funktion zurückkehrt, wird die Rückkehradresse aus dem Stapel entfernt und alles ist gut. Wenn eine andere Funktion aufgerufen wird, bevor die erste zurückgegeben wird, wird dem Stapel eine neue Rücksprungadresse hinzugefügt. Wenn sich eine Funktion wiederholt selbst aufruft, ohne jemals zurückzukehren, wird schließlich der gesamte Stapelraum (eine begrenzte Ressource) aufgebraucht und etwas Schlimmes passiert. Das passiert in deinem Code: Die Funktionen loop() und bulk() kehren nie zurück, stattdessen machen sie ihr Ding und rufen entweder sich selbst oder das andere ad infinitum auf.

In arduino, gibt es eine implizite Funktion main() mehr oder weniger wie die folgenden:

void main(void) 
{ 
    // system initialisation code 
    ... 
    ... 
    ... 
    // user code 
    setup() ; 
    for(; ;) 
     loop() ; 
} 

Das heißt, loop() aufgerufen wird, kontinuierlich. Es gibt keinen Grund, es erneut an seinem Ende zu nennen.

Hoffe, das hilft.

+0

Danke! Ich bin immer noch ziemlich neu mit Programmierung, also diese Erklärung wirklich geholfen. –

+0

Wenn Sie denken, dies ist die richtige Antwort auf Ihre Abfrage, sollten Sie es als richtig markieren (klicken Sie auf (Das Häkchen links neben dieser Antwort.) Aber Ihre vorherige Antwort würde bedeuten, dass das, was ich geschrieben habe, irrelevant ist. In diesem Fall sollten Sie Ihre eigene Antwort als die richtige markieren. Der ganze Sinn dieses Systems ist es, darauf hinzuweisen andere Leser der Frage, die Antwort war mehr u für dich. –

+0

Kein Problem, ich versuche, Ihre Lösung zu implementieren, um zu sehen, ob es funktioniert, da mein Programm immer noch augenblicklich neu zu starten scheint. –

0

Macht nichts, ich glaube, es war ein serieller Port Überlauf. Das Problem löste sich, als ich einige "Serial.println" am Ende meines Codes löschte, die ich für irrelevant hielt.

0

für Arduino, wenn das Setup-Start() einmal aufgerufen wird, dann die Schleife wiederholt aufgerufen wird (sobald sie abgeschlossen ist .. Wie erwähnt, gibt es keine Notwendigkeit für Schleife jemals selbst zu nennen ..