Go Down

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

#### D3C3PT1C0N

##### May 19, 2010, 09:55 amLast 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 Variablesint 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}`

#1

#### D3C3PT1C0N

#2
##### May 19, 2010, 10:11 amLast 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 amLast 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 onif (temperatureC < 0){  digitalWrite(LEDpin1, HIGH);  digitalWrite(LEDpin2, LOW);  digitalWrite(LEDpin2, LOW);}// Over 20 degrees red led is onelse if (temperatureC > 20){  digitalWrite(LEDpin1, LOW);  digitalWrite(LEDpin2, LOW);  digitalWrite(LEDpin2, HIGH);}// All that is left (0 - 20 degrees), the green led is onelse{  digitalWrite(LEDpin1, LOW);  digitalWrite(LEDpin2, HIGH);  digitalWrite(LEDpin2, LOW);}`

#### Groove

#4
##### May 19, 2010, 10:37 am
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.

#### D3C3PT1C0N

#5
##### May 19, 2010, 01:41 pm
Thanks. Gonna try it as soon as I arrive home.

#### D3C3PT1C0N

#6
##### May 19, 2010, 11:09 pm
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 pinint tempc = 0,tempf=0; // temperature variablesint samples[8]; // variables to make a better precisionint maxi = -100,mini = 100; // to start max/min temperatureint 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 precisiontempf = (tempc * 9)/ 5 + 32; // converts to fahrenheitif(tempc > maxi) {maxi = tempc;} // set max temperatureif(tempc < mini) {mini = tempc;} // set min temperatureSerial.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

#7
##### May 20, 2010, 12:52 pm
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 pmLast 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 pinint tempc = 0; // temperature variablesint maxi = -100,mini = 100; // to start max/min temperatureint 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 temperatureif(tempc < mini) {mini = tempc;} // set min temperatureif (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

#9
##### May 20, 2010, 06:44 pm
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 amLast 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++)
{
tempc = tempc + samples;
delay(500);
}

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

#### Groove

#11
##### May 21, 2010, 09:46 amLast 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.

#### D3C3PT1C0N

#12
##### May 21, 2010, 09:59 amLast 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 = (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

#13
##### May 21, 2010, 11:00 am
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);`

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

#### D3C3PT1C0N

#14
##### May 21, 2010, 07:50 pmLast 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++)
{
}

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 pinint tempc = 0; // temperature variablesint maxi = -100,mini = 100; // to start max/min temperatureint 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 temperatureif(tempc < mini) {mini = tempc;} // set min temperatureSerial.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

Please enter a valid email to subscribe