Loop randomly resets at 179 while reading temperature

Hi,i am a bit new to this whole arduino world but i have a small previous C# coding experience,i've just received my arduino Starter Kit and started building project 3,then i decided try creating a sketch that reads the temperature and elaboretes an average temperature with this code:

const int termoPin = A5;
float totVal = 0;
//int tot_i = 1;
//int i = 0;
void setup() {
  Serial.begin(9600);
}

void loop() {
  int tot_i = 1;  //max array value number counter
  int i = 0;      //array reference counter
  for(int l = 0;l < 10000;l++) {  //reset to avoid "cloging" the average temperature value
    int termoVal[tot_i];
    float voltage[tot_i];
    float temp[tot_i];
    termoVal[i] = analogRead(termoPin);
    voltage[i] = (termoVal[i] / 1024.0) * 5.0;  //conversion from analog valute to voltage
    temp[i] = (voltage[i] - 0.47) * 100;        //conversion from voltage to temperature in celsius
    totVal = temp[i] + totVal;
    float totMedia = totVal / i;  //average temperature
    Serial.println(totMedia);
    Serial.println(i);
    delay(500);
    tot_i++;
    i++;
  }
  Serial.println("Cleared");
}

After i start running the sketch trough my Arduino Uno R3 connected to the sensor it sarts creating the average temperature with a good accuracy,but when the loop reaches the value 171 it suddently restart (without printing the sentence "Cleared").

Welcome to the forum

The for loop iterates 10000 times
How much memory will these 3 arrays need when tot_i reaches its maximum value ?

        int termoVal[tot_i];
        float voltage[tot_i];
        float temp[tot_i];

There are other problems too, but solve the one above first

So what should I do?

Do you understand the problem ?

Each level of those 3 arrays needs 10 bytes (2 floats - 4 bytes each and 1 int - 2 bytes)

Your code attempts to create 10000 levels of each array which would need 100000 bytes of storage

Even if the Uno had that much memory your sketch repeatedly declares the 3 arrays in the for loop thus overwriting any values that have already been written to them

Start by explaining what you are trying to do with the sketch and there may be an approach that allows you to use the Uno

first iteration of the for-loop
define arrays with two elements 0,1

second iteration of the for-loop
define arrays with three elements 0,1,2

third iteration of the for-loop
define arrays with four elements 0,1,2,4

10000 iteration
define arrays with 10001 elements 0,1,2,4.....10000

does this make sense?

How much RAM-memory does your microcontroller have?

After reading your previous answer after a hot shower I had an Eureka,so basically I was creating and storing many arrays instead of just changing the value of the valuable one.Thank you so much for your help.

You are creating new arrays with the same names as previous ones thus losing previously stored values until the new arrays are too big to fit in the memory available

How much kB of RAM does your microcontroller have?

How many kB of RAM do you need for a 10000 element array?

There is a different way to obtain an averaged value with a few bytes
even if you would like to use 1 million measurements.

1 Like

I changed my code and now it works fine:

const int termoPin = A5;
int i;
int termoVal;
float totVal;
float temp;
void setup() {
  Serial.begin(9600);
}
void loop() {
  i = 0;
  temp = 0;
  termoVal = 0;
  totVal = 0;
  for (int l = 0; l < 10000; l++) {  //reset per non "intasare" la media in caso di cambio di temperatura
    termoVal = analogRead(termoPin);
    temp = (((termoVal / 1024.0) * 5.0 - 0.484) * 100);  //conversione da valore analogico a voltaggio
    totVal = temp + totVal;
    float totMedia = totVal / i;  //media basata sul numero di cicli
    Serial.println(totMedia);
    i++;
  }
  for (int p = 0; p <= 100; p++) {
    Serial.println("Cleared");
  }
}

Thank for your help and i will apreciate further suggestion.

What is the purpose of the last for loop in the loop() function ?

I used it in testing phase to create an easy solution to see when the loop restarts, it's basically useless and I will take it out after some more smaller improvements.

Here is a code-version with two modifications

The averaged value is printed only once every 500 milliseconds

The code waits for a button-press of a button that is connected between IO-pin 4 and GND

const byte termoPin = A5;
int i;
int termoVal;
float totVal;
float temp;

const byte myButtonPin = 4; 

void setup() {
  pinMode(myButtonPin,INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Setup-Start");
}


void loop() {
  Serial.println("Starting measuring......");
  i = 0;
  temp = 0;
  termoVal = 0;
  totVal = 0;
  for (int l = 0; l < 10000; l++) {  //reset per non "intasare" la media in caso di cambio di temperatura
    termoVal = analogRead(termoPin);
    temp = (((termoVal / 1024.0) * 5.0 - 0.484) * 100);  //conversione da valore analogico a voltaggio
    totVal = temp + totVal;
    float totMedia = totVal / i;  //media basata sul numero di cicli

    // only once every 500 milliseconds print i and totMedia
    if (millis() % 500 == 0) {
      Serial.print("i:");
      Serial.print(i);
      Serial.print(" totMedia=");
      Serial.println(totMedia);
    }
    i++;
  }

  Serial.println("press button to start new averaging");
  while (digitalRead(myButtonPin) == HIGH) {
    // keep looping this while-loop until button is pressed
    // digitalRead(myButtonPin) results in LOW when the button is pressed
  }
}

best regards Stefan

Thank you Stefan

What is the value of ā€œiā€ the first time this instruction executes?

It's the counter for the number of temperatures registered,it starts by the value of 0 and grows of 1 by any cycles,so I can also use it for the average formula as the total number to divide with.

The point is that as it starts with a value of zero then

float totMedia = totVal / i;

will not work the first time round

so i just need to change it to 1?

That sounds like a good idea

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.