Save analog values ​​in buffer and processing

Hello!
I have a small circuit with temperature acquisition and value processing, read the comments in the code.

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated
// constants won't change:
const long interval = 500;           // interval at which to blink (milliseconds)
void loop {

int buffer [16];
float val;
int counter = 0;
float temperature;

unsigned long currentMillis = millis();
	if (currentMillis - previousMillis >= interval) { // read analog value every 500ms
	val  = analogRead(pin); // LM35 pin
	buffer[counter] = val; // store the analog value in the buffer
	//Calculate Temperature from analog value
  	//Note that we use mV for Vref
        //Vin = ADCresult*Vref/(2^10)
        //Temp(^C) = Vin/(10) = ADCresult*Vref/(1024*10)
        temp = val*1100/(1024*10); 
	counter ++;
	previousMillis = currentMillis;
	}

if (buffer[16] != NULL){
	// when the buffer fills up, pass all the values to the Serial Monitor and stop the acquisition of temperature
	for (int i = 0; i < 17; i++) {
		Serial.print("Position: "); // buffer[0], buffer[1],...
		Serial.print(i);
		Serial.print(Value: ); // analog value stored in the buffer
		Serial.print(buffer[i]);
		Serial.print("Temeperature: ");
		Serial.println(temp);
		previousMillis = currentMillis; // reset the timer
	}
	// resumes temperature acquisition
}

I'm not even sure how to start, or put it into practice, so I google about it and I wrote all this. Do you think it will work? What else do I miss?
This is the first step, I will have to do something more useful with those temperature values.

Where is the setup() function? Please post complete and verifiable code.

int counter = 0;

That will reset the couter to 0 every time through loop(). You might want to make it static or global scope.

if (buffer[16] != NULL){

There is no buffer[16]. See below.

for (int i = 0; i < 17; i++)

Serial.print(buffer[i]);

That for statement is going to cause a buffer overrun. The elements of the buffer array are numbered 0 to 15.

counter ++;

If you make counter static or global, you will need to reset counter to 0, after 16 iterations, or it will keep counting up forever.

Do you think it will work?

I don't know what "work" means in this context. What does the code actually do? How is that different from what you want?

As I look at that code in more detail I find more things wrong. Undeclared variables and syntax errors among others.

Here is a way to do what, I think, that you want.

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store

unsigned long previousMillis = 0;        // will store last time LED was updated
// constants won't change:
const byte pin = A0;
const long interval = 500;// interval at which to blink (milliseconds)

int buffer [16];

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

void loop()
{
   static int counter = 0;
   
   unsigned long currentMillis = millis();
   if (currentMillis - previousMillis >= interval)   // read analog value every 500ms
   {
      previousMillis = currentMillis; // reset the timer
      float val  = analogRead(pin); // LM35 pin
      buffer[counter] = val; // store the analog value in the buffer
      counter ++;
      if (counter > 16)
      {
         for (int i = 0; i < 16; i++)
         {
            Serial.print("Position: "); // buffer[0], buffer[1],...
            Serial.print(i);
            Serial.print("   ");
            Serial.println(buffer[i]);
         }
         
         unsigned long total = 0;
         for (int n = 0; n < 16; n++)
         {
            total = total + buffer[n];
         }
         float average = total / 16;
         Serial.print ("ave  "); Serial.println(average);
         Serial.print("Average Temeperature: ");
         float mv = ( average / 1024.0) * 5000;
         float celcius = mv / 10;
         Serial.println(celcius);

         counter = 0;
         Serial.println();
      }
   }
}

groundFungus:
As I look at that code in more detail I find more things wrong. Undeclared variables and syntax errors among others.

Here is a way to do what, I think, that you want.

// Generally, you should use "unsigned long" for variables that hold time

// The value will quickly become too large for an int to store

unsigned long previousMillis = 0;        // will store last time LED was updated
// constants won't change:
const byte pin = A0;
const long interval = 500;// interval at which to blink (milliseconds)

int buffer [16];

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

void loop()
{
  static int counter = 0;
 
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)   // read analog value every 500ms
  {
     previousMillis = currentMillis; // reset the timer
     float val  = analogRead(pin); // LM35 pin
     buffer[counter] = val; // store the analog value in the buffer
     counter ++;
     if (counter > 16)
     {
        for (int i = 0; i < 16; i++)
        {
           Serial.print("Position: "); // buffer[0], buffer[1],...
           Serial.print(i);
           Serial.print("   ");
           Serial.println(buffer[i]);
        }
       
        unsigned long total = 0;
        for (int n = 0; n < 16; n++)
        {
           total = total + buffer[n];
        }
        float average = total / 16;
        Serial.print ("ave  "); Serial.println(average);
        Serial.print("Average Temeperature: ");
        float mv = ( average / 1024.0) * 5000;
        float celcius = mv / 10;
        Serial.println(celcius);

counter = 0;
        Serial.println();
     }
  }
}

Hello! Thanks for the reply.
This is literally a "sketch", what it should do is: acquisition of an analog value (from LM35) every 500 ms and store it in a buffer of 10-20 elements (I chose 16); when the buffer is full, the stored values are sent to the Serial Monitor but during this time the data acquisition is stopped. I displayed the data on the Monitor, clear the buffer then resumed the procedure from the beginning with acquisition.
Did you calculate the average temperature? And the condition to check if the buffer is full is that if (counter > 16)?

Did you read the code that I posted? Did you run the code that I posted? What prints in serial monitor?

groundFungus:
Did you read the code that I posted? Did you run the code that I posted? What prints in serial monitor?

I managed to run the program. I think it works pretty well. I added a message that I display when I read data from the sensor, just to know that something is happening, plus a servomotor.

The servo should have the initial position 90 , corresponding to the ambient temperature (somewhere between 21-24 ^ C). If the temperature rises above 24, then the servomotor rotates to 170 * (it can't do 180, cheap servo), if it drops below 18 ^ C than the servomotor positions close to 0 *.
I introduced some if instructions in the program, I think the servo doesn't work very well, it buzzes continuously.

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store

unsigned long previousMillis = 0;        // will store last time LED was updated
// constants won't change:
const byte pin = A0;
const long interval = 500;// interval at which to blink (milliseconds)

int buffer [16];

#include <Servo.h>
Servo myservo;// define servo variable name

void setup()
{
   myservo.attach(9);// select servo pin(9 or 10)
   myservo.write(0);// at the beginning, set the servo close to 0*
   Serial.begin(9600);
}

void loop()
{
   static int counter = 0;
   
   unsigned long currentMillis = millis();
   if (currentMillis - previousMillis >= interval)   // read analog value every 500ms
   {
      previousMillis = currentMillis; // reset the timer
      float val  = analogRead(pin); // LM35 pin
      buffer[counter] = val; // store the analog value in the buffer
      counter ++;
      if (counter > 16)
      {
         for (int i = 0; i < 16; i++)
         {
            Serial.print("Position: "); // buffer[0], buffer[1],...
            Serial.print(i);
            Serial.print("   ");
            Serial.println(buffer[i]);
         }
         
         unsigned long total = 0;
         for (int n = 0; n < 16; n++)
         {
            total = total + buffer[n];
         }
         float average = total / 16;
         Serial.print ("ave  "); Serial.println(average);
         Serial.print("Average Temeperature: ");
         float mv = ( average / 1024.0) * 5000;
         float celcius = mv / 10;
         Serial.println(celcius);
             if (celcius >= 24){ // if temperature is higer than 24^C
                myservo.write(170);// set rotate angle of the motor to 170
             }
              else if (celcius <= 18){ // if tmeperature is less than 18^C
                  myservo.write(15);// set rotate angle of the motor 
              }
               else if ((celcius < 24) && (celcius > 18)) {
                  myservo.write(90);// set rotate angle of the motor 90*
              }
         counter = 0;
         Serial.print("Reading..."); // show a message while getting data from sensor
         Serial.println();
      }
   } // The IF
}

How is the servo powered?

      float val  = analogRead(pin); // LM35 pin
      buffer[counter] = val; // store the analog value in the buffer
      counter ++;

analogRead does not return a float, and buffer is an "int" array.

 if (counter > 16)

Oops.

I missed the float, my bad. Should be int.

counter ++;
      if (counter > 16)

counter is incremented before the comparison so 16 instead of 15.

groundFungus:

counter ++;
  if (counter > 16)


counter is incremented before the comparison so 16 instead of 15.

But that means you'll put a reading into "buffer [16]"

Right, It took a minute but I do see now. Thanks.

Fixed mistakes pointed out by TheMemberFormerlyKnownAsAWOL and removed some magic numbers.

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store

unsigned long previousMillis = 0;        // will store last time LED was updated
// constants won't change:
const byte pin = A0;
const long interval = 500;// interval at which to blink (milliseconds)
const float Vcc = 5.00;

const byte NUM_SAMPLES = 16;
int buffer [NUM_SAMPLES];

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

void loop()
{
   static int counter = 0;
   
   unsigned long currentMillis = millis();
   if (currentMillis - previousMillis >= interval)   // read analog value every 500ms
   {
      previousMillis = currentMillis; // reset the timer
      float val  = analogRead(pin); // LM35 pin
      buffer[counter] = val; // store the analog value in the buffer
      counter ++;
      if (counter >= NUM_SAMPLES)
      {
         for (int i = 0; i < NUM_SAMPLES; i++)
         {
            Serial.print("Position: "); // buffer[0], buffer[1],...
            Serial.print(i);
            Serial.print("   ");
            Serial.println(buffer[i]);
         }
         
         unsigned long total = 0;
         for (int n = 0; n < NUM_SAMPLES; n++)
         {
            total = total + buffer[n];
         }
         float average = total / NUM_SAMPLES;
         Serial.print ("ave  "); Serial.println(average);
         Serial.print("Average Temeperature: ");
         float mv = ( average / 1024.0) * Vcc * 1000;
         float celcius = mv / 10;
         Serial.println(celcius);

         counter = 0;
         Serial.println();
      }
   }
}

wildbill:
How is the servo powered?

I use a different power supply.

groundFungus:
Right, It took a minute but I do see now. Thanks.

Fixed mistakes pointed out by TheMemberFormerlyKnownAsAWOL and removed some magic numbers.

// Generally, you should use "unsigned long" for variables that hold time

// The value will quickly become too large for an int to store

unsigned long previousMillis = 0;        // will store last time LED was updated
// constants won't change:
const byte pin = A0;
const long interval = 500;// interval at which to blink (milliseconds)
const float Vcc = 5.00;

const byte NUM_SAMPLES = 16;
int buffer [NUM_SAMPLES];

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

void loop()
{
  static int counter = 0;
 
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)   // read analog value every 500ms
  {
     previousMillis = currentMillis; // reset the timer
     float val  = analogRead(pin); // LM35 pin
     buffer[counter] = val; // store the analog value in the buffer
     counter ++;
     if (counter >= NUM_SAMPLES)
     {
        for (int i = 0; i < NUM_SAMPLES; i++)
        {
           Serial.print("Position: "); // buffer[0], buffer[1],...
           Serial.print(i);
           Serial.print("   ");
           Serial.println(buffer[i]);
        }
       
        unsigned long total = 0;
        for (int n = 0; n < NUM_SAMPLES; n++)
        {
           total = total + buffer[n];
        }
        float average = total / NUM_SAMPLES;
        Serial.print ("ave  "); Serial.println(average);
        Serial.print("Average Temeperature: ");
        float mv = ( average / 1024.0) * Vcc * 1000;
        float celcius = mv / 10;
        Serial.println(celcius);

counter = 0;
        Serial.println();
     }
  }
}

I notice some changes.
What do you suggest for if I also have a servomotor?

TheMemberFormerlyKnownAsAWOL:
But that means you'll put a reading into "buffer [16]"

Even if I didn't write that program, I still thank you for your remarks and reply. Now I'm trying to introduce a servomotor.

cristian10001:
Now I'm trying to introduce a servomotor.

How's it going?

TheMemberFormerlyKnownAsAWOL:
How's it going?

I managed to run the program. I think it works pretty well. I added a message that I display when I read data from the sensor, just to know that something is happening, plus a servomotor.

The servo should have the initial position 90 , corresponding to the ambient temperature (somewhere between 21-24 ^ C). If the temperature rises above 24, then the servomotor rotates to 170 * (it can't do 180, cheap servo), if it drops below 18 ^ C than the servomotor positions close to 0 *.
I introduced some if instructions in the program, I think the servo doesn't work very well, it buzzes continuously.

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store

unsigned long previousMillis = 0;        // will store last time LED was updated
// constants won't change:
const byte pin = A0;
const long interval = 500;// interval at which to blink (milliseconds)

int buffer [16];

#include <Servo.h>
Servo myservo;// define servo variable name

void setup()
{
   myservo.attach(9);// select servo pin(9 or 10)
   myservo.write(0);// at the beginning, set the servo close to 0*
   Serial.begin(9600);
}

void loop()
{
   static int counter = 0;
   
   unsigned long currentMillis = millis();
   if (currentMillis - previousMillis >= interval)   // read analog value every 500ms
   {
      previousMillis = currentMillis; // reset the timer
      float val  = analogRead(pin); // LM35 pin
      buffer[counter] = val; // store the analog value in the buffer
      counter ++;
      if (counter > 16)
      {
         for (int i = 0; i < 16; i++)
         {
            Serial.print("Position: "); // buffer[0], buffer[1],...
            Serial.print(i);
            Serial.print("   ");
            Serial.println(buffer[i]);
         }
         
         unsigned long total = 0;
         for (int n = 0; n < 16; n++)
         {
            total = total + buffer[n];
         }
         float average = total / 16;
         Serial.print ("ave  "); Serial.println(average);
         Serial.print("Average Temeperature: ");
         float mv = ( average / 1024.0) * 5000;
         float celcius = mv / 10;
         Serial.println(celcius);
             if (celcius >= 24){ // if temperature is higer than 24^C
                myservo.write(170);// set rotate angle of the motor to 170
             }
              else if (celcius <= 18){ // if tmeperature is less than 18^C
                  myservo.write(15);// set rotate angle of the motor
              }
               else if ((celcius < 24) && (celcius > 18)) {
                  myservo.write(90);// set rotate angle of the motor 90*
              }
         counter = 0;
         Serial.print("Reading..."); // show a message while getting data from sensor
         Serial.println();
      }
   } // The IF
}

How is the servo powered? If it is powered by the Arduino that may be the reason that it is buzzing. Servos take quite a bit of current and the Arduino often can't supply enough. An external supply is almost always called for. A 4 AA battery pack works well. Connect the ground of the battery to Arduino ground.

 float val  = analogRead(pin); // LM35 pin
      buffer[counter] = val; // store the analog value in the buffer
      counter ++;
      if (counter > 16)

That needs to be fixed.

 int val  = analogRead(pin); // LM35 pin
      buffer[counter] = val; // store the analog value in the buffer
      counter ++;
      if (counter >= 16)
if (counter > 16)

Again oops.
I thought we'd sorted this.

float val = analogRead(pin); We've regressed.
Are you following this?

TheMemberFormerlyKnownAsAWOL:

if (counter > 16)

Again oops.
I thought we'd sorted this.

float val  = analogRead(pin);

We've regressed.
Are you following this?

I know, I added the servomotor, but I didn't manage yet to update the program according to your observations. I am sorry for this, just a misunderstanding.

groundFungus:
How is the servo powered? If it is powered by the Arduino that may be the reason that it is buzzing. Servos take quite a bit of current and the Arduino often can't supply enough. An external supply is almost always called for. A 4 AA battery pack works well. Connect the ground of the battery to Arduino ground.

 float val  = analogRead(pin); // LM35 pin

buffer[counter] = val; // store the analog value in the buffer
     counter ++;
     if (counter > 16)



That needs to be fixed.


int val  = analogRead(pin); // LM35 pin
     buffer[counter] = val; // store the analog value in the buffer
     counter ++;
     if (counter >= 16)

I know, I added the servomotor, but I didn't manage yet to update the program according to your second program. I am sorry for this, just a misunderstanding.
The servo has it`s own power supply. I think this is happening because in the setup () I set the servo to 0 *, although I don't think I should do that anymore.