arduino-uno


Arduino Program Reset Bug


I'm using an Arduino Uno and ATMega328P to simply control a few LEDs with switches controlled by the user. However, after about 56 iterations through my main loop (or ~16 seconds) my program resets. I suspect it has something to do with the Watchdog timer, but even with it disabled via wtd_disable(); in my setup, the problem persists. The program does enter a loop that it can only exit if the user flips a switch. Any suggestions?
//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();
}
I suspect - how appropriate for a bug posted in this site - a stack overflow. I haven't really tried to understand your entire code, but from what I see, both functions (loop and bulk) call either loop() or bulk() at their end. In essence, the end of those functions is never reached.
For starters, try removing every call to loop() inside your code:
Change the code at the end of the loop function
from:
if((BatteryVoltage >= 7000) | (ACPower == 1)){
int PowerOK = digitalRead(PowerPin);
if (PowerOK == 0){
loop();
}else {
bulk();
}
}else{
loop();
}
to:
if((BatteryVoltage >= 7000) | (ACPower == 1)){
int PowerOK = digitalRead(PowerPin);
for ( ; PowerOK != 0 ; )
bulk();
}
and remove completely the following code at the end of your bulk() function:
delay(250);
//Repeat this code if power switch is on, restart if power is turned off
if(PowerOK == 0){
loop();
}else {
bulk();
}
Background:
When you call a function in C, C++ and most other languages, the return address (i.e. the place in your code where execution should continue after the called function ends) is placed on a special part of memory called the stack. When the called function returns, the return address is removed from the stack and all is well. If another function is called before the first one returns, a new return address is added to the stack. If a function repeatedly calls itself without ever returning, eventually the entire stack space (a limited resource) is used up and something bad happens. This is what happens in your code: the functions loop() and bulk() never return, instead they do their thing and call either themselves or the other one ad infinitum.
In arduino, there is an implicit main() function more or less like the following:
void main(void)
{
// system initialisation code
...
...
...
// user code
setup() ;
for( ; ; )
loop() ;
}
That is, loop() is called continuously. There is no reason to call it again at its own end.
Hope this helps.
Never mind, I believe it was a Serial port overflow. The problem resolved itself when I deleted some "Serial.println"s at the end of my code that I thought were irrelevant.
For arduino, when starting the setup() gets called once, then loop is called repeatedly (whenever it completes..
As mentioned there is no need for loop to ever call itself..

Related Links

I cannot find UID of my Arduino
Arduino Program Reset Bug
arduino uno R3 input pins with gsm shield
Light weight machine to machine communication with Arduino
Interfacing RM5 evolution coin acceptor with arduino
Arduino-ESP8266 Sending URL from a client browser connected to the esp8266 AP and receiving the entered URL in the arduino board
Need explanations about a code relative to MPU6050
Arduino Programmer only works after unlugging and plugging back in
How do I communicate between Arduino board and Intel Edison Arduino board using XBee S2?
I cannot solve my arduino program error
2.4 inch TFT LCD SPFD5408 with Arduino Uno - touch not working
DAC0808 doesn't want tranfer to analog
Trouble in programming arduino with esp8266
How to control a servo motor with Windows Remote Arduino?
Set baud rate to esp8266 at 9600
Arduino AC Dimmer - serial communication lost due to interrupt

Categories

HOME
sendgrid
twitter
keras
oracle11g
comparison
lodash
platform-builder
react-router
infragistics
rubygems
blueprintjs
ojdbc
datastax-java-driver
onelogin
azure-media-services
imacros
timeout
gz
windows-phone-7
orchardcms
try-catch
serverless-framework
django-admin
normalizr
viewport
ml
tapestry
pass-by-reference
wijmo
cas
su
newline
lightswitch-2013
hybridauth
form-data
geopositioning
file-format
dartium
neuroscience
twitch
vapor
hilbert-curve
ansible-playbook
temporary-files
bootstrapper
ensembles
dynamic-reports
fakeiteasy
eclipse-gef
dotcover
theming
pnotify
dandelion
tropo
colorama
carrot
dtexec
gcsfuse
bind9
grails-tomcat-plugin
savon
file-writing
trash
testng-dataprovider
lib.web.mvc
endeca-workbench
cannon.js
cyclomatic-complexity
comobject
retina
coveralls
nsight
graph-api-explorer
modalpopup
jsonpickle
nstableviewcell
java.util.concurrent
mdt
xojo
runtime.exec
pushbackinputstream
anonymous-methods
trusted
reddot
stage
psi
django-tagging
appendto
subviews
dentrix
xsdobjectgen
dbal
substrings
sef
libs
simpletest
aquaticprime
thread-local-storage
putchar
uiq3

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App