Arduino Water Heater Controller Circuit with LCD
In this tutorial we are going to construct a water heater temperature controller circuit using Arduino, LCD and a water proof temperature sensor. You can set your desire temperature in Celsius / Fahrenheit and the water heater will maintain the set temperature. The proposed design is equipped with a buzzer to notify the user when various temperature conditions are met.
We will see:
- Circuit diagram of temperature controlled water heater.
- Detailed circuit explanation.
- Program code for temperature controlled water heater.
- How to operate the proposed water heater controller circuit.
- Prototype Images of the circuit setup.
Circuit diagram:

Download high resolution image of the above circuit: Click here
NOTE 1: The DC buzzer has polarity, +ve (RED) terminal must connect to the switch / Arduino pin and -Ve terminal to GND.
NOTE 2: “A” and “K” are anode and cathode of the diode respectively and it is connected across the relay coil.
Circuit description:
Overview:
Using the above circuit you can heat water from 0 to 110 Celsius / 32 to 230 Fahrenheit. Four buttons are provided using which you can set a temperature that you wish to attain / maintain in the mentioned range.
The water heater we are going to use with the proposed circuit is immersion rod type:

The circuit utilizes a water proof temperature sensor DS18B20 which will be dipped in to the water that you are going to heat, this sensor collects current temperature of water using which Arduino decides when to trigger the relay ON and OFF to attain / maintain your desire temperature.
The circuit will turn OFF the heater once the desire temperature is reached and turns back ON once the temperature fall below an acceptable value, in this way temperature of the water is maintained.
A 5V buzzer is provided to alert the user once the set temperature is reached, you may enable / disable the buzzer using the slide switch provided in the circuit.
Hardware description:
Arduino board:
The proposed circuit consists of an Arduino board which is the brain of the project and you may use any Arduino board that is available with you and not just limited to Arduino nano.
LCD display:
A 16×2 LCD display is provided here to display the user set value and the current temperature of the water. A 10K variable resistor is provided to adjust the contrast of the LCD display.
DS18B20 digital temperature sensor:
A water proof (digital) temperature sensor DS18B20 is utilized in the circuit to measure the current water temperature accurately. It comes in a metallic tube and the actual sensor inside it looks like a transistor (as shown in the diagram).
The sensor comes with 3 wires 5V, Data and GND and the sensor communicates with the microcontroller using “one wire” protocol. The data line must be connected with a 4.7K pull-up resistor.

It can sense temperature from -55 to +125 degree Celsius and can measure temperature with the accuracy of +/- 0.5 degree Celsius (from -10 to +85 C). Since our application is about heating the water, we have limited the working range from 0 to 110 degree Celsius / 32 to 230 F.
Relay:

A 9V/12V relay is utilized in the circuit to turn on and off the water heater. The relay coil is controlled by a NPN transistor BC548 and the input signal to the transistor is provided from pin #8 of Arduino.
A current limiting resistor of 4.7K is connected to the base terminal to prevent over-biasing of the transistor. A diode is connected across the relay coil to arrest the high voltage spikes that could arise while energizing and de-energizing the relay coil.
Heater to relay wiring diagram:

Note: Make sure your relay contacts can handle the current your water heater demands. A 10A 250V relay can handle 1KW / 1000W heater, above which you should get a higher ampere rated relay.
Buzzer:

A 5V buzzer is provided to notify when the water reaches the temperature set by you, this feature is helpful when you just want to attain certain temperature and you would remove the heater from water.
You can turn off the buzzer using the switch provided in the circuit; you would do this when you want to maintain the temperature of the water for long time, for example: Sterilizing medical tools where the tools need to be placed in hot water several minutes to hours and you don’t want to get notified when the temperature reaches the set value.
Power input:
You can power the circuit using a wall adapter with 9V (if you are using a 9V relay) or with 12V (if you are using a 12V relay). It should provide a minimum current of 500mA.
Download “onewire.h” library: Click here
Download “DallasTemperature.h” library: Click here
Program for temperature controlled water heater:
//------------ ©Electronics-project-hub-----------// #include <OneWire.h> #include <DallasTemperature.h> #include <LiquidCrystal.h> #include<EEPROM.h> LiquidCrystal lcd(7, 6, 5, 4, 3, 2); int add_chk = 0; int check_val = 10; int c_temp = 0; int c_temp_add = 1; int f_temp = 0; int f_temp_add = 2; int set = A3, dec = A2, inc = A1, stsp = A0; int numberOfDevices; int relay = 8; int buzzer = 9; int val_tol = 0; bool exit_stsp = false; bool exit_set = false; bool buz = true; bool re_heat = false; #define ONE_WIRE_BUS 10 // Pin no #define TEMPERATURE_PRECISION 12 // 12-bit resolution OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress tempDeviceAddress; //------- Temperature tolerance -------// const int tol = 3; // in degree Celsius //-----------------------------------// void setup(void) { lcd.begin(16, 2); sensors.begin(); pinMode(stsp, INPUT_PULLUP); pinMode(inc, INPUT_PULLUP); pinMode(dec, INPUT_PULLUP); pinMode(set, INPUT_PULLUP); pinMode(relay, OUTPUT); pinMode(buzzer, OUTPUT); digitalWrite(relay, LOW); digitalWrite(buzzer, LOW); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Water Heater"); lcd.setCursor(0, 1); lcd.print(" Controller"); numberOfDevices = sensors.getDeviceCount(); if (EEPROM.read(add_chk) != check_val) { EEPROM.write(add_chk, check_val); EEPROM.write(c_temp_add, 50); f_temp = f_conv(50); EEPROM.write(f_temp_add, f_temp); c_temp = EEPROM.read(c_temp_add); f_temp = EEPROM.read(f_temp_add); } else { c_temp = EEPROM.read(c_temp_add); f_temp = EEPROM.read(f_temp_add); } delay(1500); } void loop(void) { lcd.setCursor(0, 0); lcd.print("PRESS START/SET"); lcd.setCursor(0, 1); lcd.print("TEMP: "); lcd.print(EEPROM.read(c_temp_add)); lcd.print("C/"); lcd.print(EEPROM.read(f_temp_add)); lcd.print("F"); if (digitalRead(set) == LOW && exit_set == false) { exit_set = true; c_temp = EEPROM.read(c_temp_add); f_temp = EEPROM.read(f_temp_add); while (exit_set) { if (digitalRead(inc) == LOW) { c_temp += 1; if (c_temp > 110) c_temp = 0; f_temp = f_conv(c_temp); delay(50); } if (digitalRead(dec) == LOW) { c_temp -= 1; if (c_temp < 0) c_temp = 110; f_temp = f_conv(c_temp); delay(50); } lcd.clear(); lcd.setCursor(0, 0); lcd.print("SET TEMPERATURE:"); lcd.setCursor(0, 1); lcd.print(" "); lcd.print(c_temp); lcd.print("C/"); lcd.print(f_temp); lcd.print("F"); delay(150); if (digitalRead(set) == LOW) { delay(500); if (digitalRead(set) == LOW) { exit_set = false; if (EEPROM.read(c_temp_add) == c_temp) { lcd.clear(); lcd.print("VALUE UNCHANGED!"); delay(1500); } else { EEPROM.write(c_temp_add, c_temp); EEPROM.write(f_temp_add, f_temp); lcd.clear(); lcd.print(" VALUE SAVED!"); lcd.setCursor(0, 1); lcd.print("****************"); delay(1500); lcd.clear(); } } } } } if (digitalRead(stsp) == LOW && exit_stsp == false) { exit_stsp = true; lcd.clear(); lcd.setCursor(0, 0); lcd.print("SET: "); lcd.print(EEPROM.read(c_temp_add)); lcd.print("C/"); lcd.print(EEPROM.read(f_temp_add)); lcd.print("F"); buzz(); digitalWrite(relay, HIGH); while (exit_stsp) { sensors.requestTemperatures(); for (int i = 0; i < numberOfDevices; i++) { if (sensors.getAddress(tempDeviceAddress, i)) { printTemperature(tempDeviceAddress); } } lcd.setCursor(0, 1); lcd.print("WATER: "); lcd.print(c_temp); lcd.print("C/"); lcd.print(f_temp); if (f_temp < 100) { lcd.print("F "); } else { lcd.print("F"); } if (c_temp >= EEPROM.read(c_temp_add) && buz == true) { delay(5000); if (c_temp >= EEPROM.read(c_temp_add)) { digitalWrite(relay, LOW); buz = false; re_heat = true; for (int j = 0; j < 15; j++) { digitalWrite(buzzer, HIGH); delay(100); digitalWrite(buzzer, LOW); delay(100); } } } val_tol = EEPROM.read(c_temp_add) - tol; if (c_temp <= val_tol && re_heat == true) { buz = true; re_heat = false; digitalWrite(relay, HIGH); } if (digitalRead(stsp) == LOW && exit_stsp == true) { delay(1500); if (digitalRead(stsp) == LOW) { digitalWrite(relay, LOW); exit_stsp = false; lcd.clear(); lcd.print("PROCESS STOPPED!"); lcd.setCursor(0, 1); lcd.print("****************"); buzz(); delay(500); lcd.clear(); break; } } } } } int f_conv(int x) { int temp; temp = x * 9; temp = temp / 5; temp = temp + 32; return temp; } void printTemperature(DeviceAddress deviceAddress) { c_temp = sensors.getTempC(deviceAddress); f_temp = f_conv(c_temp); } void buzz(void) { digitalWrite(buzzer, HIGH); delay(1000); digitalWrite(buzzer, LOW); } //------------ ©Electronics-project-hub-----------//
Tolerance:
To maintain certain temperature of water the relay turns OFF the heater when your desire temperature is reached so that water don’t heat further and after sometime the heater is turned ON when the temperature falls below an acceptable value.
You can set a tolerance value in the code here:
//------- Temperature tolerance -------// const int tol = 3; // in degree Celsius //-----------------------------------//
By default we have set to 3, which mean if the desire temperature is attained say 60 degree Celsius the relay turns OFF the heater and it will turn the heater back ON once the water temperature falls to 57 degree C (60-3 = 57 degree C) to raise the temperature of the water.
Similarly, if you set the tolerance value to 5, it will turn the heater back ON when the water temperature falls to 55 degree C.
Prototype:

How to operate this water heater controller?
Buttons functions:
S1: Start / long press to stop the heater.
S2: Increment a digit (INC).
S3: Decrement a digit (DEC).
S4: To set and save the temperature value.
- Turn ON the circuit with the completed hardware set-up, you will see this screen:

The above is the home screen it shows the user set temperature. You may either press start button to get your water to 50C/122F or you may press SET button (S4) to enter a new temperature value.
2. To enter a new temperature, press SET button (S4) and you’ll see the screen below. Press INC or DEC buttons to bring your desire temperature value on the screen.

3. Long press SET button to save the value and “values saved!” message will appear and it will get stored to EEPROM of Arduino and the screen will return to home.

4. Now press start button (S1), the relay will turn on with a beep to indicate that the process has started and you’ll see the below screen:

The “SET” on the screen is the value that you have just entered and “water” is the present temperature of the water where the temperature sensor is dipped in.
5. Once the water reaches the “SET” temperature the relay turns OFF and buzzer beeps for few seconds to notify that water is ready for use and you may turn off the heater by long pressing the start/stop button (S1):

- 6. Or to maintain the set temperature of the water, just leave the circuit ON for as long as you want, your set temperature will be maintained. Turn off the buzzer so that it won’t beep ever time the relay turns off.
- 7. When you turn ON the circuit the last set value will be retrieved from EEPROM. You may either press start button (S1) to heat the water or press SET button (S4) to enter a new temperature value.
If you have any questions regarding this project, feel free to ask us in the comment section and you will get a guaranteed reply from us.
dear sir,
all system functional but out put pin 8 and 9 not activated for relay and for buzzer, so plz guide me my relay is functional when i give -ve pulse..where is prblem so plz guide me
Hi,
The buzzer must be a DC buzzer (if you apply a DC voltage it will buzz) and it has polarity the +ve must connect to Arduino pin and other buzzer pin to GND.
The relay must be a 9V to 12V type like shown in this post and not a 5V one that comes in with PCB board. Connect the transistor’s collector to one of the relay coil terminal and connect the other relay coil terminal to +V 9V supply.
Regards
Dear sir,
Very good idea . i have need your help , After shut off the power , how to automatic program start , i meain don’t long press button for on
thanks .
Hi,
We did not incorporate such function because when you turn ON the circuit it will immediately turn ON the relay and no time for setting a new temperature. By the way long press is for turning off the heater, short press is for starting the circuit.
Regards
Dear sir,
Can you show relay connections with AC end the diode?
Thanks
Can you please rephrase your question?
Sorry about my english.
Can you show a picture of how you made the connections between the relay, the diode and the resistor?
In my prototype is not working 🙁
Regards
Hi,
We don’t have anymore images to show you, but there are already enough information in the circuit and you can also take a look at the relay pin diagram provided. If you still could not figure it out, kindly get help from some one who can understand this.
Regards
I just want to thank you for this project.
I use a relay module instead of a common relay, and works flawlessly.
Thank you for share your knowledge with us!
I am glad your project worked very well.
I have been looking for a solution to Heating water tanks and this looks like the one. I have constructed the circuit on a breadboard and it works as described.
I have also uploaded the code from the delay timer which also works perfectly with this circuit.
What changes to the code would be required so that I could use the countdown code prior to the water heater code starting?
This is so that I can set the heater to come on in the afternoon and count down till the morning hours after starting and maintain a set temperature rather than have the heater running all night.
I see some issues with the display size ( I have a spare 20×4 lcd in stock) also could scroll display I suppose.
I have 2 tanks to control (same temperature) so can build 2 units but note that the 18B20 can have multiple connections on the one wire bus and I could just use one unit with 2 relays.
I would very much appreciate any assistance you can provide.
Hi Michael,
Your project specifications are very much possible and requires core changes to the program code and hardware.
For such changes it takes us time and effort so we charge the readers a little who requires customization to the project.
If you are interested you may reply to this comment.
Regards
Thank you for the reply, can you email me a quote please.
I have emailed you, please check it out.
Where will the wires of the heater be connected?
Hi,
Your heater’s live/hot should be connect to N/O of relay and the other terminal of your heater directly to neutral.
Regards
Very nice little project to showcase how actually most of household items based on thermostat work – water heating boilers, ovens, clothes irons actually work… very very nice and elegant.
Next step would be introducing some advanced kind of control through implementing some kind of software PID controller with this setup. This also would require a bit more reliable (thusly more expensive) AC switch.
Or to try and mess around with triacs which is a next level, really.
This way you could get really REALLY cheap sous-vide machine for self build at a mere fraction of the price.
I am glad you liked this project, we noted your suggestions, thanks!
Hi Experts,
I want to heat the oil (mustard or some massage oil) instead of water. Can you recommend or what else can be used.
You can heat oils, without any modification.
Hi, Do you have any clearer photos of your breadboard setup? I’m working through the system and would like to guarantee that I am setting it up correctly.
The prototype presented in this project is just to show that the project works correctly. You no need to make exactly as the prototype, just follow the circuit diagram.
thank you for deep explanation. can i use this code directly for LM35 or DTT11 temperature sensor instead of dallas temperature sensor
Hi,
You cannot use LM35 or DHT11 sesnor, LM35 is an analog senor and DHT11 is not a water immersible sensor and the protocols are not compatible Dallas library.
Regards
Great Project!! I would like to convert this into cooling control device instead of heating. Can you tell me where the changes in the code need to be made?
Hi,
Hope you like the project, I wish I could explain, but your specifications require core changes to the code, which cannot be explained in one or two sentences. If possible we will try to make one in future.
Regards
Would you consider sending me a quote for the changes? Chuck
Hi,
At the present moment it is not possible for us, if you can wait a couple of weeks we will definitely get back to you.
Please let us know your thoughts.
Regards
hi its a nice project, hope youre good and going with your projects, how to add a single decimal accuracy to it, like 40.1 Deg or say 90.7 Deg c
thanks in advance
Hi,
This cannot be explained in one or two sentences, the code need to be re-written to add this functionality.
The water temperature while heating is not equal across the volume of the container, the temperature sensor measures an average temperature which makes decimal precision irreverent.
If you need such decimal precision , we will try to update in near future.
Dear sir,
How can i download the .ino file for this project program
Please copy the given code.
Great Project ! I have a few questions though
1. Doesn’t a relay come in with a flyback diode, is the IN4007 for extra protection ?
2. What software have you used for drawing the circuit diagram?
3. The circuit shows DS18820 directly connecting the resistor to 5V, will that not leave it always on ?
4. You show the +9V phase line, going into the Arduino Nano Vin, I always thought the arduino operating voltage was +5V
Hi, Sorry for the late reply.
1) We are using a stand alone relay, not the relay that comes in a breakout board. So we have to add a flyback diode on our circuit.
2) The software I have used is “Fritzing”.
3) We need a pull-up resistor on the output pin which is mandatory.
4) All most all arduino boards has a build-in voltage regulator which requires 7V to 12V input, if power is applied externally.
Regards
Hi! May I know how to convert the circuit given in the proteus. If possible can you send me the proteus diagram of this circuit.
Sorry, we don’t have a simulation.
HI Blogthor may you please contact me on my email above or whatsApp me to help me in my final year project am from Africa, Namibia.
[Protected]
whatsapp: [Protected]
Thank you for your time.
Is it possiblw to use, i stead of the 9/12 v , a 5v 10 ampere 230 v relay? I cant find a way i could apply 9-12 v in my system thats why..
Hi, There are plenty of 9V relay, please search online..
can we convert this into heating and cooling both?like
according to the desire of the user???For example if user will press button it will start cooling else on the other side its will starts heating???
Of course, it done by modifying the code appropriately.
How do we incorporate this circuit with the circuit of an electric kettle?
Please refer relay wiring diagram and please use a relay with appropriate current rating that suits electric kettle.
Hi,
since most electric kettle has built in temperature control mechanism, this circuit may not work.
Regards
If I use servo motor for electric kettle instead of Relay. That it is possible?
Hi,
You can trigger a servo motor, but you need to make significant changes to the code and hardware.
Are you going to trigger a physical switch with a servo?
Regards
If I’m using Electric kettle instead of heater. The connection for Relay, can I connect the same way as you connected the heater. Also there will be effects in the programme?
The electric kettle has built in temperature control, so this circuit cannot work with it.
Hello sir, I had a question whether the circuit will work only when the heater is connected to the circuit.
Yes!
Can I implement on boiler 2.000W AC (manual system) in my bathroom?
Hi, I would NOT recommend doing this, better you purchase a proper heating solution.
How many watts of immersion rod water heater can be used in this project?
Hi,
This depends on your relays current rating it can handle. Higher the current handling capacity, higher the wattage you can use. it will be mentioned on the relay.
Hi! Were using the code for a project and were having issues with the set value, start/stop buttons. The LCD is automatically, fluctuating between all button settings. Tried to post a picture, however, I’m not able to
Hi, There are wiring problems with your setup like incorrect wiring or loose connections.
Hey. I am building the prototype of this circuit on circuito.io and I am not able to put in place the buttons. Can you please share the prototype either on arduino or anywhere. I really need it.
Hi,
May I know what exactly you are trying to do? Like making the PCB?
Hello, does this mean, temperature sensor is connected to the Arduino, the relay is connected to the Arduino and the heating element of the water heater, and the Arduino controls the relay based on the temperature readings from the temperature sensor. what about the adapter?
Can you please rephrase your question, I did not understand.
Hi Blogther
I’m doing this project on Proteus, but the relay connections are not clear. Please, can you explain them?
Hi,
Please tell me which part of the relay is not clear, relay coil or the NO/NC?
NC
NC is not used.