Temperature control is one of the most important requirements in industrial processes, home automation, incubators, HVAC systems, and electronic equipment protection. A smart temperature controller not only monitors temperature but also allows users to configure alarm limits easily.
In this project, we designed a programmable temperature control system using Arduino, a TMP36 temperature sensor, a 4x4 keypad, and a 16×2 LCD display.
The system allows users to:
✔ Monitor real-time temperature
✔ Set high and low temperature limits
✔ Change set points using keypad
✔ View system status on LCD
✔ Get visual alerts using LEDs
This project was simulated and tested on Tinkercad, making it perfect for beginners and students.
System Overview
The temperature controller works on three main states:
| Temperature Condition | LED Status | LCD Display |
|---|---|---|
| Normal Range | Green LED ON | "Normal" |
| Above High Set Point | Red LED ON | "High" |
| Below Low Set Point | Yellow LED ON | "Low" |
The user can:
• Enter menu by long-pressing push button
• View current set points
• Modify set points using keypad
Components Used
| Component | Description |
|---|---|
| Arduino UNO | Main controller |
| TMP36 | Analog temperature sensor |
| 16x2 LCD | Display temperature & status |
| 4x4 Keypad | Set value input |
| Push Button | Menu control |
| LEDs (Red, Green, Yellow) | Status indication |
| Resistors | Current limiting |
| Jumper wires | Connections |
TMP36 Temperature Sensor Working Principle
The TMP36 is an analog temperature sensor that outputs voltage proportional to temperature.
Key Characteristics:
• Output: 10mV per °C
• 0.5V at 0°C
• Works from -40°C to +125°C
• Very accurate and simple to use
Formula Used:
Temperature (°C) = (Voltage - 0.5) × 100
System Working Logic
1. Temperature Measurement
Arduino reads analog voltage from TMP36 and converts it into Celsius.
2. Display on LCD
LCD continuously shows:
• Current temperature
• System status (Normal/High/Low)
Example:
Temp: 32.5°C
Status: Normal
3. Set Point Management
There are two adjustable values:
🔺 High Temperature Limit
🔻 Low Temperature Limit
These can be changed using keypad through the menu.
4. Menu Operation
When the push button is long pressed:
Main menu appears:
1. View
2. Setting #.Exit
View Option:
Displays current high and low limits.
Setting Option:
Allows entering new set point values using the keypad.
Exit:
The system then returns to the live monitoring mode.
5. LED Indication Logic
| Condition | LED Action |
|---|---|
| Temp > High Limit | Red LED ON |
| Temp < Low Limit | Yellow LED ON |
| Between Limits | Green LED ON |
This provides instant visual feedback.
Circuit Description
Main Connections:
TMP36:
| TMP36 Pin | Arduino |
|---|---|
| VCC | 5V |
| OUT | A0 |
| GND | GND |
LCD (16x2):
Connected in 4-bit mode to save Arduino pins.
Keypad:
8 digital pins used (4 rows + 4 columns)
LEDs:
Each connected via resistor to digital pins.
Push Button:
Connected with a pull-up resistor for menu access.
Program Flow
- Initialize LCD, keypad, sensor
- Read temperature continuously
- Display temperature and status
- Compare with set points
- Control LEDs
- Check push button for menu access
- Read keypad for new values
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Use LiquidCrystal_I2C.h for I2C version
// Define Keypad Layout
const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; // connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 1}; // connect to the column pinouts of the keypad
Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Initialize the LiquidCrystal library (adjust pins if not using standard setup)
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int tempSensorPin = A0;
const int interruptPin = 2;
const int lowOutPin = 11;
const int highOutPin = 12;
const int normalOutPin = 13;
char customKey ;
// Menu state variable
int menuState = 0; // 0: Main Menu, 1: Sub Menu 1, 2: Sub Menu 2, etc.
int low = 30;
int high = 80;
int lastTemp = 1;
bool menuMode = false;
volatile bool menuRequested = false;
volatile unsigned long pressStart = 0;
String inputBuffer = "";
//..................................//
void keyHoldISR() {
if (digitalRead(interruptPin) == LOW) {
pressStart = millis();
}
else {
if ((millis() - pressStart) >= 2000) {
menuRequested = true;
}
}
}
//................................//
void setup() {
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), keyHoldISR, CHANGE);
lcd.init();
lcd.backlight();
lcd.print("Welcome...");
lcd.setCursor(0,1);
lcd.print("electrical-info");
delay(2000);
lcd.clear();
//displayMainMenu();
pinMode(lowOutPin, OUTPUT);
pinMode(highOutPin, OUTPUT);
pinMode(normalOutPin, OUTPUT);
}
void loop()
{
if (menuRequested) {
menuMode = true;
menuRequested = false;
lcd.clear();
lcd.print("Menu Loading...");
delay(1000);
lcd.clear();
displayMainMenu();
}
if (menuMode) //keyPAd
{
char customKey = customKeypad.getKey();
if (customKey)
{
if (menuState == 0)
{
// Main menu options
switch (customKey)
{
case '1':
menuState = 1;
displaySubMenu1();
break;
case '2':
menuState = 2;
displaySubMenu2();
break;
case '#': // Exit button
//menuState =3;
menuMode = false;
lastTemp = 1;
lcd.clear();
break;
}
}
else if (menuState == 1) //view setting
{
// Sub Menu 1 options
switch (customKey)
{
case '#': // back button
menuState = 0;
displayMainMenu();
break;
}
}
else if (menuState == 2) //velue setings
{
// Sub Menu 2 options
switch (customKey)
{
case '1': // High setting
menuState = 3;
displaySubMenu21();
break;
case '2': // Low setting
menuState = 4;
displaySubMenu22();
break;
case '#': // Exit/back button
menuState = 0;
displayMainMenu();
break;
}
}
else if (menuState == 3)
{
// Sub Menu 21(High set) options
if(customKey >= '0' && customKey <= '9')
{
inputBuffer += customKey;
lcd.setCursor(13,0);
//lcd.print("Value: ");
lcd.print(inputBuffer);
//lcd.print(" ");
}
switch (customKey)
{
case '*': // set temp
saveSetpoint();
menuState = 2;
displaySubMenu2();
break;
case '#': // Exit/back button
menuState = 2;
displaySubMenu2();
break;
}
}
else if (menuState == 4)
{
// Sub Menu 22(Low set) options
if(customKey >= '0' && customKey <= '9')
{
inputBuffer += customKey;
lcd.setCursor(13,0);
//lcd.print("Value: ");
lcd.print(inputBuffer);
//lcd.print(" ");
}
switch (customKey)
{
case '*': // set temp
saveSetpoint();
menuState = 2;
displaySubMenu2();
break;
case '#': // Exit/back button
menuState = 2;
displaySubMenu2();
break;
}
}
}
}
else
{
handleTemperature();
}
}
void displayMainMenu() {
//lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Main Menu:");
lcd.print("1.View");
lcd.setCursor(0, 1);
lcd.print("2.Setting #.Quit");
}
void displaySubMenu1() { //View set points
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SubMenu1:");
lcd.print("#.back");
lcd.setCursor(0, 1);
lcd.print("low:");
lcd.print(low);
lcd.print(" High:");
lcd.print(high);
}
void displaySubMenu2() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SubMenu2: ");
lcd.print("1.High");
lcd.setCursor(0, 1);
lcd.print(" 2.Low #.back");
}
void displaySubMenu21() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set Hi Temp: ");
lcd.setCursor(0, 1);
lcd.print("*.Set #.back");
inputBuffer = "";
}
void displaySubMenu22() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set Low Temp: ");
lcd.setCursor(0, 1);
lcd.print("*.Set #.back");
inputBuffer = "";
}
void saveSetpoint() {
if (inputBuffer.length() == 0) return;
float value = inputBuffer.toFloat();
if(value<=150)
{if (menuState == 3)
{
high = value;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("High value saved");
delay(2000);
}
else if (menuState == 4 )
{
low = value;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Low value saved");
delay(2000);
}
}
else
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Out of range");
lcd.setCursor(0, 1);
lcd.print("Put it again....");
delay(2000);
}
inputBuffer = "";
}
void handleTemperature()
{ int raw = analogRead(tempSensorPin);
float voltage = (raw * (5.0 / 1023.0))-0.5;
float temperature = voltage * 100.0;
if(abs(temperature - lastTemp)>=1)
{
String state;
digitalWrite(lowOutPin, LOW);
digitalWrite(highOutPin, LOW);
digitalWrite(normalOutPin, LOW);
if (temperature < low) {
digitalWrite(lowOutPin, HIGH);
state = "Low";
}
else if (temperature > high) {
digitalWrite(highOutPin, HIGH);
state = "High";
}
else {
digitalWrite(normalOutPin, HIGH);
state = "Normal";
}
lcd.setCursor(0,0);
lcd.print("Temp:");
lcd.print(temperature,1); // One digit aftr deciml
lcd.print((char)176); // degree symbol
lcd.print("C ");
lcd.setCursor(7,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("State:");
lcd.print(state);
lastTemp = temperature;
}
delay(10);
}
Features of This System
✅ Real-time monitoring
✅ Adjustable limits
✅ User-friendly interface
✅ Visual alert system
✅ Works without computer
✅ Can be expanded to control relay/heater/fan
Possible Improvements
You can extend this project by adding:
✔ Relay for heater/cooler control
✔ Buzzer alarm
✔ EEPROM to save set points
✔ IoT monitoring using ESP32
✔ Mobile app control
Applications
This temperature control system can be used in:
• Incubators
• Greenhouses
• Industrial panels
• Cold storage
• Battery rooms
• Server cooling
• Smart home systems
Why This Project is Great for Learning
This project teaches:
🔹 Analog sensor interfacing
🔹 LCD programming
🔹 Keypad scanning
🔹 Menu system design
🔹 Embedded logic development
🔹 Real-world automation concept
This concept is ideal for Arduino beginners and engineering students.
Conclusion
This Arduino based temperature control system with keypad adjustable set points is a powerful yet simple automation project. It allows real-time monitoring, user configuration, and visual alerting — just like real industrial controllers.
With minor upgrades like relays and IoT modules, this can be converted into a professional temperature control unit.


0 Comments