how to avoid float variables?

Hello all,

I'm in the reduction/ reconstruction of my sketch, the sketch was about 29.863 kbytes and I ended knowing that float numbers consumes 2kbytes at last, do you know how to avoid them.

I wonder if is possible with bitwise operations.

thanks a lot.

It depends on what you are doing with that float variables. If you post your code, it can be easy.
In other hand, I don't understand why you say that :

sketch was about 29.863 kbytes and I ended knowing that float numbers consumes 2kbytes

What kind of memory you are talking about? How do you know it that way?

If you are talking about program memory, if you remove the float variables, it will be more difficult to do that math and so it will consume more program memory (this is not really like this, but if you show the program it will be more easy to see that).

luisilva:
It depends on what you are doing with that float variables. If you post your code, it can be easy.
In other hand, I don't understand why you say that :

sketch was about 29.863 kbytes and I ended knowing that float numbers consumes 2kbytes

Well, I wanted to summarize the story, when a to big sketch is compiled for the arduino, the compiler suggest go to here: http://www.arduino.cc/en/guide/troubleshooting#size

I don't longer has the to big sketch but need to interface with the network (ethernet): his arduino reads the humidity, the the atmosferic presure, temperature and the real time.

Using the modules dht11, bmp180, rtc3231.

the temperature, humidity and pressure are in float.

this is a pice of the sketch, that uses float numbers. this code was write by Leo Nutz

/**********************************************
  Calcualte pressure readings
 **********************************************/
float pressure(int32_t b5)
{
  int32_t x1, x2, x3, b3, b6, p, UP;
  uint32_t b4, b7; 

  UP = read_pressure();                         // Read raw pressure
  Serial.print(F("UP = ")); Serial.print(UP); Serial.println(F(";"));

  b6 = b5 - 4000;
  x1 = (b2 * (b6 * b6 >> 12)) >> 11; 
  x2 = ac2 * b6 >> 11;
  x3 = x1 + x2;
  // b3 = (((ac1 * 4 + x3) << oss) + 2) >> 2; // as per data sheet
  int32_t b3_tmp = ac1; // Split up the equation...
  b3_tmp = (b3_tmp * 4 + x3) << oss;
  b3     = (b3_tmp + 2) / 4;
  x1 = ac3 * b6 >> 13;
  x2 = (b1 * (b6 * b6 >> 12)) >> 16;
  x3 = ((x1 + x2) + 2) >> 2;
  b4 = (ac4 * (uint32_t)(x3 + 32768)) >> 15;
  b7 = ((uint32_t)UP - b3) * (50000 >> oss);
  if(b7 < 0x80000000) { p = (b7 << 1) / b4; } else { p = (b7 / b4) << 1; } // or p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
  x1 = (p >> 8) * (p >> 8);
  x1 = (x1 * 3038) >> 16;
  x2 = (-7357 * p) >> 16;
  return (p + ((x1 + x2 + 3791) >> 4)) / 100.0f; // Return pressure in mbar
}

There is a written library for the bmp180 already
Why not just try to use it.
https://github.com/sparkfun/BMP180_Breakout/archive/master.zip
Looking to your function it seams some rocket sience is happening there :grin:
Anyway since I never play with that sensor I could be wrong.
Try to compare the library with your code ...

My suggestion is to use only integer values. There are two simple solutions how to:

  1. Use integer value x10, x100 or more etc. depending on required precision. For displaying it can be used simply / and % operation.
  2. Use integer value where first 1, 2, 3,... bits represents decimals. It is similar as previous except it is using n-th power of 2. For displaying it can be used also same or bit shift operations.
    The only thing you have to check is possible overflow so you have to use bigger int as usually.

ehrja:
I'm in the reduction/ reconstruction of my sketch, the sketch was about 29.863 kbytes and I ended knowing that float numbers consumes 2kbytes at last, do you know how to avoid them.

you could implement fixed point math instead.

the idea with fixed point is that you use an integer to store the values (and hence, do integer math = faster) but what you do is allocate some of the bits of the integer for the fractional component. for example, if you have a 32 bit integer, and want to reserve 8 bytes for the fraction, you will end up with a number between +/- 2^23-1 with a 1/256 precision 0.0039. if you want higher precision, you can sacrifice more bits, 10 bits will give you 1/1024 precision 0.000976 but reduce the integer portion to +/- 2^21.

fixed point math is pretty simple to write up - it was common before floating point could be handled by the CPU; which isn't a problem for your intel/ARM types these days, but it still is a problem for 8bit CPU like the AVR :stuck_out_tongue:

// data types
typedef int32 fixed;            // 32 bit --> 24:8 precision
#define precision 8             // (change this, need to change sine table)

// fixed mathematical operations
#define Addfx(a,b) (fixed)((fixed)(a) + (fixed)(b))
#define Mulfx(a,b) (fixed)(((fixed)(a) * (fixed)(b)) >> precision)
#define Divfx(a,b) (fixed)(((fixed)(a) << precision) / (fixed)(b))

// fixed mathematical conversions
#define itofx(x) ((fixed)(x) << precision)
#define fxtoi(x) (((fixed)(x)) >> precision)

and then you can use such macro's to do your math. if you need sin(), cos(), tan() et al - you will need to pre-generate a table with the fixed math values in them. you can see an example i wrote years ago here: http://www.mobilewizardry.com/multi-platform/cube3d/application.c.txt

As Budvar10 says, use integer values 10/100/1000 times larger than you need and deal with decimal points etc when the data is displayed, until then it's not important.


Rob

how many floats do you have??? 500?!?

ehrja:
...I ended knowing that float numbers consumes 2kbytes at last, do you know how to avoid them.

they are 4 bytes each, FYI

Have you gone through the sketch putting your string constants into the F() macro already?

not:

Serial.println("My string constant");

instead:

Serial.println(F("My string constant"));

Another code reduction ideas:
Atmel application note AVR035: Efficient C Coding for AVR
I am recommendig to read this despite of it is more advanced.