Arduino LCD Thermostat!

173,855

115

19

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!

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

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
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
}

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

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
{
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

152 7.2K
10 829
59 3.3K

19 Discussions

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.

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+=fix;

settemp++;
EEPROM.write (1, settemp); /* write the most recent settemp in eeprom data stoage*/

}
else {}

{
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

int humidity = dht.getHumidity();
{SetHumidity++ ; } // add one to the settemp
else {}

{ 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 invT0 = 1.00 / 298.15; // room temp in Kelvin

int adcVal, i, numSamples = 5;
float K, C, F;

for (i = 0; i < numSamples; i++)
{
delay(100);
}
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;
}

tvalue / 6.388888888889. but what is the tvalue. hou do i calculate it to Celsius

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

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.

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!

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?

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..

// 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);

}

//Write loop that will control the

void loop()

{

tempC = analogRead(tempPin); // read the analog value from the lm35 sensor.

lcd.setCursor(8,0);

lcd.print(tempC);

lcd.print("'C");

Serial.print((byte)tempC); // send the data to the computer.

delay (250);

{

(settemp ++);

EEPROM.write(1, settemp);

}

else{

}

{

(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);

}

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.

3 replies

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

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

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

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.

3 replies

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.

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.

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.