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()被调用一次,然后循环被重复调用(每当它完成..
如前所述,循环不需要调用自己..
我正在使用 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()被调用一次,然后循环被重复调用(每当它完成.. 如前所述,循环不需要调用自己..