Have encountered a perplexing problem I'm hoping someone can shed some light on how to approach. To be general to start, here's what's happening ...
I call a particular library function from within a sketch. (In this case it happens to be a wireless WiFly library function). Calling the function during setup() appears to work fine. However, if I call the same function from within loop(), the program essentially resets .. i.e. re-enters setup() .. just as if there had been a hardware reset. So, since the function is in loop(), the program just goes back to setup() continually .. i.e. it's going from setup() --> loop() --> setup() --> loop() --> etc.
I think I've eliminated power/hardware possibilities for the source of the problem, but I don't quite know how to hunt down any possible software related issues (pointer problem, memory problem, etc. ??)
I realize I'm posing the question in a very general way at this point, but I'm hoping someone may have encountered a similar situation in their project, and can indicate how I might approach troubleshooting.
Thanks in advance,
Sounds like a classic out-of-RAM problem.
Post your code for more useful help...
Ok, thanks. I'm not sure it's a memory issue as I also have a freeMemory() utility function running which indicates about 1k of available RAM, but I will have a closer look .. perhaps more is getting eaten up when I invoke this function than I think. Will also try to run it on a Mega (once I sort out NewSoftSerial on a Mega 1280). It seems strange to me that the function runs fine during setup(), but not during loop() .. but again, I will focus on memory usage per your suggestion.
(I was avoiding posting code as there's several hundred lines to wade thru between the .pde and supporting libraries .. but I'll try to clean things up a bit, zip it up, and attach it to a subsequent post).
If it isn’t RAM and it isn’t power, I think I’d look for pointer errors causing the stack to get trashed. If a function hoses up the PC on the stack (i.e. the return address for the function), the system could appear to start over.
Will also try to run it on a Mega (once I sort out NewSoftSerial on a Mega 1280).
If you get a Mega with 4 hardware serial ports, why do you need software serial ports, too?
Thanks again kg. Yea, I'm also thinking about possible problems with pointers .. my problem being (due to lack of experience) I'm not exactly sure how to hunt that problem down just using the tools I'm currently using. I'm just pretty much using serial monitor now, and suspect I'd have to switch over to a more sophisticated debug environment to really see what's happening. Suggestions?
( ... to PaulS - just a bit of laziness on my part re: switching over to the Mega hw ports. The code I'm using is currently based around SW Serial on an Uno, and I was just trying to take the easy route to start to port it over to a Mega. I would indeed switch to the hw uarts if I needed to go the Mega route for memory reasons).
If you've got a serial port (or can manage to connect a software serial output for debugging), debug with judicious use of
Serial.print() to help nail down the function where the error occurs.
Once you find the function, look for things like local (to the function) arrays that could get indexed negatively and assigned a value (to zero, for instance). Also look for local pointers. You may also want to check your free RAM again in that function (or just before calling it), as you may be running out after you check it. It doesn't take long to consume 1k...
Not sure if you know how functions work, but when a function is called, the address of the next instruction to be executed (the PC, or program counter) in the calling function is stored on the stack; this is used to return once the function is finished executing. Local variables for the called function are allocated on the stack. If I made a mistake and initialized an integer array to all zeros, but used indices -10 to 0 instead of 0 to 10, I could trash the previously stored PC, so that when my function returns, I start at program location 0, which is the start of the program. Similar atrocities can occur by mishandling pointers (array indexing is just a special case of pointer use), or trashing all RAM by incorrectly looping past the end of an array until you modify the entire contents of memory.
I'm taking your word that it's definitely not hardware.
Thanks again j. Yea, I've got the general concepts re: how the functions, pointers, array indexing, and the stack work .. I've just not had to hunt one down like this in great detail .. especially in someone else's (library) code. To complicate the matter, the function I believe I'm having the problem with calls a function, which calls a function, which calls a function, etc. So, it's easy to envision some sort of pointer or memory error somewhere along the way. Again though, the interesting thing to me here is that this function appears to work fine if invoked during setup(), just not during loop(). Perhaps it's just getting pushed over the edge with regard to memory in loop(). I am planning to add some memory checks along the way as you suggest as this thing gets deeper and deeper into the function hierarchy to see what might be happening. I appreciate your comment that it doesn't take long to eat up 1k. (In this library there's also a lot of PROGMEM stuff being transferred back to RAM during the function calls .. so memory management is certainly an important issue).
Re: hardware, well I've learned never to eliminate any possibility entirely To check for this possibility I've run my board off external vs. USB power (these WiFly wi-fi devices take a fair amount of current during TX .. about 200ma). And I would expect any power related problem to likely also manifest itself running the function during setup(), which I haven't seen.
(If interested, and you want to have a quick look at the library I'm using, you can find it at .. Arduino WiFly Driver - Browse Files at SourceForge.net I'm spending a lot of time looking at the .isConnected() function within the WiFlySerial.cpp file .. line 866.
My advice would be to put in a debugging print before and after the suspect function. If you see the "before" but not the "after" then the function may well be to blame (depending of course if you passed valid data to it).
Another approach is to make a minimal sketch that just calls the suspect function.
Bear in mind that setup and loop are just functions themselves. There is nothing intrinsic about setup that makes it "better" than loop. It's more likely that loop, being called repeatedly, is bringing out the worst in something (eg. something that consumes memory). Again, debugging prints would show this.
Be very, very careful with debug prints however; someone here recently pointed out that they can be akin to looking for a gas leak with a candle.
I think I'd avoid the RAM-gobbling strings like "Commenced device-under-test debugging!" (see the comment about candles and gas leaks), but yes, a useful technique.
Good point, lol. That was just a demo of the idea, but I've amended the thread to point out that long-winded debugging messages may cause their own problems.
Thanks Nick and AWOL for your comments, suggestions (and cautions). I've pretty much been using Serial.print()s sprinkled around to get an idea of what's happening, but will study the Debug print in more detail and perhaps "step up my game" a bit with regards to debugging and getting a better view into code execution.
Still chasing my elusive bug down. I'm pretty sure I've eliminated hardware, and more recently (inadequate) memory, as possible sources of the trouble .. so am now focusing on perhaps a stack problem and/or errant pointer as was initially posited by j as another possible suspect for the sort of unexpected behavior I'm seeing. It's looking perhaps that some combination of functions may be at work here .. I'm finding that the one function I initially suspected seems to be affected by another function I include either before it in setup(), or with it in loop().
Oh well, the hunt is all fun .. good to be learning stuff. Should definitely keep me busy on a nice afternoon today down here in sunny southern CA
Thanks much again,
Good luck! Sadly, even overwriting a single byte of an array can cause major problems, including this classic one:
byte foo ; // declare an array of 10 items
foo  = 42; // put something in the 10th spot (oops - actually the 11th spot)
Sorry to hear that the constrained-memory issues are causing grief... very familiar with those while writing the WiFlySerial library.
On the plus side - there are learning opportunities for memory management in constrained spaces.
The WiFly preparation functions do take a certain space (ok, an unseemly heap) of their own during initialization; most of that allocation is released after completing the setup() function.
Once setup is done, not sure why you'd want to revisit the topic during loop(). Which setup function are you trying to use in loop() and why?