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:

Arduino water heater controller circuit
Arduino water heater controller circuit

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:

Immersion Water heater
Immersion rod water heater (CC BY-SA 4.0)

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.

DS18B20 Water proof temperature sensor
DS18B20 Water proof temperature sensor

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:              

Relay pin diagram
Relay pin diagram

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:

Arduino Water Heater Controller
Arduino Water Heater Controller

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.

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

Avatar photo

My nick name is blogthor, I am a professional electronics engineer specialized in Embedded System. I am a experienced programmer and electronics hardware developer. I am the founder of this website, I am also a hobbyist, DIYer and a constant learner. I love to solve your technical queries via comment section.