2016-03-31 8 views
0

私はArduino UnoとATMega328Pを使用して、ユーザーが制御するスイッチで簡単にいくつかのLEDを制御しています。しかし、私のメインループ(約16秒)を通して約5​​6回反復した後、私のプログラムはリセットされます。ウォッチドッグタイマーとは関係がありますが、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

私は疑わしい - このサイトに投稿されたバグがどれほど適切か - スタックのオーバーフロー。私は実際にあなたのコード全体を理解しようとはしていませんでしたが、私の見ているところでは、両方の関数(ループとバルク)は、ループの終わりに()または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(); 
    } 

は手始めに、あなたのコード内のループへのすべての呼び出しを()削除してみてください

、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()は決して戻りません。代わりに関数を呼び出し、自分自身または他のものを無限に呼び出します。アルドゥイーノで

は、暗黙的なmain()関数多かれ少なかれ以下のように存在する:ある

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

は、ループ()が連続的に呼ばれています。それを自前でもう一度呼び出す理由はありません。

これが役に立ちます。 Arduinoのために

+0

ありがとう!私はプログラミングではまだかなり新しいので、この説明が本当に助けになりました。 –

+0

これが正しい返信だと思うなら、それを正しいものとしてマークすることを検討してください。しかし、あなたの前回の返信は、私が書いたものが無関係であることを示しています。この場合、あなた自身の返信を正しいものとしてマークする必要があります。返信の質問の他の読者はより多くのあなたのために穏やかです。 –

+0

私のプログラムがまだ瞬時に再開しているように見えるので、問題はありません。私は解決策を実装しようとしています。 –

0

私はそれがシリアルポートのオーバーフローだと思います。この問題は、コードの最後に「Serial.println」を削除したときに問題が解決されました。

0

、セットアップを開始する()あなたができるようになる