Running out of Ram ?

Hi,
my Power Analyzer project is coming to an end and it is very complex.

I tried adding the last few detections and suddenly when i flash my project i´m only getting weird output on my lcd :frowning:
Sometimes it shows only one row of 2 and hangs directly after, sometimes i can read a few values an then strange characters start overriding my display content.

I think my ram has come to an end even though freeRam() says I´m having about 120 Byte ram left.
I added a detection for power off which reads a pin which is applied to a battery up to 125V (in my case around 45).
When i remove this detection it seems to work fine.

I tried to cluster some functions together to give you an idea of what I´m doing here, hope it helps :

ISR(TIMER1_COMPA_vect){//timer1 interrupt 1Hz toggles pin 13 (LED)
  flip = 1;
  timercount++;
}

void setup()
{
  lcd.begin(16,2); 

  PORTA |= _BV(PORTA4);      // Pull ups
  PORTA |= _BV(PORTA7);

  read_defaults();  

  DIDR0 = _BV(ADC5D) | _BV(ADC4D) | _BV(AREFD) | _BV(ADC2D) | _BV(ADC1D) | _BV(ADC0D);
  DIDR1 = _BV(ADC10D) | _BV(ADC9D) | _BV(ADC8D) | _BV(ADC7D) ;  
  ADCSRA = _BV(ADPS0) | _BV(ADPS1) | _BV(ADPS2) | _BV(ADEN) ;  // Prescaler 128 resulting at around 55-62,5 khz

  TCCR1A = 0 ;// disable PWM mode
  TCCR1B = _BV(CS13) | _BV(CS12) | _BV(CS11) | _BV(CS10);
  OCR1C = 243;   // 1Hz

  TCNT1  = 0;
  TIMSK |= _BV(OCIE1A);
  //Debug.begin( 250000 );

  stime = millis();
  mtime_sum = stime;
}


void loop(){
  //bat_volt = analogRead(2);
  //bat_volt *= 113;   // 5 * 45,45         1m + 22 kohm
  loopcount++;
  singleRead();

  diffRead();



  if(flip){

    if(page > viewpagemin && page < viewpagemax){
      if (autoswap == 1){        
        if (timercount > 1){
          altervalue(&page, viewpagemin +1 , viewpagemax -1);
          timercount = 0;
        }      

      }
      else if (autoswap == 2){      
        if (timercount > 3){
          altervalue(&page, viewpagemin +1 , viewpagemax -1);
          timercount = 0;
        } 
      }
      else if (autoswap == 3){      
        if (timercount > 7){
          altervalue(&page, viewpagemin +1 , viewpagemax -1);
          timercount = 0;
        } 
      }    
    }


    menu();

    flip = 0;

  }

  buttoncheck ();

}

void startconversion(){
  ADCSRA |= (1<<ADSC);            // start single conversion
  while (ADCSRA & (1<<ADSC) ) {  
  }     // wait until conversion is done 
  delay(1);

  ADCSRA |= (1<<ADSC);            // start single conversion  
  while (ADCSRA & (1<<ADSC) ) {  
  }     // wait until conversion is done  
  delay(1);
}

void singleRead(){
  adc_off();
  ADCSRB =  _BV(REFS2) ;   
  ADMUX =   _BV(MUX1)  | _BV(REFS1) | _BV(REFS0) ;   
  adc_on();
  startconversion();

  unsigned long bat_mom = ADC * (2560UL * volt_div) /10000000UL;
  adc_bat_sum += bat_mom;

  if(started == 1){    // If my session has startet (measuring 1 milliV average in 1 second)
    if(bat_mom <= low_voltage_detection){      // Detecting 
      //savesession();
//      lcd.clear();
//      lcd.setCursor(0,0);
//      lcd.print ("  - Stopping -  ");
//      wait();        // delay(850);
//      wait();
    }    
    
    if(bat_mom < vmin)vmin = bat_mom;
    else if (bat_mom > vmax)vmax = bat_mom;        
  }

  if(vstart == 0){
      vstart = bat_mom;
      vmin = bat_mom;      
      vmax = bat_mom;
  }

}

I came up with the idea to use the F() macro in order to save some ram but I´m getting following error :

c:/my progs/arduino-1.0.3/hardware/tools/avr/bin/…/lib/gcc/avr/4.3.2/…/…/…/…/avr/bin/ld.exe: lcd_buttons_test6_proto.cpp.elf section .text will not fit in region text
c:/my progs/arduino-1.0.3/hardware/tools/avr/bin/…/lib/gcc/avr/4.3.2/…/…/…/…/avr/bin/ld.exe: region text overflowed by 596 bytes

When i use f() on a “blank” programm it works but consumes like over 1KB of Flash.
I guess it´s not a compiler related problem rather I´m running out of flash ?

I´m using Tom Carpenters core on an Attiny 861A, any help would be appreciated.

When i use f() on a "blank" programm it works but consumes like over 1KB of Flash.

How can you use the F() macro when there is nothing to apply it to? You clearly have some different concept of a "blank progamm" than I do.

You might sprinkle calls to freeMemory() at different point in loop() to see if that's your problem. Check out:

http://playground.arduino.cc/Code/AvailableMemory

The answer to the original question is "yes, you probably do".

If you call freeRam() at setup() or loop() it will only report static memory used.

When you (or an interrupt) calls a function a few bytes are put on the stack (the retirn address) and thats 4 or 8 bytes gone. If you have arguments (C calls by value) or local non-static variables (f.ex. bat_mom in your code) , then that consumes memory, too. Likewise when you call library functions.

Of course only as you nest calls do these add up, rather than just the max of the biggest. Put a freeRam() call somewhere deep inside your functions and see the difference.

How can you use the F() macro when there is nothing to apply it to? You clearly have some different concept of a "blank progamm" than I do.

Sorry with "blank" i meant a sketch initialising a lcd and setting up Tinydebug for testing purposes, that´s why i encircled the blank with "`s ;)

Another method that seems to be even simpler is the following:

Declare this function:

int freeRam () { extern int heap_start, *brkval; int v; return (int) &v - (brkval == 0 ? (int) &heap_start : (int) __brkval); }

and call it anywhere in your program like that: Serial.println(freeRam());

That´s what i used for calculating my available ram and i put it inside my menu output which is located very deep in my programm structure.

*Edit: When i put freeRam where i alter digits of values i get strange results(-13760, 520, 109). buttoncheck() -> menu() -> someothermethod() I guess you mean that with "nest calls" ?

In my menu method i use Strings to print to the display, i guess i could save some ram when i use chars ? http://arduino.cc/en/Reference/string - Found some info about it but it is not clear to me what uses more ram If i use one of the following:

char Str4[ ] = "arduino"; char Str5[8] = "arduino";

it is easy to use but i´m still using Strings to fill my char array, just the printing will be done with a char array instead of a String ?

char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'}; char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};

One of theese would be better in terms of ram usage ?