Temperature sensor + Leds

Hello!
I came up with an idea to use temperature sensor and leds to indicate the temperature value. I found LadyAda-s tutorial Temperature sensor tutorial - Using the TMP36 / LM35, 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..

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

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

sp. "degrees" :wink:

sp. "degrees"

right ..

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

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

Maybe it is better to use:

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

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

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

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

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!

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.

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.

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);
}

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.

I tried to make what you were suggesting, please comment.

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);
> [/quote]

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.

tempc += analogRead (pin);

Just don't forget to zero "tempc" before the loop.

So the final code should be:

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.

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:

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.

if i put float in front of last "tempc" i get the decimal places, but all numbers are zeros.

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

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

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

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
}

When you put float in front of tempc, you created a local variable with the same name as the global variable, with an initial value of 0.0.

From that point on, all references to tempc are to the local variable, until it goes out of scope.

So, the 0.0 values are not surprising.

You need to change the type of the global variable to float, not create a local variable.

I loathe unecessary globals:

const int pin = 0; // analog pin
float maxi = -100.0;
float mini = 100.0; // to start max/min temperature

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

void loop()
{
  float tempc = 0.0;

  for(int i = 0; i < 8; 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, 2);  //or however many decimal places you need
  Serial.print(" Celsius, ");

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

  delay(1000); // delay before loop
}

Using PaulS suggestions ended up like this

int pin = 0; // analog pin
int tempc = 0; // temperature variables
int tempb = 0;
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 tempb = (5.0 * tempc * 100.0) / (8.0 * 1024.0);

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

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

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

tempc = 0;
tempb = 0;

delay(1000); // delay before loop
}

And serial monitor

23.4375000000 Celsius, 23 Max, 23 Min
23.4375000000 Celsius, 23 Max, 23 Min

...

int tempb = 0;

Why?

Serial.print(tempb,DEC);

Isn't ten places of decimals excessive?

AWOL,
using your code, serial monitor show this:

23.44 Celsius, 10111 Max, 10111 Min
23.44 Celsius, 10111 Max, 10111 Min
...

It is good that eventually there are 2 decimal places, but have to manage out why are Max / Min displayed in binary ( is it bin ? )

Serial.print(tempc, 2); -> shows 23.44
but
Serial.print(maxi, 2); -> shows 11010