I wrote a sketch with about 17K long. The sketch has several menus (display Nokia 5110). To move from menu to menu I use a resistor pot that changes the voltage at an ADC pin. The menu selection is according the ACD value. A lot of times when I change menu, the MCU makes a Reset. I suspected of shortage in RAM, but, after counting the global variables (count the number of bytes used by each variable), I count about 200 bytes. I have also a sprite "static const byte airplane[]" 504 bytes long. I used the sketch #include <MemoryFree.h> and Serial.print("freeMemory() reports "); Serial.println( freeMemory() ); and got a 590 bytes free.
Can it be a shortage RAM problem?
Is there any clue why I have MCU reset at menu change?
[quote author=Manuel Silva link=topic=85107.msg637072#msg637072 date=1325196549]
I wrote a sketch with about 17K long. [/quote]
The size of a sketch really doesn't give you an idea of how much RAM it is using. The compiler has no way of knowing what RAM usage will be when a program starts to run.
[quote author=Manuel Silva link=topic=85107.msg637072#msg637072 date=1325196549]
Can it be a shortage RAM problem?[/quote]
The most likely reason for the processor to reset is running out of RAM.
[quote author=Manuel Silva link=topic=85107.msg637072#msg637072 date=1325196549]
Is there any clue why I have MCU reset at menu change?[/quote]
Without seeing code, it is tough to make guesses.
One of the old hands here very kindly supplied this code fragment when I asked a similar question:
// this function will return the number of bytes currently free in RAM
extern int __bss_end;
extern int *__brkval;
int freemem()
{
int free_memory;
if((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
}
[quote author=Manuel Silva link=topic=85107.msg637094#msg637094 date=1325197355]
Counting the global variables and the information given by the "FreeMemory" is it reliable to have an idea of the RAM used?[/quote]
These are guides, at best. The global variables will tell you the minimum your program consumes. From there, the heap depends on when and how functions are called.
Since there is no memory manager in the ATmega328, there is nothing that knows which section of RAM are in use and what aren't. This includes the various code chunks that take a best-guess at the amount of free RAM.
Are you using the String class, or anything else that allocates memory dynamically?
Other things that can cause a program to go haywire include writing an array element with an index outside the bounds of the array, and writing through a pointer that does not point to the correct area of memory.
Which Arduino board are you using? Without diving too deeply into the code, you are definitely hitting RAM limits (2k) on an ATmega328.
As madworm points out, move your airplane to PROGMEM. In fact, anything you have marked as a "const" should probably go there as well. No sense burning up RAM on something that can't ever change.
Additionally, anytime you use a char const like:
lcd.print("Cell Volts");
The string, "Cell Volts" is copied into RAM before it can be used by lcd.print(). If moving just airplane doesn't work you might want to move all of your string constants to PROGMEM as well.
I looked at your code, and I have some questions. Why are you showing the bitmap in loop? Why are you running an infinite loop inside loop()? The loop() function is already called in an infinite loop.
Why do you have static arrays with global scope? The static keyword contributes nothing to global variables.
Why do you have two variables named airplane_width and two named airplane_height? Memory is limited on the Arduino. Wasting it with duplicate variables doesn't help.
Where were you calling the free memory function? Calling it in one place does not give you a good indication of available memory, since each function call takes memory, too.
The questions you are put, are difficult to me. I do not have knowledge enough to answer to them (this is my first C program).
Basically the program receives 52 bytes of data from UART, that is saved in a vector. This data sent by an airmodel (two way receiver in the air) and is received by the transmitter (two way) that has a USART output.The rate of the date is 52 bytes /second.
After received the data, I read it from the vector and do all the calculations. After that and depending of the ADC value read at an input is chosed the data to display.
Summarizing:
I do not know what you mean by:
Are you using the String class, or anything else that allocates memory dynamically?
Other things that can cause a program to go haywire include writing an array element with an index outside the bounds of the array, and writing through a pointer that does not point to the correct area of memory.
I am going to read the tutorial about PROGMEM, but I do not understand what you mean by:
This also requires using the related pgm_read_byte() function.
I've looked at your code. You are not using String (which is good) and I can't see any obvious errors of the sort that would cause the program to go out of control. Possibly the problem is occurring in one of the libraries you are using.
You said that the reset occurs when you move the pot to change the display. Does it make a difference which screen you are switching from/to, or can the reset occur between any pair? One difference I can see that changing the pot makes is that the lcd is cleared before the new screen is displayed. If you comment out the lcd.clear() statements in function display_data, does the resetting problem go away?
OK, that helped, and I think I've found the problem. In max_data_print() you have the statement:
lcd.print(altit_max,1);
However, altit_max has type integer, so the second argument is instructing print() to print it in base 1. Printing a number other than 0 is base 1 is rather difficult! It's probably causing either infinite recursion or a buffer overflow, depending on the implementation of print() for integers. You need to remove the ",1" from that statement.