Arduino 程序重置错误

Arduino Program Reset Bug

我正在使用 Arduino Uno 和 ATMega328P 通过用户控制的开关来简单地控制几个 LED。但是,在我的主循环(或约 16 秒)迭代了大约 56 次之后,我的程序重置了。我怀疑它与看门狗定时器有关,但即使通过 wtd_disable(); 禁用它也是如此。在我的设置中,问题仍然存在。该程序确实进入了一个循环,只有当用户按下开关时它才能退出。有什么建议吗?

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

没关系,我相信这是串口溢出。当我在我的代码末尾删除一些我认为不相关的 "Serial.println" 时,问题自行解决了。

我怀疑 - 对于此站点中发布的错误来说有多合适 - 堆栈溢出。我并没有真正尝试理解您的整个代码,但据我所知,这两个函数(循环和批量)在它们的末尾都调用了 loop() 或 bulk() 。从本质上讲,这些功能永远不会结束。

对于初学者,请尝试删除代码中对 loop() 的所有调用:

修改循环函数结束处的代码 来自:

  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++ 和大多数其他语言中调用函数时,return 地址(即代码中被调用函数结束后应继续执行的位置)位于内存称为堆栈。当调用函数returns时,return地址从栈中移除,一切正常。如果在第一个 returns 之前调用了另一个函数,则会将一个新的 return 地址添加到堆栈中。如果一个函数在没有 returning 的情况下重复调用自身,最终整个堆栈 space(有限的资源)都会用完,并且会发生一些不好的事情。这就是您的代码中发生的情况:函数 loop() 和 bulk() 从不 return,而是它们做自己的事情并无限地调用自己或另一个。

在 arduino 中,有一个隐含的 main() 函数,大致如下所示:

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

即不断调用loop()。没有理由在它自己的末端再次调用它。

希望对您有所帮助。

对于arduino,当启动时setup()被调用一次,然后循环被重复调用(每当它完成.. 如前所述,循环不需要调用自己..