我使用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();
}
答案 0 :(得分:0)
没关系,我相信这是串口溢出。当我在代码末尾删除了一些我认为无关紧要的" Serial.println"时,问题就解决了。
答案 1 :(得分:0)
我怀疑 - 这个网站上发布的错误是多么合适 - 堆栈溢出。我还没有真正理解你的整个代码,但从我看到的,两个函数(循环和批量)在它们的末尾调用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 ++和大多数其他语言调用函数时,返回地址(即代码中被调用函数结束后应继续执行的位置)放在称为堆栈的内存的特殊部分上。当被调用函数返回时,返回地址将从堆栈中删除,一切正常。如果在第一个函数返回之前调用另一个函数,则会向堆栈添加新的返回地址。如果一个函数在没有返回的情况下重复调用自身,最终整个堆栈空间(一个有限的资源)被用完了,发生了一些不好的事情。这就是你的代码中发生的事情:函数loop()和bulk()永远不会返回,相反,他们会做自己的事情并自己调用或者无限调用。
在arduino中,有一个隐含的main()函数或多或少如下:
void main(void)
{
// system initialisation code
...
...
...
// user code
setup() ;
for( ; ; )
loop() ;
}
即,连续调用loop()。没有理由在自己的最后再次打电话。
希望这有帮助。
答案 2 :(得分:0)
对于arduino,当启动setup()被调用一次,然后重复调用循环(只要它完成.. 如上所述,循环不需要自己调用..