2016-03-31 12 views
0

Я использую Arduino Uno и ATMega328P, чтобы просто управлять несколькими светодиодами с помощью переключателей, управляемых пользователем. Однако после 56 повторений через мой основной цикл (или ~ 16 секунд) моя программа сбрасывается. Я подозреваю, что он имеет какое-то отношение к таймеру Watchdog, но даже с ним отключен через wtd_disable(); в моей установке проблема сохраняется. Программа действительно вводит цикл, который может выйти только в том случае, если пользователь переключает переключатель. Какие-либо предложения?Ошибка восстановления программы Arduino

//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

ли вы быть в состоянии чтобы получить код для цикла? – cchapman

ответ

0

Я подозреваю - как это подходит для ошибки, опубликованной на этом сайте - переполнение стека. Я действительно не пытался понять весь ваш код, но из того, что я вижу, обе функции (цикл и объем) вызывают либо loop(), либо bulk() в конце. По сути, конец этих функций никогда не достигается.

Для начала, попробуйте удалить каждый вызов цикла() внутри кода:

Изменить код в конце функции петли от:

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

    } 
    }else{ 
    loop(); 
    } 

к:

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

и полностью удалите следующий код в конце своей функции (

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

    if(PowerOK == 0){ 

     loop();  
    }else { 

     bulk(); 
    } 

фона:

При вызове функции в C, C++ и большинство других языков, обратный адрес (т.е. место в вашем коде, где выполнение должно продолжаться после завершения вызываемой функции) помещается в специальную часть памяти, называемую стеком. Когда вызываемая функция возвращается, адрес возврата удаляется из стека, и все хорошо. Если вызывается другая функция перед первым возвратом, в стек добавляется новый адрес возврата. Если функция повторно вызывает себя, не возвращаясь, в конечном итоге все пространство стека (ограниченный ресурс) используется, и происходит что-то плохое. Это то, что происходит в вашем коде: функции loop() и bulk() никогда не возвращаются, вместо этого они выполняют свою задачу и вызывают либо себя, либо другую бесконечность.

В Arduino, есть функция неявное основная() более или менее, как следующее:

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

То есть, петля() называется непрерывно. Нет причин снова называть его в своем собственном конце.

Надеюсь, это поможет.

+0

Спасибо, я все еще довольно новичок в программировании, так что это объяснение действительно помогло. –

+0

Если вы считаете, что это правильный ответ на ваш запрос, вы должны рассмотреть его как правильную (нажмите флажок слева от этого ответа). Однако ваш предыдущий ответ будет указывать на то, что то, что я написал, не имеет значения. В этом случае вы должны отметить свой собственный ответ как правильный. Весь смысл этой системы - указать другие читатели вопроса, ответ был больше u для вас. –

+0

Нет проблем, я пытаюсь реализовать ваше решение, чтобы увидеть, работает ли оно, поскольку моя программа все еще, кажется, перезагружается в моменты. –

0

Ничего, я считаю, что это был перелив последовательного порта. Проблема решена сама, когда я удалил некоторые «Serial.println» в конце моего кода, которые, как я думал, были неактуальны.

0

Для Arduino при запуске установки() вызывается один раз, то цикл вызывается повторно (всякий раз, когда он завершает .. Как уже упоминалось нет необходимости в цикл когда-либо называть себя ..