Pages: [1] 2 3   Go Down
Author Topic: Temperature sensor + Leds  (Read 5387 times)
0 Members and 1 Guest are viewing this topic.
Europe, Estonia
Offline Offline
Full Member
***
Karma: 0
Posts: 208
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

//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
}


« Last Edit: May 19, 2010, 03:28:42 am by Fredx » Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://arduino.cc/en/Reference/If


sp. "degrees"   smiley-wink
« Last Edit: May 19, 2010, 03:08:36 am by GrooveFlotilla » Logged

Per Arduino ad Astra

Europe, Estonia
Offline Offline
Full Member
***
Karma: 0
Posts: 208
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
sp. "degrees"
right ..

Is it really that simple?
Part of the code taken from my first post:
Code:
// 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..
« Last Edit: May 19, 2010, 03:32:27 am by Fredx » Logged

Europe, Estonia
Offline Offline
Full Member
***
Karma: 0
Posts: 208
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Maybe it is better to use:
Code:
// 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);
}
« Last Edit: May 19, 2010, 03:38:32 am by Fredx » Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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.
Logged

Per Arduino ad Astra

Europe, Estonia
Offline Offline
Full Member
***
Karma: 0
Posts: 208
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Europe, Estonia
Offline Offline
Full Member
***
Karma: 0
Posts: 208
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 644
Posts: 50452
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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.
Logged

Europe, Estonia
Offline Offline
Full Member
***
Karma: 0
Posts: 208
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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);
}
« Last Edit: May 20, 2010, 07:12:31 am by Fredx » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26525
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

"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.

Europe, Estonia
Offline Offline
Full Member
***
Karma: 0
Posts: 208
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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);
« Last Edit: May 21, 2010, 02:49:04 am by Fredx » Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
tempc += analogRead (pin);
Just don't forget to zero "tempc" before the loop.
« Last Edit: May 21, 2010, 02:47:45 am by GrooveFlotilla » Logged

Per Arduino ad Astra

Europe, Estonia
Offline Offline
Full Member
***
Karma: 0
Posts: 208
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: May 21, 2010, 03:18:06 am by Fredx » Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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.
Logged

Per Arduino ad Astra

Europe, Estonia
Offline Offline
Full Member
***
Karma: 0
Posts: 208
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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
}
« Last Edit: May 21, 2010, 12:57:59 pm by Fredx » Logged

Pages: [1] 2 3   Go Up
Jump to: