#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "TMPL6id6EFANY"
#define BLYNK_TEMPLATE_NAME "bel otomatis "
#define BLYNK_AUTH_TOKEN "ttKmFPFxii2lHuonY7gPI551HQUqGPX1"
//library
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
// #include <SoftwareSerial.h>
// #include <DFRobotDFPlayerMini.h>
#include <EEPROM.h>
#include <Vector.h>
//wifi dan blynk
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST"; //nama hotspot yang digunakan
char pass[] = ""; //password hotspot yang digunakan
//blynk
BlynkTimer timer;
WidgetTerminal terminal(V6)
//dfplayer
// EspSoftwareSerial mp3Serial(16, 17); // rx, tx
// DFRobotDFPlayerMini dfplayer;
//rtc dan lcd
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd (0x27, 16, 2);
// eeprom
#define EEPROM_SIZE 1024
#define MAX_JADWAL 50
//led dan buzzer
const int ledWiFi = 2; // LED indikator WiFi (GPIO2)
const int buzzer = 4; // buzzer jadwal aktif (GPIO4)
//rtc
unsigned long previousMillis = 0;
const long interval = 1000; //update tiap detik
char tujuhHari[7][12] = {"Senin", "Selasa", "Rabu", "Kamis", "Jum'at", "Sabtu", "Ahad"};
//input dari blynk
int inputHari = 0, inputJam = 0, inputMenit = 0, inputFile = 0;
int inputIndex = - 1;
//struktur data jadwal
struct Jadwal {
int hari;
int jam;
int menit;
int file;
};
Jadwal jadwalList[MAX_JADWAL];
int totalJadwal = 0;
//blynk virtual pin
#define VP_STATUS_SISTEM V0
#define VP_HARI V1
#define VP_JAM V2
#define VP_MENIT V3
#define VP_FILE V4
#define VP_TAMBAH_JADWAL V5
#define VP_TERMINAL V6
#define VP_INDEX V7
#define VP_HAPUS_JADWAL V8
#define VP_FILE_UJI V9
#define VP_PUTAR_FILE V10
void setup() {
Serial.begin(115200); //mengaktifkan serial monitor
//inisialisasi pin
pinMode(ledWiFi, OUTPUT);
pinMode(buzzer, OUTPUT);
// Inisialisasi LCD
lcd.init();
lcd.backlight();
// koneksi wifi
WiFi.begin("Wokwi-GUEST", "", 6);
Serial.print("Connecting to WiFi");
lcd.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
for (int positionCounter = 0; positionCounter < 30; positionCounter++) {
delay(250);
lcd.scrollDisplayLeft();
}
lcd.clear();
}
Serial.println(" Connected!");
lcd.print(" Connected!");
digitalWrite(ledWiFi, HIGH); //nyalakan led
tone(buzzer, 100); //play buzzer
delay(1000);
digitalWrite(ledWiFi, LOW); //matikan led
noTone(buzzer); //matikan buzzer
//koneksi blynk
Blynk.begin(auth, ssid, pass); //koneksi ke blynk
//koneksi rtc
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
Serial.println("RTC berhasil diatur!");
// Inisialisasi EEPROM
EEPROM.begin(1024);
muatJadwalTampilkan(); //panggil fungsi muat jadwal dari eeprom dan tampilkan di terminal
// //inisialisasi dfplayer
// mp3Serial.begin();
// dfplayer.begin();
// dfplayer.volume(20);
}
void loop() {
//tampilkan waktu realtime di lcd
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval){
previousMillis = currentMillis;
DateTime now = rtc.now(); //rtc berjalan
lcd.setCursor(0, 0);
lcd.print(String(tujuhHari[now.dayOfTheWeek()])+", ");
Serial.println(String(tujuhHari[now.dayOfTheWeek()])+", "+String(now.day())+'/'+String(now.month())+'/'+String(now.year() % 100));
lcd.setCursor(8, 0);
lcd.print(String(now.day())+'/'+String(now.month())+'/'+String(now.year() % 100));
lcd.setCursor(8, 1);
lcd.print(String(now.hour())+':'+String(now.minute())+':'+String(now.second()));
Serial.println(String(now.hour())+':'+String(now.minute())+':'+String(now.second()));
}
//jalankan fungsi lain
Blynk.run(); //blynk berjalan
timer.run();
// panggil fungsi
cekJadwalBunyikan(); //panggil fungsi cek jadwal dari eeprom dan bunyikan bel jika sesuai realtime.
delay(1000);
}
//muat jadwal dari eeprom dan tampilkan di terminal
void muatJadwalTampilkan() {
terminal.clear(); //membersihkan terminal
totalJadwal = 0;
for (int i = 0; i < MAX_JADWAL; i++) {
Jadwal data;
EEPROM.get(i * sizeof(Jadwal), data);
//validasi hanya simpan jadwal yang masuk akal
if (data.hari >= 1 && data.hari <= 7 && data.jam >= 0 && data.jam <= 24 && data.menit >= 0 && data.menit <= 60 ) {
jadwalList[totalJadwal++] = data;
char buffer[50];
snprintf(buffer, sizeof(buffer), "Jadwal %d; Hari %d %02d;%02d - File %d", totalJadwal, data.hari, data.jam, data.menit, data.file);
terminal.println(buffer);
}
}
if (totalJadwal == 0) {
terminal.println("belum ada jadwal tersimpan");
}
terminal.flush(); //tampilkan di terminal blynk
}
// tambah jadwal
BLYNK_WRITE(VP_HARI) {inputHari = param.asInt();}
BLYNK_WRITE(VP_JAM) {inputJam = param.asInt();}
BLYNK_WRITE(VP_MENIT) {inputMenit = param.asInt();}
BLYNK_WRITE(VP_FILE) {inputFile = param.asInt();}
BLYNK_WRITE(VP_TAMBAH_JADWAL) {
if(param.asInt() == 1) {
if (totalJadwal < MAX_JADWAL) {
Jadwal j;
j.hari = inputHari;
j.jam = inputJam;
j.menit = inputMenit;
j.file = inputFile;
jadwalList[totalJadwal++] = j;
simpanJadwal();
} else {
terminal.println("jadwal penuh");
Serial.println("jadwal penuh");
}
}
terminal.flush();
}
//hapus jadwal
BLYNK_WRITE(VP_HAPUS_JADWAL) {
if (inputIndex >= 0 && inputIndex < totalJadwal) {
for (int i = inputIndex; i < totalJadwal -1; i++) {
jadwalList[i] = jadwalList[i + 1];
}
totalJadwal--;
simpanJadwal();
muatJadwalTampilkan();
} else {
terminal.println("index tidak valid");
Serial.println("index tidak valid");
}
terminal.flush();
}
//putar file untuk uji suara
// BLYNK_WRITE(VP_PUTAR_FILE) {
// if (param.asInt() == 1) {
// int file = Blynk.virtualRead(VP_PUTAR_FILE).asInt();
// dfplayer.play(file);
// }
// }
//cek jadwal dan bunyikan
void cekJadwalBunyikan(){
DateTime now = rtc.now(); //rtc berjalan
for (int i = 0; i < totalJadwal; i++) {
if (jadwalList[i].hari == now.dayOfTheWeek() &&
jadwalList[i].jam == now.hour() &&
jadwalList[i].menit == now.minute()) {
lcd.setCursor(0, 0);
lcd.print("bel aktif ");
Serial.println("bel aktif ");
tone(buzzer, 100); //play buzzer
delay(1000);
noTone(buzzer); //matikan buzzer
delay(60000); //hindari bunyi ulang dalam 1 menit
break;
}
}
}
//simpan jadwal ke eeprom
void simpanJadwal(){
EEPROM.write(0, totalJadwal);
int addr = 1;
for (int i = 0; i<totalJadwal; i++) {
EEPROM.write(addr++, jadwalList[i].hari);
EEPROM.write(addr++, jadwalList[i].jam);
EEPROM.write(addr++, jadwalList[i].menit);
EEPROM.write(addr++, jadwalList[i].file);
}
EEPROM.commit();
Serial.println("jadwal disimpan ke epprom");
}