problem with float array

Here is some code to calculate values at various temperatures. It works if “calculatedTemp” is of type int.
I would like it to be of type float, but the program crashes. I saw something about PROGMEM, but this is saying it is for READONLY. Any suggestions how I can have a float calculatedTemp[425] array?

Thanks.

int calculatedTemp[425];

void createTemperatureTable(void)
{
  int i = 0;
  float c;
  int  fahrenheit;
  float RTD;
  int   iRTD;
  
  for (i=0;i<10;i++){
    fahrenheit = i - 325;        //Fahrenheit temperature
    c = (float) (5.0/9.0)*(fahrenheit - 32.0);
    //c = i - 200;
    if (c < 0)
      RTD = 10000.0*(1.0 + (A_RTD*c) + (B_RTD*c*c) + (C_RTD*(c-100)*c*c*c) );
    else
      RTD = 10000.0*(1.0 + (A_RTD*c) + (B_RTD*c*c));
    iRTD = round(RTD);
    
    calculatedTemp[i] = iRTD;
    Serial.print(fahrenheit);
    Serial.print(" ");
    Serial.print(c);
    Serial.print(" ");
    Serial.println(calculatedTemp[i]);
  }
}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

Each float takes 4 bytes of memory, so the array is eating up 1700 bytes of SRAM memory, and you only have 2K total (assuming a 328 chip). My guess is that, since SRAM must handle all of the variables (heap and stack), I'd guess you're running out of memory when you try to use floats. You could use PROGMEM, which moves the array from SRAM to program memory. See:

Good thought, but I reduced the loop to just 10 calculations (40 bytes) and I still had the issue. If you run the code it fails after the first calculation, unless it is calculating the RAM it needs during compilation.

imsmooth:
Posts: 50

You’ve been here long enough to know the drill. Use
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags when posting code.

imsmooth:
If you run the code...

And how would we do that? Magic wand?

sketch_mar10a.ino: In function 'void createTemperatureTable()':
sketch_mar10a.ino:16: error: 'A_RTD' was not declared in this scope
sketch_mar10a.ino:16: error: 'B_RTD' was not declared in this scope
sketch_mar10a.ino:16: error: 'C_RTD' was not declared in this scope
sketch_mar10a.ino:18: error: 'A_RTD' was not declared in this scope
sketch_mar10a.ino:18: error: 'B_RTD' was not declared in this scope

So this code works. I extracted it from the main program. The comment about the RAM issue seems to be the problem. I guess the compiler reserves the space with my

float Pt100[426]

declaration. Somewhere between a size of Pt100[326] and Pt100[426] the program crashes even if I don’t call the createTemperatureTable routine in my true program. This one still works unless I make the array bigger.

The question becomes how can I tell how much SRAM I’m using in total? Is there a way to generate a tally?

#include <arduino.h> 

#define A_RTD 0.0039083
#define B_RTD -0.0000005775
#define C_RTD -0.000000000004183
    

int   iPt100[426];
//float Pt100[426];

void createTemperatureTable(void)
{
  int i = 0;
  float c;
  int  fahrenheit;
  float RTD;
  int   iRTD;
  
  for (i=0;i<=426;i++){
    fahrenheit = i - 325;        //Fahrenheit temperature
    c = (float) (5.0/9.0)*(fahrenheit - 32.0);
    //c = i - 200;
    if (c < 0)
      RTD = 10000.0*(1.0 + (A_RTD*c) + (B_RTD*c*c) + (C_RTD*(c-100)*c*c*c) );
    else
      RTD = 10000.0*(1.0 + (A_RTD*c) + (B_RTD*c*c));
    iRTD = round(RTD);
    
    iPt100[i] = iRTD;
    //Pt100[i] = RTD/100;               //Does not work if the array is much bigger
 
    Serial.print(fahrenheit);
    Serial.print(" ");
    Serial.print(c);
    Serial.print(" ");
    Serial.println(Pt100[i]);
  }
}

void setup()
{
  Serial.begin(9600);
  createTemperatureTable();

}

void loop()
{
  while (1)
  {
  }
}

If you can calculate the values that you want to store in your floating point array, why do you want to store them? You are simply going to run out of space.

There are 425 floating data points and I don't want to type them by hand. I have solved my problem by just storing the number as an integer, knowing it is 100x larger than needed. This works out fine.

imsmooth:
There are 425 floating data points and I don't want to type them by hand. I have solved my problem by just storing the number as an integer, knowing it is 100x larger than needed. This works out fine.

What are you aiming to do with the stored values ? Could you not calculate each value as it is needed instead of storing them all ?

I'm as confused as UKHeliBob: what you are doing doesn't make sense.

If you can calculate a number, you don't need to store it OR type it in.

As you have been told:-

int   iPt100[426];
float Pt100[426];

Uses 426 * 4 + 426 *2 = which is 2.5K of the 2K available.

Here is the reason. The 425 stored values serve as interpolation points for finer resolution. Each point is 1 degree. The ADC can measure much better so I can have degrees in tenths. This gives me 4250 values. The ADC input will be between two data points. I need to use two points as a reference to find out which temperature I am close to rather do this in real-time and interpolate the value. The ADC gives me the RTD number. I need the temperature number. I would have to solve a third-order quadratic with interation every second.

Grumpy_Mike:
As you have been told:-

int   iPt100[426];

float Pt100[426];



Uses 426 * 4 + 426 *2 = which is 2.5K of the 2K available.

In the actual code I only had one of these declared.

Here is the reason. The 425 stored values serve as interpolation points for finer resolution. Each point is 1 degree. The ADC can measure much better so I can have degrees in tenths. This gives me 4250 values. The ADC input will be between two data points. I need to use two points as a reference to find out which temperature I am close to rather do this in real-time and interpolate the value. The ADC gives me the RTD number. I need the temperature number. I would have to solve a third-order quadratic with interation every second.

No part of the above argument convinces me of the need to calculate and store a long list of values. If it turns out not to be possible to calculate and interpolate the two points within the allotted time, that might be a reason. However, one second seems like plenty of time to calculate every quantity of interest.

In the actual code I only had one of these declared.

Then why the ***** did you not say, are we supposed to be mind readers or what?
There is no point posting code for comments that is not the code you are using.

It was a typo. When I was going back and forth trying to see what worked and what didn't I forgot to comment one of them out. My mistake grumpy mike.

Still, no one has told me if it is possible to see how much SRAM is being taken by a program other than number crunching every variable. All I see when I compile is the program size.

Still, no one has told me if it is possible to see how much SRAM is being taken by a program other than number crunching every variable.

Then, it should be obvious that the answer is that with 1.0.5 and earlier versions, you can't. With 1.5.5+, you are told how much SRAM will be used when the sketch is loaded, which is NOT the same thing as the amount of SRAM that will be used at any time when the sketch is running. Therefore, the number is over there, by useless.

Just for the fun of it, I ran the routine

void createTemperatureTable(void)

to calculate 100 elements of the table. The entire run took 155 milliseconds, so it take about 1.5 milliseconds per temperature table entry.

Conclusion: there is absolutely no reason to precalculate and store anything, and to do so is simply a waste of precious SRAM.

I couldn't take the badgering, so I got rid of the table and replaced it with a bisection algorithm to calculate the values.