I have developed a Telnet server application running on an arduino Mega which controls a number of fucntions in my building automation system.
The sketch includes a command parser and and individual commands can either take parameters in a single line or the command can be entered on its own and the sketch then asks for the parameters missing. For example
Command syntax to show the temperature of device 55 can be:
(a) showTemp 55 OR
(b) showTemp
Device No?
55
Temperature is : 28 Deg
Besides the Telnet server, the sketch also includes webserver, sensor sampling, ftp, RTC, RS485 links, external memory handling, Modbus interrogation to name some of the major functions…
The function of the program depends on a number of variables that hold the current state, what is pending, retrial of failed commands, error states, etc.
Some of these variables are also stored on EEPROM so that their value is maintained after reset.
All activity is stored in a log on SD card and, based on settings, certain types of errors/ warnings will be logged or just shown on screen or just accumulate a particular register.
For example, a packet that is lost on the RS485 bus (also interfaced to the Mega) doesn’t produce a visible error, but rather a particular register is incremented for statistical purposes. If however the user so wishes a warning message can also be generated or a report is prepared every so often or on demand.
So far I was pretty much able to trace and debug the sketch, but as the total compiled hex file now approaches 120kB, it is becoming increasingly difficult to figure out what is wrong when things are not behaving as expected. This is because behavior at any given moment depends on the state of a number of variables as explained above. If live debugging was available where the variable contents could be monitored along with program step execution, it would be much easier to debug but unfortunately this is not available.
I am not a professional programmer, although I ve been programming in various languages for ..a few decades now! Obviously well-structured programming is of paramount importance for debugging purposes and I am doing my best in this respect but it seems it is no longer enough!
I am seeking for advice on how to handle – there must be some sort of best practice already established- this sort of “state variables” in order to facilitate easier debugging.
Apologies if this is a somewhat vague question, but obviously I couldn’t post code in this case because of its sheer size and complexity.
DKWatson:
Have you tried loading your code into Atmel Studio? Run the simulator and all variables, ports and registers are exposed step by step or beakpoint.
Doesnt that need an emulator hardware to be connected to my board?
Each piece of your code should be separately tested - a good plan is to put each piece of functionality
in its own file (perhaps as a library), and tested with its own test sketch(s).
Combining the functionality is something to do only when each part has been exercised and found
to work. Trying to debug several interacting sets of code as a whole is obviously much more
complicated, and its much easier to create unexpected interactions between the parts if you
don't keep them entirely separate during development.
Separation of function also forces you to explicitly code all the interactions between them, which
means your brain has a better chance of understanding the interactions!
And if you go the whole hog of creating your own libraries for the parts, you can reuse them in
other projects, and it makes replacing one library with another easier (say you find a good
library online, with better functionality that your home-spun one).
Do you think you can point me towards somewhere in you project related to the technique what i am looking for?
I don't understand, what are you looking for. But my project is similar so somehow I solved that problem.
The additional ino files of my project can be put away easily to test only a part of the project. I moved it from Uno to esp8266 and later to M0. On the new architecture I put aside all other ino files except of the main file Regulator.ino and in it I commented out the calls to setups and loops of the additional ino files. Once the main sketch was running I added next .ino and made it work. Then the next etc.