Introduction: Arduino LCD Thermostat!
In this project we'll use an arduino uno, an LCD and a temperature sensor to control your air conditioning.! Also You can modify the code for a heater. The code is well explained! I show even how I made mine permanent!
Great your beginners to learn arduino and for hot room that have an old manual a/c. This is a project to try!
Step 1: Prototyping the Test Circuit
This circuit is to test if the thermostat is working or not. The lcd should display a hello,world! sketch, the the current temperature of the room, and below is the ideal temperature or settemp. If the current temperature is off by a little you may need to adjust the code which calculates the 10 bit number read from A0 into a temperature reading in degrees Fahrenheit. If you need Celsius will will also need to change the line of code the calculates the temperature. If you wan to control an a/c, you can remove the led and replace it with an N-Channel MOSFET ( Metal Oxide Semi-conductor Field Effect Transistor). Then TO USE A PROTECTION DIODE! I will go over this as well. In the next step.
Parts list:
12 volt power supply
7805 5 volt voltage regulator
arduino uno or other arduino dev board
3x 10k ohm resistors
led
jumper wire
solderless breadboard
arduino ide
10k potentiometer ( or a 1k ohm and a 220 ohm resistor) (or the 3rd pin can go to ground)
16x2 Hitachi driven hdd44780 LCD
10k thermistor a.k.a. (10k ohm NTC, (Negative Thermal Coefficient)
2x tactile button switches ( or any other button switch)
usb b type connector to program arduino
For use with an a/c:
N-channel MOSFET
120VAC 20-40A relay
1N4007 - 1N4004 rectifier diode
a/c
To finalize:
perfboard / PCB
Project enclosure
And tool that everyone should have
Let's get started!
Step 2: The Code
So the code:
// written by Dylon Jamna (ME!)
// include the library code
#include <EEPROM.h>
#include <LiquidCrystal.h>// include the library code
int tempPin = A0; // make variables// thermistor is at A0
int led =13; // led is at pin
float temp; // make a variable called temp
float settemp; // make a variable called temp
int swtu = 7; // switch up is at pin 7
int swtd = 6; // switch down is at pin 6
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // lcd is at 12,11,5,4,3,2
void setup() {
pinMode (led,1); // make led or pin13 an output
Serial.begin (9600); // set the serial monitor tx and rx speed
lcd.begin(16, 2); // set up all the "blocks" on the display
lcd.setCursor(0,0); // set the cursor to colum 0 row 0
lcd.print("hello, world!"); // display hello world for 1 second
lcd.clear(); // clear the lcd
EEPROM.read (1); // make the eeprom or atmega328 memory address 1
}
void loop() {
int tvalue = analogRead(tempPin); // make tvalue what ever we read on the tempPin
float temp = (tvalue / 6.388888888889); // the math / conversion to temp
lcd.setCursor (0,0); // set the cursor to 0,0
lcd.print (temp); // Print the current temp in f
lcd.print ('F');
Serial.println (temp); // print the temp it the serial monitor
settemp = EEPROM.read(1); // read the settemp on the eeprom
delay (250); // wait for the lcd to refresh every 250 milliseconds
if // if we se the switch up pin reading on 1 or 5 volts
(digitalRead(swtu)== 1 )
{
settemp ++ // add one to the settemp, the settemp is the ideal temperature for you
;
}
else{// other wise do nothing
}
if
(digitalRead (swtd) == 1)// if we detect a 1 on the other switch pin
{
(settemp --);// subtract one fromm the settemp
}
else {
// else, do nothing
}
if (temp > settemp) // if the temperature exceeds your chosen settemp
{
digitalWrite (led, 1); // turn on the led
}
else // if that doesn't happen, then turn the led off
{
digitalWrite (led,0);
}
lcd.setCursor (0,1); // set the cursor to 0,1
lcd.print ("Set To "); // Print set to and your ideal temperature in f
lcd.print (settemp);
lcd.print ('F');
Serial.println(settemp); // Print the settemp in the serial montior
EEPROM.write (1,settemp); /* write the most recent settemp in eeprom data stoage
so that if the power is disconnected, you settemp is saved!*/
delay (250); // wait 250 milliseconds
} // we're done
Step 3: The Build
Now to actually make this project useful we need to make it more permanent. We do this by soldering it to the perfboard. Now there are many ways to solder on perfboard. The way I prefer to solder it is by soldering on thick buses for power and ground made of solder. Then I strip, tin, and solder ribbon cable wire to every necessary connection. But you can tin track on the board, or wire above the board and solder below which is very popular. Also to switch our a/c on or off we need to modify the led. Now there are a few seps to follow.
Step 1 - remove the led
Step 2- attach the gate of your N channel MOSFET Check your datasheet for the pin out!!!!
Step 3 - Attach the ground to your source pin on the MOSFET
Step 4 - Attach the Drain pin to your MOSFET
Step 5 - Attach your relay's coil to 12v depending on the relay, and the other to you drain pin on the MOSFET
Step 6 - Add the the protection diode, connect the striped silver end (cathode) to your 12v, and you other end (anode) to your Drain pin on the MOSFET.
use the other diagram for the power input.
Step 4: The Final Product
Now I know this isn't the best looking project enclosure as you saw in the intro, but here's how I did it. I use 1/4 plywood type of scrap kind of wood, and you can check the Home depot for it and look carefully. I cut it up to size and nailed it together with an air compressor nailing gun. It actually didn't split,( Take your time or it will split!) No glue is necessary. I drill hole for the wire like the thermister and 3 wires for the separate relay power control box, and drilled one big one were the lcd was supposed to go. This was so I could stick a jigsaw blade in there and cut out a rectangle. The 2 tactile switches had tall shafts which poked through the plywood just barely. You could glue or epoxy on plastic rods from a pen tube or something.
Also I embedded an atmega8 not an atmega328 just because my sketch was only 6k bytes. The atmega8 only holds 8k bytes so I was safe. I pretty much made a stand alone arduino on perboard. I used a voltage divider for the lcd which was 1k and 220 ohm resistor. 1k goes to 5 volts and pin 3 on the LCD, and the 220 ohm resistor goes to ground and the pin 3 on the LCD.
To prop up the board to the front panel. The 3 pin header connector was from the connection the the relay power box.
I used an iec connector, I soldered a main female connector to this one so I can plug it in the box. I used hot glue this time for the box and it worked surprisingly well.
Remember to comment or contact me if you have any problem. Any go to arduino.cc and arduino forums or more troubleshooting and help.

Participated in the
Arduino Contest
20 Comments
1 year ago
Wow this is great.
Now, I wanted to ask how one can connect a heater, a thermostat, a temperature sensor and an 128*64 LCD to an arduino to monitor temperature
5 years ago
Hi
This is Eabul.
i want to save data to eeprom from press button .
when TemperatureUp button press. increase float data like as 0.01> 0.02--------30.10> 30.61
and this value save to eeprom.
and when TemperatureDown button press . decrease float data like as 30.60>30.59-----29.10
and update minus value eeprom
and increase and decrease valud view lcd display .
but when press button save int number not float. and show me lcd display int value.
please help how to write and read float value from eeprom. press button.
hear my code.
//For Display
#include <LiquidCrystal595.h> // 3wire display
LiquidCrystal595 lcd(4, 3, 2); // DS, ST_CP, SH_CP
//For time
#include <Wire.h>
#include <RTClib.h>
RTC_DS1307 RTC;
//for humidity
#include "DHT.h"
DHT dht;
//for stor tempereratur and humidity
#include <EEPROM.h>
int SetHumidity;
int HumidityUp = 10; // switch up is at pin 10
int HumidityDown = 11; // switch down is at pin 11
float fix = 0.01;
float settemp; // make a variable called temp
float TemperatureUp = 12; // switch up is at pin 12
float TemperatureDown = 13; // switch down is at pin 13
//result view
int led = 0; // led is at pin 0
void setup() {
//For timer
Wire.begin();
RTC.begin();
//For welcome screen
lcd.begin(16,4);
lcd.setCursor(0,0);
lcd.print("Welcome Elab");
delay(2000);
lcd.clear();
//for dht-11 pin setup
dht.setup(A1); // data pin 2
}
void loop() {
//For tempererature up / down
float temp[3];
getTemp(temp);
float tempererature = temp[1];
settemp = EEPROM.read(1); // read the settemp on the eeprom
if(digitalRead(TemperatureUp) == 1 )
{
settemp+=fix;
settemp++;
EEPROM.write (1, settemp); /* write the most recent settemp in eeprom data stoage*/
}
else {}
if(digitalRead (TemperatureDown) == 1)
{
settemp -= fix;
settemp--;
EEPROM.write (1, settemp); /* write the most recent settemp in eeprom data stoage*/
}
if (tempererature >= settemp) { digitalWrite (led, 1); }
else { digitalWrite (led, 0);}
//else { };
lcd.setCursor(0,0);
lcd.print("T:");
lcd.print(tempererature);
lcd.setCursor(8,0);
lcd.print ("ST");
lcd.print (settemp);
lcd.print((char)223);
//End tempererature controll
//For humidity up / down
SetHumidity = EEPROM.read(2);
int humidity = dht.getHumidity();
if(digitalRead(HumidityUp ) == 0 )
{SetHumidity++ ; } // add one to the settemp
else {}
if(digitalRead (HumidityDown) == 0)
{ SetHumidity--; } // Reduse settemp
else { };
lcd.setCursor (0, 1);
lcd.print ("CH:");
lcd.print (humidity);
lcd.print ("%");
lcd.setCursor (8, 1);
lcd.print ("SH:");
lcd.print (SetHumidity);
lcd.print ("%");
delay (1); // wait 100 milliseconds
EEPROM.write (2, SetHumidity); /* write the most recent settemp in eeprom data stoage*/
//End tempererature controll controll
}
//analog temperature
void getTemp(float * t)
{
const int analogPin = 0; // replace 0 with analog pin
const float invBeta = 1.00 / 3380.00; // replace "Beta" with beta of thermistor
const float adcMax = 1023.00;
const float invT0 = 1.00 / 298.15; // room temp in Kelvin
int adcVal, i, numSamples = 5;
float K, C, F;
adcVal = 0;
for (i = 0; i < numSamples; i++)
{
adcVal = adcVal + analogRead(analogPin);
delay(100);
}
adcVal = adcVal/5;
K = 1.00 / (invT0 + invBeta*(log ( adcMax / (float) adcVal - 1.00)));
C = K - 273.15; // convert to Celsius
F = ((9.0*C)/5.00) + 32.00; // convert to Fahrenheit
t[0] = K; t[1] = C; t[2] = F;
return;
}
6 years ago
tvalue / 6.388888888889. but what is the tvalue. hou do i calculate it to Celsius
6 years ago
Hello,
I m newbe.
hoe do i set F to Celsius.
I have to chance float temp = (tvalue / 6.388888888889); // the math / conversion to temp
to what?
thanks
6 years ago
Wiring is wrong on breadboard for the LCD backlight needs reversing.
Small errors in code notes, needs some mean values on coding as too sensitive for central heating it toggles too much near changeover threshold OK for electrical heating.
7 years ago
Arduino termisotr
8 years ago on Introduction
How to change max. set temp with 250F to 350F???
8 years ago on Introduction
How to change the set temp???????
Reply 8 years ago on Introduction
You use the push buttons with a pull down resistor in this configuration to change the set temp. But do change it for your application, this is a rough version that still could use a little tweaking because the subtle temperature changes trigger the a/c on and off a million times. Good luck!
8 years ago on Introduction
I made it FINALLY after months of problems!!! i reworked the code a bit and added 3 relays total and a toggle switch cause where i live sometimes you just want it off!
the relays are for
1. hot
2. cold
3. fan
and my switch is a 4 way switch so it can click to heat, cool, fan, and off
thanks a bunch!!! if i get a nice sheild made i may do a kickstarter! do you have a way for me to donate some $ to you?
9 years ago on Introduction
Hi Dylon,
Your project seems useful so I tried to replicate it but using Grove-LCD RGB Backlight display instead.
Everything is flowing nicely until I get to the user buttons. Im using a-pushto-off button with only 2 connecting wires.
So the problem I'm facing is, when I pressed the up button, the temperature (settemp) will go up and not stop. Same goes if I press the down button.
I'll give you my codes below but Im sure it's similar..
Please help me if you can. It's giving me sleepless nights... :(
// Declare variables
#include <Wire.h>
#include <EEPROM.h>
#include <Bounce2.h>
#include "rgb_lcd.h"
rgb_lcd lcd;
const int colorR = 30;
const int colorG = 30;
const int colorB = 60;
float tempC;
float settemp;
int tempPin = A0; //temp sensor plugged in pin 0
int ledPin = 13; //closest to ground
int fan1 = 2; // fan connected to pin 6
int swtu = 7;
int swtd = 6;
Bounce bouncer = Bounce();
// Write setup programme
void setup()
{
Serial.begin(9600); //Open serial port to communicate. sets data rate to 9600
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// initialize the serial communications:
lcd.setRGB(colorR, colorG, colorB);
lcd.print("Temp = ");
delay(250);
pinMode(ledPin, OUTPUT);
pinMode(fan1, OUTPUT);
pinMode(swtu, INPUT);
bouncer.attach (swtu);
bouncer .interval(5);
pinMode (swtd, INPUT);
bouncer.attach (swtd);
bouncer .interval(5);
EEPROM.read(1); //make eeprom memory address
}
//Write loop that will control the
void loop()
{
tempC = analogRead(tempPin); // read the analog value from the lm35 sensor.
tempC = (5.0 * tempC * 100.0)/1024.0; // convert the analog input to temperature in centigrade.
lcd.setCursor(8,0);
lcd.print(tempC);
lcd.print("'C");
Serial.print((byte)tempC); // send the data to the computer.
settemp = EEPROM.read(1); // read the settemp at memory 1
delay (250);
if (digitalRead (swtu)==1)
{
(settemp ++);
EEPROM.write(1, settemp);
}
else{
}
if (digitalRead(swtd)==1)
{
(settemp --);
EEPROM.write(1, settemp);
}
else {
}
if (tempC > settemp)
{
digitalWrite(ledPin, HIGH);
digitalWrite(fan1, HIGH);
}
else
{
digitalWrite(ledPin, LOW);
digitalWrite(fan1, LOW);
}
lcd.setCursor(0,1);
lcd.print("Set Temp To: ");
lcd.print(settemp);
Serial.print((byte)settemp);
// EEPROM.write(1, settemp);
delay(250);
}
9 years ago on Step 2
In the code, you have
if (temp > settemp) // if the temperature exceeds your chosen settemp
{
digitalWrite (led, 1); // turn on the led
}
else // if that doesn't happen, then turn the led off
{
digitalWrite (led,0);
}
I'm guessing that turning on the LED also activates the MOSFET and turns on the A/C, correct?
My main question is this: For someone who has both a heater and an A/C, could you have it do something like this:
if (temp > settemp + 2) // if the temperature exceeds your chosen settemp
{
digitalWrite (led, 1); // turn on the led for the A/C circuit
}
elseif (temp < settemp - 2) //If the temperature exceeds your settemp
{
digitalWrite (led, 1); // turn on the LED for the heater circuit
}
else // if that doesn't happen, then turn the led off
{
digitalWrite (led,0);
// digitalWrite (ledX,0); //ledX would be the second led for the heater circuit
}
My goal with this is to replace the "heat/cool" switch on a regular thermostat, and have it be a pure climate control system (where it either turns the heat or A/C on to keep the temp at what you want). Also, I added the + 2 and - 2, because most furnaces and A/C's won't start until the temp is 2 degrees above/below your set temp. It might have to be tweaked out to 3 or 4, depending on whether your furnace and/or A/C stops before the actual temp gets more than 2 degrees from your set temp. Otherwise, your heater and a/c will constantly be turning off and on to keep your temp set.
Have a great day.:)
Patrick.
Reply 9 years ago on Step 2
Sorry for the late response. You would need a second output or "led" which yes, is connected to a MOSFET then to a relay. I'm still new to arduino coding, so I really can't give you valuable code. The constant switching on and off is a problem that I have experienced, but you can make the code realize or have a hysteresis or a number/ temperature that will take into account the temperature lag and other stuff. Here is a helpful link because I can't explain stuff right.
I hope it helps
Dylon J
Reply 9 years ago on Step 2
Sorry for the late response. You would need a second output or "led" which yes, is connected to a MOSFET then to a relay. I'm still new to arduino coding, so I really can't give you valuable code. The constant switching on and off is a problem that I have experienced, but you can make the code realize or have a hysteresis or a number/ temperature that will take into account the temperature lag and other stuff. Here is a helpful link because I can't explain stuff right.
I hope it helps
Dylon J
Reply 9 years ago on Step 2
Sorry for the late response. You would need a second output or "led" which yes, is connected to a MOSFET then to a relay. I'm still new to arduino coding, so I really can't give you valuable code. The constant switching on and off is a problem that I have experienced, but you can make the code realize or have a hysteresis or a number/ temperature that will take into account the temperature lag and other stuff. Here is a helpful link because I can't explain stuff right.
I hope it helps
Dylon J
10 years ago on Step 2
The code is a good beginning but needs revision on the EEPROM.write command being used through every loop. EEPROM has a limited number of write cycles before it wears out. A better idea would be to only write to it periodically or only when the value to be written changes.
Reply 10 years ago on Introduction
I know what you mean. But I used a cheap atmega8 that can be rewriten about 10,000 times before having errors. Plus, I really new to coding up the arduino.
Reply 9 years ago on Step 2
The easiest way to reduce the number of write cycles would be to move the 'EEPROM.write' command to a new line just below each of the
'(settemp ++);' and '(settemp --);' lines. This way the EEPROM is only being written to each time a button is being pressed.
Reply 9 years ago on Introduction
thx I'll try and change my code
10 years ago on Introduction
Add your relay pin control to pin 10-8 or else you will flick to relay on and of rapidly it the start of the code.