Visualizing temperature as color using an RGB led, a LM35 sensor and Arduino


I decided this weekend to work on a mini-project, since it came to my mind during the last week.

I found that my Arduino starter kit actually had an LM35 temperature sensor, it’s just that I noticed that quite late. The LM35 is a sensor that varies its ouput voltage proportionally to the temperature and it’s specially designed for the Celsius scale. The limits of what it can sense is from -55°C to 150°C. You can read more about it if you want from its datasheet.

When I set out to make this mini-project work, I thought it would be really simple to program it. And simple it was, until I had a couple of *facepalm moments.

I wanted to make the LED shine from blue to green, to yellow then red as the temperatures increases. I believe there are probably better methods of accomplishing this, but my logic told me to this:

  • the blue led will be at maximum brightness if the temperatures drops bellow 0°C, and will gradually decrease in intensity from 0°C to 45°C.
  • the green led will increase its brightness from 15°C to 35°C and then will gradually decrease until 75°C
  • the red led will increase its brightness from 45°C to 90°C, and will stay lit after 90°C

That was apparently simple until I opened the Arduino IDE. First of all, I used some code I found on this blog. I was mainly interested on the voltage-to-celsius conversion part, and I build upon that.

The problem was that I had no idea how to correctly decrease the intensity. At first, I instinctively implemented something like the function f(x)=1/x, but that obviously didn’t work. I then figured out that I should use something like f(x)=a-x, where a is a constant defined by me. Using the blue pin as an example, “a” would have been 25. So at 0°C I would have f(o)=25-0=25. At 24°C f(24)=25-24=1. But then that obviously needs to be converted to a value between 0 and 255, because that’s how PWM works on Arduino.

But then somebody suggested I use the map function with reversed values here. That was a glorious *facepalm moment. It was that simple! All I had to do was: map(tempC, 0, 25, 255, 0);

It’s not a perfect code, it’s not the perfect solution, but it works. Here’s the code:

float tempC;
int tempPin = 0;
int redPin= 3;
int greenPin= 5;
int bluePin= 6;

int blueTemp= 0; int greenTemp= 0; int redTemp= 0;

void setup()
{
Serial.begin(9600); //opens serial port, sets data rate to 9600 bps
}

void loop()
{
tempC = analogRead(tempPin);           //read the value from the sensor
tempC = (5.0 * tempC * 100.0)/1024.0;  //convert the analog data to temperature
Serial.println((byte)tempC);             //send the data to the computer

if(tempC<0){
analogWrite(bluePin, 255);}
else if(tempC>0&&tempC<=45){
blueTemp= map(tempC, 0, 45, 255, 0);
analogWrite(bluePin, blueTemp);}
else if(tempC>45){
analogWrite(bluePin, 0);}

if(tempC<15){
analogWrite(greenPin, 0);}
else if(tempC>15&&tempC<=35){
greenTemp = map(tempC, 15, 35, 1, 254);
analogWrite(greenPin, greenTemp);}
else if(tempC>35&&tempC<=75){
greenTemp = map(tempC, 35, 75, 255, 0);
analogWrite(greenPin, greenTemp);}
else if(tempC>75){
analogWrite(greenPin, 0);}

if(tempC<45){
analogWrite(redPin, 0);}
else if(tempC>=45){
redTemp= map(tempC, 45, 90, 1, 255);
analogWrite(redPin, redTemp);}
else if(tempC>90){
analogWrite(redPin, 255);}

delay(200);                           //wait 200 ms before sending new data
}

Now the delay was set to 200ms, and I didn’t really bother with it. Perhaps setting it to something lower like 100ms would produce a more fluent change in the led’s color.

21 thoughts on “Visualizing temperature as color using an RGB led, a LM35 sensor and Arduino

  1. as tu decouvert la formule ? que tu m-as demande? En fin,tu sais qu’il suivra : ton blog est excellent,fantastique !

    1. Oui! La formule est une façon de résoudre le problème, mais il est plus difficile. Quelqu’un m’a suggéré que je utiliser la fonction la «map» avec des valeurs inversées, et ça marche! Merci pour ton comment!

  2. Hi , that’s fantastic … I have the same idea for a project that i have to do on college but i have problem with the schematic-circuit .. i don’t know how to do it … that arduino is unknown for me … do you mind of giving me your schematic ? if there is a problem it’s fine …. thanks

    1. I’d happily post a schematic, but I’ve done the project quite a while ago, and as you can guess, I don’t have it assembled anymore. It’s quite easy if you follow the pin initializations at the start of the code. Most of what is not connected to those pins goes to ground. Don’t forget about resistors for the LED! Here’s a quick guide on how to hook up your temperature sensor to Arduino: http://learn.adafruit.com/tmp36-temperature-sensor

  3. Hi I am working on a project really similar to yours, I was wondering if you could help me out at all?

    Regards,
    Nathan

    1. Hi Nathan! I haven’t tackled with Arduino for quite some time, but I’ll do my best to answer your questions. What do you need help with?

  4. Hi,

    Can you please send me the scheme of this project on e-mail? I want to start with learning electronics and I found this project very interesting for studying…

    1. I would love to, but this is project has been disassembled long time ago, and my materials are at my home. Besides the code, you just have to use 3 resistors for each LED anode pin( the positive pins, the ground just goes to GND on Arduino). The temp sensor is easy to connect as well, you just insert its output into the first analog socket, the ground to GND and the positive to +5V.

  5. Hey I really enjoyed this post
    This code was a conciderable help to me as far as understanding the code and how to build upon it
    i made some changes for it so my computers tempature would have color as well but i edited it to have purple as the lowest colors temp
    i also had the code take a average of 50 results to smooth out the transition aswell
    here is my final products code and i hope this helps someone like it helped me

    #define aref_voltage 3.3
    const int numReadings = 50;

    int readings[numReadings]; // the readings from the analog input
    int index = 0; // the index of the current reading
    int total = 0; // the running total
    int average = 0; // the average

    int inputPin = A1;

    int redPin= 6;
    int greenPin= 3;
    int bluePin= 5;

    int blueTemp= 0; int greenTemp= 0; int redTemp= 0;

    void setup(void) {
    Serial.begin(9600);
    analogReference(EXTERNAL);

    for (int thisReading = 0; thisReading = numReadings)
    // …wrap around to the beginning:
    index = 0;

    // calculate the average:
    average = total / numReadings;
    float voltage = average * aref_voltage;
    voltage /= 1024.0;
    // print out the voltage
    // now print out the temperature
    float temperatureC = (voltage – 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
    // now convert to Fahrenheight
    float tempC = (temperatureC * 9.0 / 5.0) + 32.0;
    Serial.print(tempC); Serial.println(” degrees F”);

    if(tempC70&&tempC84){
    analogWrite(bluePin, 0);}

    if(tempC76&&tempC85&&tempC97){
    analogWrite(greenPin, 0);}

    if(tempC65&&tempC75&&tempC85&&tempC95){
    analogWrite(redPin, 255);}

  6. Currently there are digital RGB LED strips which can be controlled by an arduino. Search the web for the “fastled” library (adafruit)
    Code that does the same as yours, but for digital controllable LED’s (temperatures may be a little different due to my needs):

    #include “FastLED.h”
    #define NUM_LEDS 1 // define the amount of LED’s in the strip, here 1 LED is used.
    #define DATA_PIN 3
    #define CLOCK_PIN 13

    CRGB Leds[NUM_LEDS];

    float tempC;
    int tempPin = 0;

    void setup() {
    FastLED.addLeds(Leds, NUM_LEDS);
    Serial.begin(9600);
    }

    void loop()
    {
    tempC = analogRead(tempPin);
    tempC = (5.0 * tempC * 100.0)/1024.0;
    Serial.println((byte)tempC);

    if (tempC25&&tempC40&&tempC55){
    Leds[0] = CRGB(255, 0, 0);
    }

    FastLED.show();
    delay(500);
    }

    1. Thanks a lot for sharing Bob! Although I don’t quite have the time to share projects on this blog anymore, it’s nice to still find useful information from other people.
      On the Github page of the library they say it can control adafruit chipsets but also ones found on aliexpress, like TM1809. I wonder if these modules can be adapted for car mods?
      Thanks again!

Leave a comment