Stasiun monitoring suhu yang komprehensif.
Fitur-fitur yang akan kita tambahkan meliputi:
Alarm Suhu Tinggi/Rendah: Menggunakan LED dan buzzer untuk memberi peringatan jika suhu melebihi batas atas atau turun di bawah batas bawah.
Pengaturan Batas Alarm: Menggunakan tombol UP/DOWN untuk mengatur nilai batas suhu alarm (tinggi dan rendah) langsung dari perangkat, dengan tampilan di LCD.
Mode Tampilan: Menggunakan tombol Mode untuk beralih antara tampilan suhu normal dan tampilan batas alarm.
Penyimpanan Batas Alarm (EEPROM): Menyimpan nilai batas alarm ke memori non-volatil (EEPROM) Arduino, sehingga pengaturan tidak hilang saat daya mati.
Tombol Reset Alarm: Menghentikan alarm (LED dan buzzer) secara manual.
Stasiun Monitoring Suhu Digital LENGKAP dengan Alarm & Pengaturan
Komponen yang Dibutuhkan:
Arduino Board (Uno disarankan)
Sensor Suhu LM35
LCD 16x2 dengan Modul I2C
2x LED (misalnya, 1 merah untuk alarm tinggi, 1 biru untuk alarm rendah)
2x Resistor 220 Ohm (untuk LED)
1x Buzzer Piezo (aktif atau pasif)
4x Tombol Tekan (Push Button): Mode, Up, Down, Reset Alarm
4x Resistor Pull-down (sekitar 10k ohm)
Kabel Jumper
Skema Pengkabelan (Tambahan & Ringkasan):
LCD 16x2 I2C ke Arduino:
SDA LCD ke A4
SCL LCD ke A5
VCC LCD ke 5V
GND LCD ke GND
Sensor Suhu LM35 ke Arduino:
Vcc ke 5V
Vout ke A0
GND ke GND
LED ke Arduino:
LED Alarm Tinggi (Merah): Anoda (+) ke Digital Pin 10 (via resistor 220 Ohm), Katoda (-) ke GND.
LED Alarm Rendah (Biru): Anoda (+) ke Digital Pin 11 (via resistor 220 Ohm), Katoda (-) ke GND.
Buzzer ke Arduino:
Pin Positif (+) Buzzer: Ke Digital Pin 9.
Pin Negatif (-) Buzzer: Ke GND.
Tombol ke Arduino (semua dengan Resistor Pull-down 10k Ohm ke GND):
Tombol Mode: Ke Digital Pin 2.
Tombol Up: Ke Digital Pin 3.
Tombol Down: Ke Digital Pin 4.
Tombol Reset Alarm: Ke Digital Pin 5.
Instalasi Library:
Pastikan Anda sudah menginstal library LiquidCrystal_I2C
. Jika belum:
Buka Arduino IDE.
Pilih Sketch > Include Library > Manage Libraries...
Cari "LiquidCrystal I2C" (biasanya oleh Frank de Brabander).
Klik "Install".
Kode Program:
// --- Library yang Dibutuhkan ---
#include <Wire.h> // Diperlukan untuk komunikasi I2C
#include <LiquidCrystal_I2C.h> // Library untuk LCD I2C
#include <EEPROM.h> // Library untuk membaca/menulis ke memori EEPROM
// --- Konfigurasi Pin ---
const int LM35_PIN = A0; // Pin analog tempat sensor LM35 terhubung
const int LED_HIGH_ALARM = 10; // LED untuk alarm suhu tinggi
const int LED_LOW_ALARM = 11; // LED untuk alarm suhu rendah
const int BUZZER_PIN = 9; // Pin untuk buzzer
const int BUTTON_MODE_PIN = 2; // Tombol untuk mengganti mode tampilan/pengaturan
const int BUTTON_UP_PIN = 3; // Tombol untuk menaikkan nilai pengaturan
const int BUTTON_DOWN_PIN = 4; // Tombol untuk menurunkan nilai pengaturan
const int BUTTON_RESET_ALARM_PIN = 5; // Tombol untuk mereset alarm
// --- Konfigurasi LCD ---
LiquidCrystal_I2C lcd(0x27, 16, 2); // Alamat I2C umum: 0x27 atau 0x3F
// --- Variabel Pembacaan Suhu ---
float temperatureC = 0; // Suhu dalam Celcius
float temperatureF = 0; // Suhu dalam Fahrenheit
// --- Variabel Alarm ---
int highAlarmLimitC; // Batas alarm suhu tinggi (Celcius)
int lowAlarmLimitC; // Batas alarm suhu rendah (Celcius)
bool alarmActive = false; // Status alarm aktif atau tidak
// --- Variabel untuk Debounce Tombol ---
unsigned long lastButtonModeTime = 0;
unsigned long lastButtonUpTime = 0;
unsigned long lastButtonDownTime = 0;
unsigned long lastButtonResetAlarmTime = 0;
const long DEBOUNCE_DELAY = 50; // Delay debounce dalam milidetik
// --- Variabel Mode Tampilan / Pengaturan ---
enum DisplayMode { NORMAL_TEMP, SET_HIGH_ALARM, SET_LOW_ALARM };
DisplayMode currentDisplayMode = NORMAL_TEMP;
// --- Variabel Update Tampilan ---
unsigned long lastTempUpdateTime = 0;
const long TEMP_UPDATE_INTERVAL = 1000; // Update pembacaan suhu setiap 1 detik
unsigned long lastLCDRefreshTime = 0;
const long LCD_REFRESH_INTERVAL = 250; // Refresh LCD lebih sering untuk responsifitas tombol
// --- Default Alarm Limits (akan disimpan ke EEPROM) ---
const int DEFAULT_HIGH_ALARM = 30; // Default 30 C
const int DEFAULT_LOW_ALARM = 20; // Default 20 C
// --- Alamat EEPROM untuk menyimpan batas alarm ---
const int EEPROM_HIGH_ADDR = 0;
const int EEPROM_LOW_ADDR = 1;
void setup() {
// --- Inisialisasi Pin ---
pinMode(LM35_PIN, INPUT);
pinMode(LED_HIGH_ALARM, OUTPUT);
pinMode(LED_LOW_ALARM, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(BUTTON_MODE_PIN, INPUT);
pinMode(BUTTON_UP_PIN, INPUT);
pinMode(BUTTON_DOWN_PIN, INPUT);
pinMode(BUTTON_RESET_ALARM_PIN, INPUT);
// Matikan LED dan buzzer saat startup
digitalWrite(LED_HIGH_ALARM, LOW);
digitalWrite(LED_LOW_ALARM, LOW);
noTone(BUZZER_PIN); // Memastikan buzzer mati
// --- Inisialisasi Serial (Debugging) ---
Serial.begin(9600);
Serial.println("Digital Thermometer with Alarm & Settings Started");
// --- Inisialisasi LCD ---
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Thermo Station");
lcd.setCursor(0, 1);
lcd.print("Loading Settings...");
delay(2000);
// --- Membaca Batas Alarm dari EEPROM ---
// Baca batas alarm tinggi (jika nilai valid, gunakan itu)
highAlarmLimitC = EEPROM.read(EEPROM_HIGH_ADDR);
if (highAlarmLimitC < -10 || highAlarmLimitC > 99) { // Cek validitas (misal -10C to 99C)
highAlarmLimitC = DEFAULT_HIGH_ALARM;
EEPROM.update(EEPROM_HIGH_ADDR, highAlarmLimitC); // Tulis default jika invalid
}
// Baca batas alarm rendah
lowAlarmLimitC = EEPROM.read(EEPROM_LOW_ADDR);
if (lowAlarmLimitC < -10 || lowAlarmLimitC > 99) {
lowAlarmLimitC = DEFAULT_LOW_ALARM;
EEPROM.update(EEPROM_LOW_ADDR, lowAlarmLimitC);
}
// Pastikan batas rendah tidak lebih tinggi dari batas tinggi
if (lowAlarmLimitC >= highAlarmLimitC) {
lowAlarmLimitC = highAlarmLimitC - 1; // Atur batas rendah 1 di bawah batas tinggi
EEPROM.update(EEPROM_LOW_ADDR, lowAlarmLimitC);
}
Serial.print("Loaded High Alarm: "); Serial.println(highAlarmLimitC);
Serial.print("Loaded Low Alarm: "); Serial.println(lowAlarmLimitC);
// Tampilan awal suhu
readTemperature(); // Baca suhu pertama kali
displayTemperature(); // Tampilkan di LCD
}
void loop() {
unsigned long currentTime = millis();
// --- Pembacaan Suhu (Non-blocking) ---
if (currentTime - lastTempUpdateTime >= TEMP_UPDATE_INTERVAL) {
lastTempUpdateTime = currentTime;
readTemperature();
// Cek alarm hanya saat suhu diperbarui
checkAlarm();
}
// --- Penanganan Tombol ---
handleButtons(currentTime);
// --- Pembaruan Tampilan LCD (lebih sering dari pembacaan suhu) ---
if (currentTime - lastLCDRefreshTime >= LCD_REFRESH_INTERVAL) {
lastLCDRefreshTime = currentTime;
if (currentDisplayMode == NORMAL_TEMP) {
displayTemperature();
} else if (currentDisplayMode == SET_HIGH_ALARM) {
displaySetAlarm("HIGH", highAlarmLimitC);
} else if (currentDisplayMode == SET_LOW_ALARM) {
displaySetAlarm("LOW ", lowAlarmLimitC);
}
}
// --- Alarm Tanda Visual/Auditory ---
if (alarmActive) {
if (temperatureC > highAlarmLimitC) {
digitalWrite(LED_HIGH_ALARM, HIGH);
digitalWrite(LED_LOW_ALARM, LOW); // Pastikan LED lain mati
tone(BUZZER_PIN, 1000); // Nada 1000 Hz
} else if (temperatureC < lowAlarmLimitC) {
digitalWrite(LED_LOW_ALARM, HIGH);
digitalWrite(LED_HIGH_ALARM, LOW); // Pastikan LED lain mati
tone(BUZZER_PIN, 500); // Nada 500 Hz
}
} else {
digitalWrite(LED_HIGH_ALARM, LOW);
digitalWrite(LED_LOW_ALARM, LOW);
noTone(BUZZER_PIN);
}
}
// --- Fungsi-fungsi Pembantu ---
void readTemperature() {
int analogValue = analogRead(LM35_PIN);
float voltage_mV = (analogValue / 1024.0) * 5000.0;
temperatureC = voltage_mV / 10.0;
temperatureF = (temperatureC * 9 / 5) + 32;
}
void checkAlarm() {
if (temperatureC > highAlarmLimitC || temperatureC < lowAlarmLimitC) {
alarmActive = true;
} else {
alarmActive = false;
}
}
void resetAlarm() {
alarmActive = false;
digitalWrite(LED_HIGH_ALARM, LOW);
digitalWrite(LED_LOW_ALARM, LOW);
noTone(BUZZER_PIN);
Serial.println("Alarm manually reset.");
}
void displayTemperature() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperatureC, 1);
lcd.print((char)223); // Karakter derajat
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print(" "); // Untuk membersihkan sisa angka jika ada
lcd.setCursor(0, 1);
lcd.print(temperatureF, 1);
lcd.print((char)223);
lcd.print("F");
}
void displaySetAlarm(const char* label, int limit) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SET ALARM ");
lcd.print(label);
lcd.setCursor(0, 1);
lcd.print("Limit: ");
lcd.print(limit);
lcd.print((char)223);
lcd.print("C");
}
void handleButtons(unsigned long currentTime) {
// --- Tombol Mode ---
if (digitalRead(BUTTON_MODE_PIN) == HIGH && (currentTime - lastButtonModeTime > DEBOUNCE_DELAY)) {
lastButtonModeTime = currentTime;
resetAlarm(); // Reset alarm saat mengganti mode
// Pindah ke mode berikutnya
if (currentDisplayMode == NORMAL_TEMP) {
currentDisplayMode = SET_HIGH_ALARM;
} else if (currentDisplayMode == SET_HIGH_ALARM) {
currentDisplayMode = SET_LOW_ALARM;
} else if (currentDisplayMode == SET_LOW_ALARM) {
currentDisplayMode = NORMAL_TEMP;
}
Serial.print("Mode changed to: "); Serial.println(currentDisplayMode);
lastLCDRefreshTime = 0; // Force refresh LCD immediately
}
// --- Tombol UP (hanya di mode pengaturan) ---
if (currentDisplayMode == SET_HIGH_ALARM || currentDisplayMode == SET_LOW_ALARM) {
if (digitalRead(BUTTON_UP_PIN) == HIGH && (currentTime - lastButtonUpTime > DEBOUNCE_DELAY)) {
lastButtonUpTime = currentTime;
if (currentDisplayMode == SET_HIGH_ALARM) {
highAlarmLimitC++;
if (highAlarmLimitC > 99) highAlarmLimitC = 99; // Batasi max
if (highAlarmLimitC <= lowAlarmLimitC) highAlarmLimitC = lowAlarmLimitC + 1; // Pastikan high > low
EEPROM.update(EEPROM_HIGH_ADDR, highAlarmLimitC); // Simpan ke EEPROM
} else if (currentDisplayMode == SET_LOW_ALARM) {
lowAlarmLimitC++;
if (lowAlarmLimitC > 99) lowAlarmLimitC = 99; // Batasi max
if (lowAlarmLimitC >= highAlarmLimitC) lowAlarmLimitC = highAlarmLimitC - 1; // Pastikan low < high
EEPROM.update(EEPROM_LOW_ADDR, lowAlarmLimitC); // Simpan ke EEPROM
}
Serial.print("Limit set to: "); Serial.println(currentDisplayMode == SET_HIGH_ALARM ? highAlarmLimitC : lowAlarmLimitC);
lastLCDRefreshTime = 0; // Force refresh LCD
}
// --- Tombol DOWN (hanya di mode pengaturan) ---
if (digitalRead(BUTTON_DOWN_PIN) == HIGH && (currentTime - lastButtonDownTime > DEBOUNCE_DELAY)) {
lastButtonDownTime = currentTime;
if (currentDisplayMode == SET_HIGH_ALARM) {
highAlarmLimitC--;
if (highAlarmLimitC < -10) highAlarmLimitC = -10; // Batasi min
if (highAlarmLimitC <= lowAlarmLimitC) highAlarmLimitC = lowAlarmLimitC + 1; // Pastikan high > low
EEPROM.update(EEPROM_HIGH_ADDR, highAlarmLimitC); // Simpan ke EEPROM
} else if (currentDisplayMode == SET_LOW_ALARM) {
lowAlarmLimitC--;
if (lowAlarmLimitC < -10) lowAlarmLimitC = -10; // Batasi min
if (lowAlarmLimitC >= highAlarmLimitC) lowAlarmLimitC = highAlarmLimitC - 1; // Pastikan low < high
EEPROM.update(EEPROM_LOW_ADDR, lowAlarmLimitC); // Simpan ke EEPROM
}
Serial.print("Limit set to: "); Serial.println(currentDisplayMode == SET_HIGH_ALARM ? highAlarmLimitC : lowAlarmLimitC);
lastLCDRefreshTime = 0; // Force refresh LCD
}
}
// --- Tombol Reset Alarm ---
if (digitalRead(BUTTON_RESET_ALARM_PIN) == HIGH && (currentTime - lastButtonResetAlarmTime > DEBOUNCE_DELAY)) {
lastButtonResetAlarmTime = currentTime;
resetAlarm(); // Panggil fungsi reset alarm
}
}
Penjelasan Fitur Baru & Modifikasi:
Library
EEPROM.h
:Diimpor untuk memungkinkan penyimpanan data (batas alarm) ke memori EEPROM non-volatil Arduino. Data yang disimpan di EEPROM tidak akan hilang saat Arduino dimatikan.
Pin Alarm & Tombol Baru:
LED_HIGH_ALARM
,LED_LOW_ALARM
,BUZZER_PIN
untuk output alarm.BUTTON_MODE_PIN
,BUTTON_UP_PIN
,BUTTON_DOWN_PIN
,BUTTON_RESET_ALARM_PIN
untuk input kontrol.
Variabel Alarm:
highAlarmLimitC
,lowAlarmLimitC
: Menyimpan batas suhu alarm (Celcius).alarmActive
:true
jika alarm sedang berbunyi/menyala,false
jika tidak.
Variabel & Logika Debounce Tombol:
Diimplementasikan untuk setiap tombol baru untuk menghindari pembacaan ganda.
Variabel & Enum
DisplayMode
:enum DisplayMode { NORMAL_TEMP, SET_HIGH_ALARM, SET_LOW_ALARM };
: Mendefinisikan mode-mode tampilan/pengaturan yang berbeda.currentDisplayMode
: Menyimpan mode aktif saat ini.
setup()
Function:Inisialisasi Pin Output: Semua pin LED dan buzzer diatur sebagai
OUTPUT
.Inisialisasi Pin Input: Semua pin tombol diatur sebagai
INPUT
(dengan asumsi pull-down eksternal).Membaca dari EEPROM:
EEPROM.read(address)
digunakan untuk membaca nilai yang tersimpan.Ada validasi nilai yang dibaca dari EEPROM. Jika nilai yang dibaca aneh (di luar rentang -10C hingga 99C), itu berarti EEPROM mungkin kosong atau korup, jadi kita set ke nilai default dan menyimpannya (
EEPROM.update()
).EEPROM.update(address, value)
: Mirip denganEEPROM.write()
, tapiupdate()
hanya menulis jika nilai berbeda dari yang sudah ada, memperpanjang masa pakai EEPROM.
Menyesuaikan Batas: Memastikan
lowAlarmLimitC
selalu lebih rendah darihighAlarmLimitC
secara otomatis.
loop()
Function:Pembacaan Suhu: Dilakukan setiap
TEMP_UPDATE_INTERVAL
(1 detik) menggunakanmillis()
(non-blocking).checkAlarm()
: Dipanggil setelah pembacaan suhu untuk menentukan apakah alarm harus aktif.handleButtons()
: Fungsi terpisah untuk memproses semua input tombol, menjagaloop()
tetap rapi.Pembaruan Tampilan LCD: Sekarang diperbarui lebih sering (
LCD_REFRESH_INTERVAL
, 250ms) untuk responsifitas tombol di mode pengaturan, tetapi pembacaan suhu hanya setiap 1 detik.Logika Alarm Visual/Auditory: Menyalakan LED dan buzzer sesuai kondisi alarm (
temperatureC
vs.highAlarmLimitC
/lowAlarmLimitC
). Nada buzzer berbeda untuk alarm tinggi dan rendah.
Fungsi Pembantu Baru:
readTemperature()
: Fungsi untuk membaca sensor LM35.checkAlarm()
: Fungsi untuk menentukan apakah kondisi alarm terpenuhi.resetAlarm()
: Fungsi untuk mematikan LED dan buzzer alarm secara manual. Ini dipanggil oleh tombol reset dan saat mengubah mode.displayTemperature()
: Fungsi untuk menampilkan suhu normal di LCD.displaySetAlarm(const char* label, int limit)
: Fungsi untuk menampilkan mode pengaturan batas alarm di LCD.handleButtons(unsigned long currentTime)
: Mengelola semua logika penekanan tombol dan debounce.
Logika Pengaturan Batas Alarm di
handleButtons()
:Tombol Mode:
Saat ditekan, ia memutar (
NORMAL_TEMP -> SET_HIGH_ALARM -> SET_LOW_ALARM -> NORMAL_TEMP
).Juga memanggil
resetAlarm()
saat mode diubah.
Tombol UP/DOWN:
Hanya aktif saat
currentDisplayMode
adalahSET_HIGH_ALARM
atauSET_LOW_ALARM
.Menambah/mengurangi batas alarm yang sesuai (
highAlarmLimitC
ataulowAlarmLimitC
).Ada batas minimum/maksimum (-10C hingga 99C) dan aturan
highAlarmLimitC
harus selalu lebih besar darilowAlarmLimitC
.Setiap perubahan batas disimpan langsung ke EEPROM menggunakan
EEPROM.update()
.
Tombol Reset Alarm: Memanggil fungsi
resetAlarm()
untuk mematikan indikator alarm.
Sebelum Mengunggah Program:
Pastikan Semua Pengkabelan Benar: Verifikasi setiap pin dan sambungan. Ingat keselamatan listrik saat berurusan dengan komponen AC (jika ini bagian dari sistem yang lebih besar) dan LED/Buzzer.
Instal Library: Pastikan
LiquidCrystal_I2C
terinstal.EEPROM
adalah library bawaan.Periksa Alamat I2C LCD: Jika LCD tidak berfungsi, periksa alamat I2C di
LiquidCrystal_I2C lcd(0x27, 16, 2);
.Pilih Board dan Port: Di Arduino IDE, pilih board dan port yang benar.
Unggah Kode: Klik tombol "Upload".
Setelah program diunggah, Anda akan memiliki stasiun monitoring suhu digital yang sangat fungsional. Anda bisa melihat suhu, mengatur batas alarm, dan sistem akan memberi peringatan jika suhu keluar dari batas yang aman.
Komentar
Posting Komentar