Okie doke, I had an issue in another thread unrelated to this specific region of my project, so I felt a new thread was in order- Not to mention I just thought of this…
My project is simple; displaying the temperature from a TMP-36 on an oLED display.
My goal is to be able to average 5 readings and display the calculated average from that.
int sensorPin = 0; //the analog pin the TMP36's Vout (sense) pin is connected to
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void setup() {
Serial.begin(9600);
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)
// init done
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(32,0);
display.print("Temp:");
display.setTextSize(1);
display.setCursor(0,0);
display.print("TMP36");
display.display();
}
void loop() {
int reading = analogRead(sensorPin);
// converting that reading to voltage, for 3.3v arduino use 3.3
float voltage = reading * 5.0;
voltage /= 1024.0;
// print out the voltage
// Serial.print(voltage); Serial.println(" volts");
// now print out the temperature
float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
//to degrees ((voltage - 500mV) times 100)
// Serial.print(temperatureC); Serial.println(" degrees C");
// now convert to Fahrenheit
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
display.setTextColor(WHITE, BLACK);
display.setTextSize(3);
display.setCursor(8,18);
display.print(temperatureF);
display.print("F");
display.setTextSize(1);
display.setCursor(0,40);
display.print(temperatureC);
display.print("C");
display.display();
Serial.print(temperatureF); Serial.println(" degrees F");
delay(750);
}
Is my current code, I don’t know how to store the values in my Arduino in order to do the calculation.
I’ve looked around and I can’t find all that much on this. Thanks everyone, I’m slowly learning!
Here’s one simple way, google “Arduino analog smoothing” for many more.
void setup()
{
Serial.begin(9600);
}
void loop()
{
int total = 0;
for(int i = 0;i < 16;i++) // accumulate 16 readings in total
total += analogRead(A0);
Serial.println(total / 16); // divide by 16 and print
delay(1000);
}
outsider:
Here’s one simple way, google “Arduino analog smoothing” for many more.
void setup()
{
Serial.begin(9600);
}
void loop()
{
int total = 0;
for(int i = 0;i < 16;i++) // accumulate 16 readings in total
total += analogRead(A0);
Serial.println(total / 16); // divide by 16 and print
delay(1000);
}
Can you break this down in detail for me? What does each operator do? Thanks, appreciate it.
void setup()
{
Serial.begin(9600);
}
void loop()
{
int total = 0; // declare a 16 bit signed integer (int)
// named "total"
for(int i = 0;i < 16;i++) // the "for" loop does the next line 16 times
total += analogRead(A0); // Get an analog input reading from pin A0
// and add to total
Serial.println(total / 16); // print the results of total divided by 16
delay(1000); // wait one second
}
{
Serial.begin(9600);
}
void loop()
{
int total = 0; // declare a 16 bit signed integer (int)
// named “total”
for(int i = 0;i < 16;i++) // the “for” loop does the next line 16 times
total += analogRead(A0); // Get an analog input reading from pin A0
// and add to total
Serial.println(total / 16); // print the results of total divided by 16
delay(1000); // wait one second
}
How does int i = 0;i < 16;i++ work? I’d like to familiarize myself with this type of loop as I see it sometimes, but don’t quite understand it.
138.88Favg
137.12 degrees F
136.24Favg
135.36 degrees F
133.60Favg
134.48 degrees F
130.96Favg
131.84 degrees F
I’m doing something wrong, but I can’t figure it out. I want a 30 second average, I heated up the sensor for just a second, if it’s an average, why would it basically reflect the current value?
My code so far
int sensorPin = 0; //the analog pin the TMP36's Vout (sense) pin is connected to
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void setup() {
Serial.begin(9600);
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)
// init done
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(32,0);
display.print("Temp:");
display.setTextSize(1);
display.setCursor(0,0);
display.print("TMP36");
display.display();
}
void loop() {
int total = 0;
for(int i = 0;i < 30;i++) // accumulate 5 readings in total
total += analogRead(A0);
int avg = (total / 30); // divide by 30
// Serial.println(avg);
int reading = analogRead(sensorPin);
/////////////////////////////////////////////////
float voltageavg = avg * 5.0;
voltageavg /= 1024.0;
// now print out the temperature
float temperatureCavg = (voltageavg - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
//to degrees ((voltage - 500mV) times 100)
// Serial.print(temperatureC); Serial.println(" degrees C");
// now convert to Fahrenheit
float temperatureFavg = (temperatureCavg * 9.0 / 5.0) + 32.0;
Serial.print(temperatureFavg);
Serial.println("Favg");
///////////////////////////////////////////////////
float voltage = reading * 5.0;
voltage /= 1024.0;
// now print out the temperature
float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
//to degrees ((voltage - 500mV) times 100)
// Serial.print(temperatureC); Serial.println(" degrees C");
// now convert to Fahrenheit
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
///////////////////////////////////////////////////
display.setTextColor(WHITE, BLACK);
display.setTextSize(3);
display.setCursor(8,18);
display.print(temperatureF);
display.setTextSize(2);
display.print("F");
display.setTextSize(1);
display.setCursor(0,40);
display.print(temperatureC);
display.print("C");
display.display();
Serial.print(temperatureF); Serial.println(" degrees F");
delay(1000);
}
For a rolling average like this, I like to use a software low-pass filter.
double smoothed = some_sensible_initial_value;
void loop() {
if(its time to take a sample) {
double sample = take_a_sample();
smoothed = smoothed * .75 + sample * .25;
}
}
If you tweak the .75/.25, you get a filter that responds quickly or slowly to fluctuations. If you make two filters - a quick one and a slow one - the difference can tell you something about how fast the temperature is changing. Eg, you could ignore the data temperature unless both values more-or-less agree, so filtering out transient spikes.