Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Need suggestion in Memory consumption reduction

Status
Not open for further replies.

Mithun_K_Das

Advanced Member level 3
Joined
Apr 24, 2010
Messages
899
Helped
24
Reputation
48
Reaction score
26
Trophy points
1,318
Location
Dhaka, Bangladesh, Bangladesh
Activity points
8,253
There is no error or fault here, but I need to find a way to reduce the memory consumption of the following code. If you have any suggestions please suggest.

MCU: PIC16F690, 8bit. Compiler: mikroC pro for PIC v7.6.0
This block is consuming 544 bytes of ROM. How can I reduce a little from here? Other parts are saturated but I need to add some in another part.

All strings [str_xyz] are kept as const char[]; delay(xyz) is simple delay function.

C++:
void edit_parameters(short mode)
{
   switch (mode)
   {
     case 0:
              Lcd_COut(1,5,str_temp);
              temp_set_point1 = EEPROM_Read(temp_address0)*100+EEPROM_Read(temp_address1)*10+EEPROM_Read(temp_address2);
              if(!plus)
              {
                 if(temp_set_point1<400)temp_set_point1++;//50.0'C
                 else temp_set_point1=400;
                 buzzer=1;
              }
              if(!minus)
              {
                 if(temp_set_point1>0)temp_set_point1--;
                 else temp_set_point1 = 0;
                 buzzer=1;
              }

              EEPROM_Write(temp_address0,(temp_set_point1/100)%10);  while(WR_bit);
              EEPROM_Write(temp_address1,(temp_set_point1/10)%10);  while(WR_bit);
              EEPROM_Write(temp_address2,(temp_set_point1/1)%10);  while(WR_bit);
           
              temp_set_point1 = EEPROM_Read(temp_address0)*100+EEPROM_Read(temp_address1)*10+EEPROM_Read(temp_address2);
              temp_setpoint = 700 + temp_set_point1;

              display_temp(2,0,temp_setpoint);
              delay(150);
              buzzer=0;
              break;
     case 1:
              Lcd_COut(1,5,str_on);
              Lcd_COut(1,9,str_time);
              on_time =  EEPROM_Read(on_time_address);
              if(!plus)
              {
                 if(on_time<255)on_time++;
                 else on_time=255;
                 buzzer=1;
              }
              if(!minus)
              {
                 if(on_time>1)on_time--;
                 else on_time=1;
                 buzzer=1;
              }
              on_time_minute = (int)(on_time/60);
              on_time_second =  on_time-(on_time_minute*60);
              disp_time(2,1,on_time_minute,on_time_second);
              Lcd_COut(2,10,str_mm_ss);
              EEPROM_Write(on_time_address,on_time);
              while(WR_bit);
              delay(150);
              buzzer=0;
              break;
     case 2:
              Lcd_COut(1,5,str_off);
              Lcd_COut(1,9,str_time);
              off_time =  EEPROM_Read(off_time_address);
              if(!plus)
              {
                 if(off_time<59)off_time++;
                 else off_time=59;
                 buzzer=1;
              }
              if(!minus)
              {
                 if(off_time>1)off_time--;
                 else off_time=1;
                 buzzer=1;
              }
              disp_time(2,1,off_time,0);
              Lcd_COut(2,10,str_mm_ss);
              EEPROM_Write(off_time_address,off_time);
              while(WR_bit);
              delay(150);
              buzzer=0;
              break;
     break;
   }
}
--- Updated ---

Also in this block how can I reduce some memory consumption?


C++:
//temp_sensing
/******************************************************************************/
int k=0;
unsigned int temp;
bit temp_read_ok;
unsigned int temperature=0;
float average=0.0;
/******************************************************************************/
void read_temp()
{
    temperature=0;
    TRISA0_bit = 1;
    ADCON0=0x01;//select adc0
    ADCON1=0x00;//2uS per sample
    ANSEL=0x01;
    ANSELH=0x00;
    for(k=0;k<=10;k++)
    {
      temp = ADC_Read(0);
      average = (unsigned int)temp;
      average = ((1023 /average)-1);
      average = 10000/average; // get the resistor value
      average = average/10000; // R/Ro
      average = log(average); // temp = log(R/Ro)
      average /= 3950; // 1/B
      average += 1.0/(25.00 + 273.15);
      average = 1.00/average;
      average = ((average-273.15)*1.8)+32.00; // converting K to F.
      temperature += (unsigned int)average*10; //take Temperature data
      delay(50);
    }
    temperature/=10;
    temp_read_ok=1;//read ok
    separation_bit=1;
}
/******************************************************************************/





//
 
Last edited:

Hi,

There are at least three different memories:
* program ROM in microcontroller
* RAM in microcontroller
* EEPROM

Please confirm that you are talking about program ROM only.

If so you should look at the compiler output for what the memory is used:
* included library functions
* your program code
* constants
...

Klaus
--- Updated ---

Some comments about programming:

I see a lot of issue in your read_temp() function.

One question is: Why do you do the averaging?
* to reduce ADC noise --> then just average the ADC value.. and do the temperature calculation afterwards
* or to average real temperature variations. --> then your calculation makes sense somehow.

mathematically there could be a lot improved:
Code:
average = 10000/average; // get the resistor value
average = average/10000; // R/Ro
average = log(average); // temp = log(R/Ro)

you need to know that dividing is more difficult them multiplying.
and multiplying is more difficult than adding or subtracting

could be simplified to this single line:
Code:
average = -log(average); // temp = log(R/Ro)

Why:
the first two lines can be combined to
average = 10000 / average / 10000 = 1 / average
and since log(1/x) = -log(x)
you could replace the "1/average" by simply inverting result of the log() by putting a "-" in front of it.

There are many other issues....

Don´t get me wrong. I don´t say that your code is wrong, but at least it could be simplyfied and thus may reduce code space, RAM usage and save much of processing power.

Klaus
 
Last edited:

    Mithun_K_Das

    Points: 2
    Helpful Answer Positive Rating
Thanks for this suggestion. This code is being used in many units for a long time. Works absolutely fine. But it consumes lots of ROM & RAM comparing to other functions. That is why I'm trying to save some.

For adc noise issue, we can use the average adc result but that will not be the smooth one comparing with the total average. With the total average, we can sense 0.01'F difference with 10bit adc efficiently.
--- Updated ---

RAM consumption can be reduced by simplification of calculations. But here, I see no option. Like, if we use 56/10 rather than 5.6 when multiplying with integer, it saves RAM.
 
Last edited:

Pointers for variables will save you memory, both RAM and ROM.

In interrupts do not call other f()'s if at all possible,. Just set a
flag , return to main, and process. This saves a lot of stack push
and associated code need to manage the stack operations. Also
possible RAM depending on whats coded in ISR

Run simple compiler tests, I found this, over common if statement, in
one compiler, that saves ROM

Myvar = (integer == 5) ? (TRUE) : (FALSE); // Note this just example

I was desperate to get some space back in a 32K limited part, was able to
get ~ 3K back in ROM, by looking at compile and how it handled some
different forms of typing, and use of pointers everywhere. Then I promptly
added more design features and eliminated my margin :). I also examined
ASM listing from compiler to get clues of what to look for/at. Very revealing.

I did some basic stack size trials, but not (in my opinion) thorough enough,
found some bytes there. But you have to be careful, codebase may at a later time
find itself w/o enough stack space if you are not careful. There are tools out there
for some compilers that will help you evaluate that. They in general are pricey.


Regards, Dana.
 
Last edited:

    Mithun_K_Das

    Points: 2
    Helpful Answer Positive Rating
I have no idea what overhead your compiler adds but you might save a few bytes by converting "for(k=0;k<=10;k++)" into a count down to zero, something like "k=10; while(k--) ..." to take advantage of the PICs zero detecting jump instructions.

Brian.
 

    Mithun_K_Das

    Points: 2
    Helpful Answer Positive Rating
If you are using floating point of course if you can convert all operations into integers
do so. But if not some compilers, like GNU or addons have "light" versions which can
save you code.

Even look at Linker settings and the way it pulls libraries in, Some are more atomic
than others, some pull in sections of libraries not needed causing bloat.

The details are in the pudding.....Its surprising what you can find with some detective
work, if you have the time for it.


Regards, Dana.
 

For adc noise issue, we can use the average adc result but that will not be the smooth one comparing with the total average. With the total average, we can sense 0.01'F difference with 10bit adc efficiently.
Mathematically this makes no sense. I just did some Excel tests.
If you do the averaging on ADC_values correctly the result is as smooth as with your method... but it´s more simple.

Don´t know how moch code and RAM it can save.

Klaus
 

Some background on averaging, attached.

Note averaging has a constraint, that is noise needs to be largely uncorrelated.

But in an embedded d3esign with clocks predominant noise source, you guessed it, the
noise is highly correlated so there are diminishing returns from averaging. Buyer
beware.


Regards, Dana.
 

Attachments

  • AtoD averaging.zip
    1.7 MB · Views: 85

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top