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:
int tempPin = 0;
int redPin= 3;
int greenPin= 5;
int bluePin= 6;
int blueTemp= 0; int greenTemp= 0; int redTemp= 0;
Serial.begin(9600); //opens serial port, sets data rate to 9600 bps
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
blueTemp= map(tempC, 0, 45, 255, 0);
greenTemp = map(tempC, 15, 35, 1, 254);
greenTemp = map(tempC, 35, 75, 255, 0);
redTemp= map(tempC, 45, 90, 1, 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.