Thermometer using the TMP36

So I found it feasible to make a thermometer in this heat seeing as I never know what the temperature is.
In this project, I'm using an Arduino Uno, RGB LED (picture below), and a TMP36. If something else comes to mind I might add it in.
Old versions:

Newest Code:

Code:

int temperaturePin = 0;

const int RED_LED_PIN = 9;
const int GREEN_LED_PIN = 10;
const int BLUE_LED_PIN = 11;

int redIntensity = 0;
int greenIntensity = 0;
int blueIntensity = 0;

void setup()
{
  Serial.begin(9600);
}
void loop() {

  float temperature = getVoltage(temperaturePin);

  // 9/5 (C+32
  temperature = (temperature - .5) * 100/*)* 1.8) + 32*/;
  float temperature2 = (9/5*(temperature +32));  
  Serial.println(temperature2);                     //printing the result
  delay(1000);

  if (temperature2 >= 89.99){
    blueIntensity = 15;
    greenIntensity = 10;
    redIntensity = temperature2 +15;
  } 
  else {
    if (temperature2 >= 79.99){
      greenIntensity = temperature2 /3+20;
      redIntensity = 0;
      blueIntensity = 0;
    } 

    else {
      if (temperature2 >= 69.99){
        greenIntensity = 5;
        blueIntensity = temperature2 /2;
        redIntensity = 0;
      }
      else {
        // we know temperature2 must be <= 69.98 if it gets to here
        greenIntensity = 63;
        redIntensity = 50;
        blueIntensity = 100;
      }
    }
  }

  redIntensity = constrain(redIntensity, 0, 255);
  greenIntensity = constrain(greenIntensity, 0, 255);
  blueIntensity = constrain(blueIntensity, 0, 255);
  analogWrite(RED_LED_PIN, redIntensity);
  analogWrite(BLUE_LED_PIN, blueIntensity);
  analogWrite(GREEN_LED_PIN, greenIntensity);
} // end of loop()
float getVoltage(int pin){
 return (analogRead(pin) * .004882814); //converting from a 0 to 1023 digital range
                                        // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
}

[Code Updated!]

I will be updating this thread as I go, making further advancements, and most likely asking for help with small snippits of my code

Update 1:

Going to add support for the RGB LED (Link is just a picture)
What it is planned to do:
Change Red Green or blue values accordingly to the temperature.
Progress: ||||||||||about 87%

Needs to be done:

Better color display.
Improved temperature display.

Problems so far:
Cannot get the temperature to display only when there is a drastic change (i.e when it goes up or down by 1 degree.)
Cannot get the Diodes within the LED to light up accordingly. Blue/Green stay on even though at 90+ they are supposed to shut of (see code above). Red is always on as well. It produces a milky white color mos of the time (all 3 diodes are on.)

I think you are better off using the thermometer library maybe that would work. The thermometer IC I got sends some type of serial messages, that may be what you are getting for the voltage. Just a suggestion I'm not familiar with your temp IC.

mykiscool:
I think you are better off using the thermometer library maybe that would work. The thermometer IC I got sends some type of serial messages, that may be what you are getting for the voltage. Just a suggestion I'm not familiar with your temp IC.

I cannot seem to find the Thermometer library?

Hi SimpleMindedMan,

Cannot get the temperature to display only when there is a drastic change (i.e when it goes up or down by 1 degree.)

Even at it's maximum temperate rating of 125C the TMP35 only outputs about 1.7 volts and at it's minimum of -50C is outputs about 0.1 volts. The max reading from analogueRead will be about 348 for 125C and 20 for -50C with the default 5V AREF.
You can improve the accuracy by using external AREF of lower voltage (maybe the 3.3V arduino supply).

Cannot get the Diodes within the LED to light up accordingly. Blue/Green stay on even though at 90+ they are supposed to shut of (see code above). Red is always on as well. It produces a milky white color mos of the time (all 3 diodes are on.)

I'm new to C programming but I don't see what this line does 'greenIntensity <= 255;' also you never turn off the red LED like you do the green and blue ones (blueIntensity = 0;).
Might be worth looking at the map command map() - Arduino Reference

Hope this helps.

I never turn off the red diode because I only turn it on when the temperature hits above 90.
I remember doing a miniature one of these projects a few months ago, and it only displayed if it went up or down by 2 or more.
the redIntensity <= 255; (or what ever, I'm just writing this out real fast), was supposed to be so it knows the max each one of the 3 diodes can only hit 255. I know there is a different way to do it, but i had forgotten how

As you never turn off the red LED then if the temperature rises to 90F or above and then drops again it will never turn off.
For the 'greenIntensity <= 255;' try Constrain constrain() - Arduino Reference or
if (greenIntensity > 255){
greenIntensity = 255;
}

Riva:
As you never turn off the red LED then if the temperature rises to 90F or above and then drops again it will never turn off.
For the 'greenIntensity <= 255;' try Constrain constrain() - Arduino Reference or
if (greenIntensity > 255){
greenIntensity = 255;
}

I remember back when I was programming java you could do something like int greenMAX = 255;
then add it into the code somehow. Just don't remember how to add it in

Hi,

There are a few errors still in the code which won't function as you intend:

greenIntensity - 5;
 ...and later...
   blueIntensity - 15;
   greenIntensity -10;

If you're wanting to assign those values to the variables use = as your operator. There won't be an error generated, but the lines actually won't do anything with that typo. So make like this and you'll get a result:

greenIntensity = 5;

These next lines at the top of loop() will have no effect, since you're over-writing these same variables to different values before you do your analogWrite's to drive the RGB LED:

redIntensity = constrain(redIntensity, 0, 255);
  greenIntensity = constrain(greenIntensity, 0, 255);
  blueIntensity = constrain(blueIntensity, 0, 255);

In the actual logic of your loop() function, there's also a problem which is best illustrated if I remove the code blocks to show just the logic

 if (temperature2 <= 69.98){
// do stuff #1
}

if (temperature2 >= 79.99){
// do stuff #2
}

if (temperature2 >= 69.99){
// do stuff #3
}

if (temperature2 >= 89.99){
// do stuff #4
}

At each point you set the values and drive the LEDs. Unfortunately this won't be achieving what you're setting out to do. Let's take some examples.

For the value 65, stuff #1 is executed correctly and nothing else will fire. So far, so good.
For 85, stuff #2 will happen, then stuff #3, leaving the LED in the state of #3 which is wrong
For 90, #2, #3 and #4 will happen, leaving the LED correctly in state #4, but setting the light wrong along the way

Presumably, the logic you're looking for is to compare the variable to a range and do something or ELSE test for the next range and do that.

So (without making any assumptions as to whether the other code is correct) your loop() could be re-sequenced to look more like this:

void loop() {

  float temperature = getVoltage(temperaturePin);

  // 9/5 (C+32
  temperature = (temperature - .5) * 100/*)* 1.8) + 32*/;
  float temperature2 = (9/5*(temperature +32));  
  Serial.println(temperature2);                     //printing the result
  delay(1000);

  if (temperature2 >= 89.99){
    blueIntensity = 15;
    greenIntensity = 10;
    redIntensity = temperature2 +15;
  } 
  else {
    if (temperature2 >= 79.99){
      greenIntensity = temperature2 /3+20;
      redIntensity = 0;
      blueIntensity = 0;
    } 

    else {
      if (temperature2 >= 69.99){
        greenIntensity = 5;
        blueIntensity = temperature2 /2;
        redIntensity = 0;
      }
      else {
        // we know temperature2 must be <= 69.98 if it gets to here
        greenIntensity = 63;
        redIntensity = 50;
        blueIntensity = 100;
      }
    }
  }

  redIntensity = constrain(redIntensity, 0, 255);
  greenIntensity = constrain(greenIntensity, 0, 255);
  blueIntensity = constrain(blueIntensity, 0, 255);
  analogWrite(RED_LED_PIN, redIntensity);
  analogWrite(BLUE_LED_PIN, blueIntensity);
  analogWrite(GREEN_LED_PIN, greenIntensity);
} // end of loop()

This can certainly be simplified further, but I hope it helps. You'll notice by moving the constrain to the end, it will adjust the variables if necessary only after they've been set; and leaving the analogWrites to the end isn't necessary, but imo does make it much easier to read since there's really no need to duplicate them in amongst all the tests for temperature values.

There is one other thing that I thought when you mentioned the LED is always white - if you have a common anode type RGB LED (where you have one common leg you attach to +5V and the other 3 to the PWM pins on the Arduino) setting the intensity to 0 will actually have the reverse effect of what you might expect - it will drive that colour to full power. And setting the intensity to 255 will turn that colour off. In that situation you'll want to change your analogWrite's to :

analogWrite(RED_LED_PIN, 255-redIntensity);

There's plenty of info out there on common anode RGB LEDs, PWM and Arduino so hit google if that is the type of RGB LED you're using.

Lots of text, I'm sorry. Hope it helps more than it confuses :roll_eyes:
Geoff

There is one other thing that I thought when you mentioned the LED is always white - if you have a common anode type RGB LED (where you have one common leg you attach to +5V and the other 3 to the PWM pins on the Arduino) setting the intensity to 0 will actually have the reverse effect of what you might expect - it will drive that colour to full power. And setting the intensity to 255 will turn that colour off.

Darn, I forgot about that. Good thinking strykeroz

Thanks Strykerz, I'm newer to programming with C

Do you have any suggestions for it to display the temperature per 1 degree change instead of per second (what what ever millisecond time I set.)

Sure, but with only 4 different colours to display whether you change it based on time or temperature it's only going to alter when you cross one of those 10 degree bands so the effect will be the same, surely?

What is it you're trying to achieve?

Geoff

strykeroz:
Sure, but with only 4 different colours to display whether you change it based on time or temperature it's only going to alter when you cross one of those 10 degree bands so the effect will be the same, surely?

What is it you're trying to achieve?

Geoff

I don't know how to explain why I want it to show per 1 degree change. It just looks better, in my opinion, if it displays per 1+- degree change instead of every second.

Actually since your LED is never turned off it would be difficult to tell there was a change, unless you have a different colour for every degree. If you want it to be more immediate that it changes, simply remove the delay. Your Arduino won't mind working harder :slight_smile:

strykeroz:
Actually since your LED is never turned off it would be difficult to tell there was a change, unless you have a different colour for every degree. If you want it to be more immediate that it changes, simply remove the delay. Your Arduino won't mind working harder :slight_smile:

Well, I added the code you created for the loo, and the changes for colors are a little more dramatic. when jumping from 69.99 to 70 it isn't a fluid change of colors, as my initial design intended. Same with 79.99 to 80. But only when it hits over 100 it does a fluid change as the temp increases. (for some reason when you start the serial monitor, or stop it. It displays over 200, and decreases to actual temperature).
Edit: Here's a small data log, about 15 seconds.

162.66
128.48
106.51
94.79
87.96
85.03
83.07
81.61
80.63
80.14
80.14
80.14
80.14
80.14
80.63
80.63
80.63
80.63
81.61
81.61
82.59
82.59
82.10
82.59

There is nothing in your code presently to create a fluid change of colour between each of the 4 steps - as the intensity values are set instantly from one value to the next. You could move from one colour to the next utilising a loop quite simply though. You will need to store the current colour and each iteration set your RGB values a step nearer the next colour until all 3 values are where they need to be. This is the kind of thing you'll often see in Arduino RGB mood lights, so a bit of google-fu and you should find plenty of examples if you're looking for inspiration.

Cheers ! Geoff

I do have an example of some code that changes through all the colors for a RGB LED, the issue is initializing it for it to change accordingly to the temperature.

// LED leads connected to PWM pins
const int RED_LED_PIN = 9;
const int GREEN_LED_PIN = 10;
const int BLUE_LED_PIN = 11;

// Used to store the current intensity level of the individual LEDs
int redIntensity = 0;
int greenIntensity = 0;
int blueIntensity = 0;

// Length of time we spend showing each color
const int DISPLAY_TIME = 100; // In milliseconds


void setup() {
  // No setup required.
}

void loop() {
  // Cycle color from red through to green
  // (In this loop we move from 100% red, 0% green to 0% red, 100% green)
  for (greenIntensity = 0; greenIntensity <= 255; greenIntensity+=5) {
        redIntensity = 255-greenIntensity;
        analogWrite(GREEN_LED_PIN, greenIntensity);
        analogWrite(RED_LED_PIN, redIntensity);
        delay(DISPLAY_TIME);
  }

  // Cycle color from green through to blue
  // (In this loop we move from 100% green, 0% blue to 0% green, 100% blue)  
  for (blueIntensity = 0; blueIntensity <= 255; blueIntensity+=5) {
        greenIntensity = 255-blueIntensity;
        analogWrite(BLUE_LED_PIN, blueIntensity);
        analogWrite(GREEN_LED_PIN, greenIntensity);
        delay(DISPLAY_TIME);
  }

  // Cycle cycle from blue through to red
  // (In this loop we move from 100% blue, 0% red to 0% blue, 100% red)    
  for (redIntensity = 0; redIntensity <= 255; redIntensity+=5) {
        blueIntensity = 255-redIntensity;
        analogWrite(RED_LED_PIN, redIntensity);
        analogWrite(BLUE_LED_PIN, blueIntensity);
        delay(DISPLAY_TIME);
  }
}

I just wouldn't have a clue on how to make it more fluid like the above code.

Sorry for the double post, but I just wanted a quick quick bump to page 1.