//Include libraries
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHTesp.h>
#include <WiFi.h>
//pins declaration
#define BUZZER 5
#define LED_1 15
#define PB_CANCEL 33
#define PB_OK 32
#define PB_UP 34
#define PB_DOWN 35
#define DHTpin 15
//OLED parameters
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0X3c //should check with data sheet
//Wifi parameters
#define NTP_SERVER "pool.ntp.org"
#define UTC_OFFSET 19800
#define UTC_OFFSET_DST 0
// declare objects
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //OLED display
DHTesp DHT;
// variables
float temp;
float humidity;
//tones
int n_notes = 8;
int C = 262;
int D = 294;
int E = 330;
int F = 349;
int G = 392;
int A = 440;
int B = 494;
int C_H = 523;
int notes[] = {C, D, E, F, G, A, B, C_H};
//time
int day;
int hr;
int mint;
int sec;
//alarms
int n_alarm = 3;
int alarms[3][2]; // Alarms will be saved in 2D array in form of (hr,mint)
bool alarm_triggered[3] ;
bool alarm_enable = true;
//Menu
int current_mode = 0;
int max_modes = 5;
String modes[] = {"1-Set Time", "2-Set Alarm 1", "3-Set Alarm 2", "4-Set Alarm 3", "5-Disable Alarms"};
//functions
void readDHT();
// void print_DHT();
void print_line(String txt, int col, int row, int txt_size);
void update_time();
void print_time_DHT();
void set_alarm(int h, int m);
void check_alarm();
void ring_alarm();
void goto_menu();
void setup() {
// setting pinmodes
pinMode(BUZZER, OUTPUT);
pinMode(LED_1, OUTPUT);
pinMode(PB_CANCEL, INPUT);
pinMode(PB_OK, INPUT);
pinMode(PB_UP, INPUT);
pinMode(PB_DOWN, INPUT);
// DHT setup
DHT.setup(DHTpin, DHTesp::DHT22);
// display settup
Serial.begin(115200);
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); // initiating OLED
display.clearDisplay();
delay(100);
print_line("smart Medibox...", 0, 10, 2);
delay(500);
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
display.clearDisplay();
print_line("Connectingto WiFi...", 0, 5, 2);
}
display.clearDisplay();
print_line("Connected.", 0, 5, 2);
configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
display.clearDisplay();
}
void loop() {
update_time();
readDHT();
check_alarm();
display.clearDisplay();
print_time_DHT();
if (digitalRead(PB_OK) == LOW) {
delay(200);
go_to_menu();
}
delay(250);
}
void readDHT() {
TempAndHumidity DHTdata = DHT.getTempAndHumidity();
temp = DHTdata.temperature;
humidity = DHTdata.humidity;
return;
}
//print functions
void print_line(String txt, int col, int row, int txt_size) {
display.setTextSize(txt_size);
display.setTextColor(SSD1306_WHITE);
display.setCursor(col, row);
display.println(txt);
display.display();
}
void print_time_DHT() {
// display time
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 10);
display.print(String(hr));
display.setCursor(30, 10);
display.print(":");
display.setCursor(40, 10);
display.print(String(mint));
display.setCursor(60, 10);
display.print(":");
display.setCursor(70, 10);
display.print(String(sec));
//display temperature and humidity
display.setTextSize(1);
display.setCursor(0, 35);
display.print("T:" + String(temp, 2) + "C");
display.setCursor(72, 35);
display.print("H:" + String(humidity, 1) + "%");
display.setCursor(0, 52);
display.print("Main Menu : Press OK");
display.display();
}
// void print_DHT() {
// display.setTextSize(1);
// display.setCursor(0, 55);
// display.println("T:" + String(temp, 2) + "C");
// display.setCursor(72, 55);
// display.println("H:" + String(humidity, 1) + "%");
// display.display();
// }
void update_time() {
struct tm timeinfo;
getLocalTime(&timeinfo);
char timeHour[3];
strftime(timeHour, 3, "%H", &timeinfo);
hr = atoi(timeHour);
char timeMinute[3];
strftime(timeMinute, 3, "%M", &timeinfo);
mint = atoi(timeMinute);
char timeSecond[3];
strftime(timeSecond, 3, "%S", &timeinfo);
sec = atoi(timeSecond);
char timeDay[3];
strftime(timeDay, 3, "%d", &timeinfo);
day = atoi(timeDay);
}
// void set_alarm(int h, int m) {
// alarms[n_alarm][0] = h;
// alarms[n_alarm][1] = m;
// n_alarm ++;
// }
void check_alarm() {
if (alarm_enable) {
for (int i = 0; i < n_alarm; i++) {
if (alarm_triggered[i] == false && alarms[i][0] == hr && alarms[i][1] == mint) {
ring_alarm();
alarm_triggered[i] = true;
}
}
}
}
void ring_alarm() {
display.clearDisplay();
print_line("Take", 0, 10, 2);
print_line("Medicines", 0, 32, 2);
bool break_happened = false;
//Ring the buzzer to alert
while (break_happened == false && digitalRead(PB_CANCEL) == HIGH) {
for (int i = 0; i < n_notes; i++) {
if (digitalRead(PB_CANCEL) == LOW) {
delay(200);
break_happened = true;
break;
}
tone(BUZZER, notes[i]);
delay(500);
noTone(BUZZER);
delay(2);
}
}
// digitalWrite(LED_1, LOW);
display.clearDisplay();
}
//Menu
void go_to_menu() {
while (digitalRead(PB_CANCEL) == HIGH) {
display.clearDisplay();
print_line(modes[current_mode], 0, 0, 2);
int pressed = wait_for_button_press();
if (pressed == PB_UP) {
current_mode += 1;
current_mode = current_mode % max_modes;
}
else if (pressed == PB_DOWN) {
current_mode -= 1;
if (current_mode < 0) {
current_mode = max_modes - 1;
}
}
else if (pressed == PB_OK) {
run_mode(current_mode);
}
else if (pressed == PB_CANCEL) {
break;
}
}
}
int wait_for_button_press() {
while (true) {
if (digitalRead(PB_UP) == LOW) {
delay(200);
return PB_UP;
}
else if (digitalRead(PB_DOWN) == LOW) {
delay(200);
return PB_DOWN;
}
else if (digitalRead(PB_OK) == LOW) {
delay(200);
return PB_OK;
}
else if (digitalRead(PB_CANCEL) == LOW) {
delay(200);
return PB_CANCEL;
}
update_time();
}
}
void set_time() {
int temp_hour = hr;
while (true) {
display.clearDisplay();
print_line("Enter hour: " + String(temp_hour), 0, 0, 2);
int pressed = wait_for_button_press();
if (pressed == PB_UP) {
temp_hour += 1;
temp_hour = temp_hour % 24;
}
else if (pressed == PB_DOWN) {
temp_hour -= 1;
if (temp_hour < 0) {
temp_hour = 23;
}
}
else if (pressed == PB_OK) {
hr = temp_hour;
break;
}
else if (pressed == PB_CANCEL) {
break;
}
}
int temp_minute = mint;
while (true) {
display.clearDisplay();
print_line("Enter minute: " + String(temp_minute), 0, 0, 2);
int pressed = wait_for_button_press();
if (pressed == PB_UP) {
temp_minute += 1;
temp_minute = temp_minute % 60;
}
else if (pressed == PB_DOWN) {
temp_minute -= 1;
if (temp_minute < 0) {
temp_minute = 59;
}
}
else if (pressed == PB_OK) {
mint = temp_minute;
break;
}
else if (pressed == PB_CANCEL) {
break;
}
}
display.clearDisplay();
print_line("Time is set", 0, 0, 2);
delay(1000);
}
void set_alarm(int alarm) {
int temp_hour = alarms[alarm][0];
while (true) {
display.clearDisplay();
print_line("Enter hour: " + String(temp_hour), 0, 0, 2);
int pressed = wait_for_button_press();
if (pressed == PB_UP) {
temp_hour += 1;
temp_hour = temp_hour % 24;
}
else if (pressed == PB_DOWN) {
temp_hour -= 1;
if (temp_hour < 0) {
temp_hour = 23;
}
}
else if (pressed == PB_OK) {
alarms[alarm][0] = temp_hour;
break;
}
else if (pressed == PB_CANCEL) {
break;
}
}
int temp_minute = alarms[alarm][1];
while (true) {
display.clearDisplay();
print_line("Enter minute: " + String(temp_minute), 0, 0, 2);
int pressed = wait_for_button_press();
if (pressed == PB_UP) {
temp_minute += 1;
temp_minute = temp_minute % 60;
}
else if (pressed == PB_DOWN) {
temp_minute -= 1;
if (temp_minute < 0) {
temp_minute = 59;
}
}
else if (pressed == PB_OK) {
alarms[alarm][1] = temp_minute;
break;
}
else if (pressed == PB_CANCEL) {
break;
}
}
display.clearDisplay();
print_line("Alarm is set", 0, 0, 2);
delay(1000);
}
void run_mode(int mode) {
if (mode == 0) {
set_time();
}
else if (mode > 0 && mode < 4) {
set_alarm(mode - 1);
}
else if (mode == 4) {
alarm_enable = !alarm_enable;
display.clearDisplay();
if (alarm_enable){
modes[4] = "5-Disable Alarms";
print_line("Alarms are enabled",0,0,2);
}
else{
modes[4] = "5-Enable Alarms";
print_line("Alarms are disabled",0,0,2);
}
delay(2000);
}
}