Go Down

Topic: Temperature sensor + Leds (Read 5 times) previous topic - next topic

D3C3PT1C0N

May 19, 2010, 09:55 am Last Edit: May 19, 2010, 10:28 am by Fredx Reason: 1
Hello!
I came up with an idea to use temperature sensor and leds to indicate the temperature value. I found LadyAda-s tutorial http://www.ladyada.net/learn/sensors/tmp36.html, and now i want to add leds, so that when the temperature is under 0 degrees the blue led is on, when the temp is over 0 degrees the green led is on and when it is over 20 degrees the red led is on. Actually I have no idea, how to integrate leds to the temperature code. Maybe someone here can help..
Code: [Select]


//TMP36 Pin Variables
int sensorPin = 0; //the analog pin the TMP36's Vout (sense) pin is connected to
                       //the resolution is 10 mV / degree centigrade with a
                       //500 mV offset to allow for negative temperatures

#define BANDGAPREF 14   // special indicator that we want to measure the bandgap

/*
* setup() - this function runs once when you turn your Arduino on
* We initialize the serial connection with the computer
*/
void setup()
{
 Serial.begin(9600);  //Start the serial connection with the computer
                      //to view the result open the serial monitor
 delay(500);
}

void loop()                     // run over and over again
{
 // get voltage reading from the secret internal 1.05V reference
 int refReading = analogRead(BANDGAPREF);  
 Serial.println(refReading);
 
 // now calculate our power supply voltage from the known 1.05 volt reading
 float supplyvoltage = (1.05 * 1024) / refReading;
 Serial.print(supplyvoltage); Serial.println("V power supply");
 
 //getting the voltage reading from the temperature sensor
 int reading = analogRead(sensorPin);  

 // converting that reading to voltage
 float voltage = reading * supplyvoltage / 1024;

 // 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 ((volatge - 500mV) times 100)
 Serial.print(temperatureC); Serial.println(" degress C");

 // now convert to Fahrenheight
 float temperatureF = (temperatureC * 9 / 5) + 32;
 Serial.print(temperatureF); Serial.println(" degress F");

 delay(1000);                                     //waiting a second
}



Groove

#1
May 19, 2010, 10:03 am Last Edit: May 19, 2010, 10:08 am by GrooveFlotilla Reason: 1
Per Arduino ad Astra

D3C3PT1C0N

#2
May 19, 2010, 10:11 am Last Edit: May 19, 2010, 10:32 am by Fredx Reason: 1
Code: [Select]
sp. "degrees"
right ..

Is it really that simple?
Part of the code taken from my first post:
Code: [Select]

// now print out the temperature
 float temperatureC = (voltage - 0.5) * 100 ;  

if (temperatureC < 0){
 digitalWrite(LEDpin1, HIGH);
 digitalWrite(LEDpin2, LOW);
 digitalWrite(LEDpin2, LOW);
}

if (temperatureC > 0){
 digitalWrite(LEDpin1, LOW);
 digitalWrite(LEDpin2, HIGH);
 digitalWrite(LEDpin2, LOW);
}

if (temperatureC > 20){
 digitalWrite(LEDpin1, LOW);
 digitalWrite(LEDpin2, LOW);
 digitalWrite(LEDpin2, HIGH);
}


Is this correct, when i write temperatureC > 0 and temperatureC > 20 - does it change the led or both are going to be ON ? I want that only one led is on..

D3C3PT1C0N

#3
May 19, 2010, 10:25 am Last Edit: May 19, 2010, 10:38 am by Fredx Reason: 1
Maybe it is better to use:
Code: [Select]

// Under 0 degrees blue led is on
if (temperatureC < 0){
 digitalWrite(LEDpin1, HIGH);
 digitalWrite(LEDpin2, LOW);
 digitalWrite(LEDpin2, LOW);
}

// Over 20 degrees red led is on
else if (temperatureC > 20)
{
 digitalWrite(LEDpin1, LOW);
 digitalWrite(LEDpin2, LOW);
 digitalWrite(LEDpin2, HIGH);
}

// All that is left (0 - 20 degrees), the green led is on
else
{
 digitalWrite(LEDpin1, LOW);
 digitalWrite(LEDpin2, HIGH);
 digitalWrite(LEDpin2, LOW);
}

Groove

Just to avoid grief, whenever you're dealing with "float"s or "double"s, particularly if you're mixing them with "integer types,  always try to include the decimal point on constants.
e.g.
Code: [Select]
float supplyvoltage = (1.05 * 1024[glow].[/glow]0) / refReading;

Sometimes, they're not necessary, but get into the habit and you'll have a lot less hair-tearing.
Per Arduino ad Astra

D3C3PT1C0N

Thanks. Gonna try it as soon as I arrive home.

D3C3PT1C0N

As I bought temperature sensor LM35CZ, there is actually better script:

Code: [Select]
Code*****
/*

An open-source LM35DZ Temperature Sensor for Arduino. (cc) by Daniel Spillere Andrade

*/

int pin = 0; // analog pin
int tempc = 0,tempf=0; // temperature variables
int samples[8]; // variables to make a better precision
int maxi = -100,mini = 100; // to start max/min temperature
int i;

void setup()
{
Serial.begin(9600); // start serial communication
}

void loop()
{


for(i = 0;i<=7;i++){ // gets 8 samples of temperature

samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
tempc = tempc + samples[i];
delay(1000);

}

tempc = tempc/8.0; // better precision
tempf = (tempc * 9)/ 5 + 32; // converts to fahrenheit

if(tempc > maxi) {maxi = tempc;} // set max temperature
if(tempc < mini) {mini = tempc;} // set min temperature

Serial.print(tempc,DEC);
Serial.print(" Celsius, ");

Serial.print(tempf,DEC);
Serial.print(" fahrenheit -> ");

Serial.print(maxi,DEC);
Serial.print(" Max, ");
Serial.print(mini,DEC);
Serial.println(" Min");

tempc = 0;

delay(1000); // delay before loop
}

END OF CODE*****


Working Great!

PaulS

Code: [Select]
samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;

You don't use the values in the samples array again. Why bother storing the values in an array?

Since multiplication and division are not fast on the Arduino, you'd be better off just adding up the values read, in the loop, and then performing the multiplication and division on the average reading, after the loop.

D3C3PT1C0N

#8
May 20, 2010, 01:53 pm Last Edit: May 20, 2010, 02:12 pm by Fredx Reason: 1
I made the code a little shorter by removing the calculation of 8 samples and Fahrenheit. Haven't tried it but i hope it works.

Code: [Select]

int pin = 0; // analog pin
int tempc = 0; // temperature variables
int maxi = -100,mini = 100; // to start max/min temperature
int ledPin =  13;

void setup()
{
Serial.begin(9600); // start serial communication
pinMode(ledPin, OUTPUT);
}

void loop()
{
tempc = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;

if(tempc > maxi) {maxi = tempc;} // set max temperature
if(tempc < mini) {mini = tempc;} // set min temperature

if (tempc > 22){
digitalWrite(ledPin, HIGH);
}

if (tempc < 22){
digitalWrite(ledPin, LOW);
}

Serial.print(tempc,DEC);
Serial.print(" Celsius, ");

Serial.print(maxi,DEC);
Serial.print(" Max, ");
Serial.print(mini,DEC);
Serial.println(" Min");

tempc = 0;

delay(1000);
}

AWOL

Quote
I made the code a little shorter by removing the calculation of 8 samples

"I made the code more prone to noisy readings by removing the calculation of 8 samples "

As PaulS said, just sum a number of raw readings into an appropriately large data type, and do the arithmetic after you've collected a number.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

D3C3PT1C0N

#10
May 21, 2010, 08:51 am Last Edit: May 21, 2010, 09:49 am by Fredx Reason: 1
I tried to make what you were suggesting, please comment.

Quote

Old verison

for(i = 0;i<=7;i++)
{
samples = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
tempc = tempc + samples;
delay(1000);
}

tempc = tempc/8.0; // better precision



Quote

New verison

for(i = 0;i<=7;i++)
{
samples = analogRead(pin);
tempc = tempc + samples;
delay(500);
}

tempc = (5.0 * tempc * 100.0) / (8.0 * 1024.0);

Groove

#11
May 21, 2010, 09:46 am Last Edit: May 21, 2010, 09:47 am by GrooveFlotilla Reason: 1
Why are you storing the results in an array?
You're not using the results afterwards, or doing a rolling average or a median filter or anything that requires a discrete sample history, so there's no need for the array.
Code: [Select]
tempc += analogRead (pin);
Just don't forget to zero "tempc" before the loop.
Per Arduino ad Astra

D3C3PT1C0N

#12
May 21, 2010, 09:59 am Last Edit: May 21, 2010, 10:18 am by Fredx Reason: 1
So the final code should be:

Quote

int pin = 0; // analog pin
int tempc = 0; // temperature variables
int maxi = -100,mini = 100; // to start max/min temperature
int i;

void setup()
{
Serial.begin(9600); // start serial communication
}

void loop()
{

for(i = 0;i<=7;i++)
{
tempc += analogRead(pin);
}

tempc = (5.0 * tempc * 100.0) / (8.0 * 1024.0);


if(tempc > maxi) {maxi = tempc;} // set max temperature
if(tempc < mini) {mini = tempc;} // set min temperature

Serial.print(tempc,DEC);
Serial.print(" Celsius, ");

Serial.print(maxi,DEC);
Serial.print(" Max, ");
Serial.print(mini,DEC);
Serial.println(" Min");

tempc = 0;

delay(1000); // delay before loop
}


How do I make Arduino to display decimal places? When i open the serial monitor, it only shows 22 degrees, but I want 22,5 degrees. In data-sheet it is said that the temperature sensor LM35 has precision of 0,1 degrees.

Groove

Well, "tempc" is an integer, so doesn't have any places after the decimal point.
You could make it a float, which would make more sense here:
Code: [Select]
tempc = (5.0 * tempc * 100.0) / (8.0 * 1024.0);


You can still sum your integer readings into it.

0018 allows you to specify the number of decimal places with the print or println method.
Per Arduino ad Astra

D3C3PT1C0N

#14
May 21, 2010, 07:50 pm Last Edit: May 21, 2010, 07:57 pm by Fredx Reason: 1
if i put float in front of last "tempc" i get the decimal places, but all numbers are zeros.

Quote

for(i = 0;i<=7;i++)
{
tempc += analogRead(pin);
}

float tempc = (5.0 * tempc * 100.0) / (8.0 * 1024.0);



Quote
Output without FLOAT:
14 Celsius, 14 Max, 14 Min
14 Celsius, 14 Max, 14 Min



Quote
Output with FLOAT:
0.0000000000 Celsius, 0 Max, 0 Min
0.0000000000 Celsius, 0 Max, 0 Min



I tried other variations but no luck.

Here is the whole code using float
Code: [Select]

int pin = 0; // analog pin
int tempc = 0; // temperature variables
int maxi = -100,mini = 100; // to start max/min temperature
int i;

void setup()
{
Serial.begin(9600); // start serial communication
}

void loop()
{

for(i = 0;i<=7;i++)
{
tempc += analogRead(pin);
}

float tempc = (5.0 * tempc * 100.0) / (8.0 * 1024.0);

if(tempc > maxi) {maxi = tempc;} // set max temperature
if(tempc < mini) {mini = tempc;} // set min temperature

Serial.print(tempc,DEC);
Serial.print(" Celsius, ");

Serial.print(maxi,DEC);
Serial.print(" Max, ");
Serial.print(mini,DEC);
Serial.println(" Min");

tempc = 0;

delay(1000); // delay before loop
}

Go Up