#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <DHTesp.h>
#include <WiFi.h> // updating time via wifi
// Define OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
#define BUZZER 14 // Defining Buzzer
#define LED_1 13 // Defining LED
#define PB_CANCEL 1 //define Push Button CANCEL
#define PB_OK 47 //define Push Button OK
#define PB_UP 48 //define Push Button UP
#define PB_DOWN 21 //define Push Button DOWN
//Wifi Timing initialize
#define NTP_SERVER "pool.ntp.org"
#define UTC_OFFSET 19800
#define UTC_OFFSET_DST 0
// Define I2C
#define SDA_PIN 5 // or any other suitable GPIO
#define SCL_PIN 4
const int DHTPIN = 3;
//#define DHTPIN 2 //Define DHT pin
// Define Buzzer Notes
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};
// Declare Objects
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
DHTesp dhtSensor;
//define global variable
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
// initializing the alarm
bool alarm_enabled = (true);
int n_alarms = 2;
int alarm_hours[] = {0,1};
int alarm_minutes[] = {1,10};
bool alarm_trigered[] = {false,false};
// to update the time manually
unsigned long timeNow = 0;
unsigned long timeLast = 0;
//initiatizing Menu
int current_mode =0;
int max_modes = 4;
String modes[] = {"1 - Set Time", "2 - Set Alarm 1", "3 - Set Alarm 2", "4 - Disable Alarms"};
void setup() {
//Define Buzzer and LED
pinMode(BUZZER, OUTPUT);
pinMode(LED_1, OUTPUT);
pinMode(PB_CANCEL, INPUT); // define Push Button
pinMode(PB_OK, INPUT); // define menu
pinMode(PB_UP, INPUT);
pinMode(PB_DOWN, INPUT);
dhtSensor.setup(DHTPIN, DHTesp::DHT22); // Setup DHT sensor
Serial.begin(115200); // initialise serial monitor and OLED display
Wire.begin(SDA_PIN, SCL_PIN); // initialise I2C Comm
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 Allocation Failed"));
for(;;);
}
display.display(); // Turning on the display
delay(2000);
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
display.clearDisplay();
print_line("Connecting to WIFI", 0, 0, 2);
}
display.clearDisplay();
print_line("Connectied to WIFI", 0, 0, 2);
configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
display.clearDisplay(); // clear the screen
print_line("Welcome to Medibox!", 10, 20, 2);
delay(1000);
display.clearDisplay(); // to remove welcome screen
}
void loop() {
update_the_time_with_check_alarm (); // Update the Time
if(digitalRead(PB_OK) == HIGH) {
delay(200);
go_to_menu();
}
check_temp();
}
void print_line(String text, int colum, int row, int text_size){ // Function print_line
delay (100); // to slow down the time counter
// display.clearDisplay(); have to remove this to print time now
// display customised msg
display.setTextSize(text_size);
display.setTextColor(SSD1306_WHITE);
display.setCursor(colum, row);
display.println(text);
display.display();
// delay(2000); have to remove this to print time now
}
void print_time_now(void){ // Function time_now
display.clearDisplay(); // to remove welcome screen
print_line(String (days), 0, 0, 2);
print_line(":", 20, 0, 2);
print_line(String (hours), 30, 0, 2);
print_line(":", 50, 0, 2);
print_line(String (minutes), 60, 0, 2);
print_line(":", 80, 0, 2);
print_line(String (seconds), 90, 0, 2);
}
void update_time(){ // Function update_time
struct tm timeinfo; // Get the time from WIFI
getLocalTime(&timeinfo);
char timeHour[3];
strftime(timeHour,3, "%H", &timeinfo);
hours = atoi(timeHour);
char timeMinutes[3];
strftime(timeMinutes,3, "%M", &timeinfo);
minutes = atoi(timeMinutes);
char timeSeconds[3];
strftime(timeSeconds,3, "%S", &timeinfo);
seconds = atoi(timeSeconds);
char timeDay[3];
strftime(timeDay,3, "%d", &timeinfo);
days = atoi(timeDay);
}
/*
timeNow = millis()/1000; // since it calculate in mili seconds
seconds = timeNow - timeLast;
if (seconds >= 60){
minutes += 1; // to countdown minutes
timeLast += 60;
}
if (minutes >= 60){
hours += 1; // to countdown hours
minutes = 0;
}
if (hours >= 24){
days += 1; // to countdown hours
hours = 0;
}
}*/
void ring_alarm() { // Function ring_alarm
display.clearDisplay();
print_line("Time to Take Medicine!", 0, 0, 2);
digitalWrite(LED_1, HIGH);
bool break_happend = false;
while(break_happend == false && digitalRead(PB_CANCEL) == HIGH) {
// Ring the Buzzer
for(int i = 0; i < 8; i++){
if(digitalRead(PB_CANCEL) == LOW) {
delay(200);
break_happend = true;
break;
}
tone(BUZZER,notes[i]);
delay(500);
noTone(BUZZER);
delay(2);
}
}
digitalWrite(LED_1, LOW);
display.clearDisplay();
}
void update_the_time_with_check_alarm (void){ // Function update the time with check alarm
update_time();
print_time_now();
if (alarm_enabled == true) {
for (int i = 0; i < n_alarms; ++i){
if (alarm_trigered [i] == false && alarm_hours [i]== hours && alarm_minutes [i]== minutes){
ring_alarm();
alarm_trigered [i] = true;
}
}
}
}
int wait_for_button_press(){ // Defining temp int with following function
while(true){
if(digitalRead(PB_UP) == HIGH){
delay(200);
return PB_UP;
}
else if(digitalRead(PB_DOWN) == HIGH){
delay(200);
return PB_DOWN;
}
else if(digitalRead(PB_OK) == HIGH){
delay(200);
return PB_OK;
}
else if(digitalRead(PB_CANCEL) == LOW){
delay(200);
return PB_CANCEL;
update_time;
}
}
}
void go_to_menu() { // Function go_to_menu
while (digitalRead(PB_CANCEL) == HIGH){
display.clearDisplay();
print_line(modes[current_mode], 0, 0, 2);
int pressed = wait_for_button_press(); // Define temp int
if(pressed == PB_UP){
delay(200);
current_mode += 1;
current_mode = current_mode % max_modes;
}
else if(pressed == PB_DOWN){
delay(200);
current_mode -= 1;
if (current_mode<0){
current_mode = max_modes - 1;
}
}
else if(pressed == PB_OK){
delay(200);
run_mode(current_mode);
}
else if(pressed == PB_CANCEL){
delay(200);
break;
}
}
}
void set_time(){ // Function set_time
int temp_hour = hours; // Define temp int
while (true){
display.clearDisplay();
print_line("Enter hour:" + String(temp_hour), 0, 0, 2);
int pressed = wait_for_button_press();
if(pressed == PB_UP){
delay(200);
temp_hour += 1;
temp_hour = temp_hour % 24;
}
else if(pressed == PB_DOWN){
delay(200);
temp_hour -= 1;
if (temp_hour<0){
temp_hour = 23;
}
}
else if(pressed == PB_OK){
delay(200);
hours = temp_hour;
break;
}
else if(pressed == PB_CANCEL){
delay(200);
break;
}
}
int temp_minute = minutes; // Define temp int
while (true){
display.clearDisplay();
print_line("Enter minute:" + String(temp_minute), 0, 0, 2);
int pressed = wait_for_button_press(); // Define temp int
if(pressed == PB_UP){
delay(200);
temp_minute += 1;
temp_minute = temp_minute % 60;
}
else if(pressed == PB_DOWN){
delay(200);
temp_minute -= 1;
if (temp_minute<0){
temp_minute = 59;
}
}
else if(pressed == PB_OK){
delay(200);
minutes = temp_minute;
break;
}
else if(pressed == PB_CANCEL){
delay(200);
break;
}
}
display.clearDisplay();
print_line("Time is set", 0, 0, 2);
delay(1000);
}
int set_alarm(int alarm){
int temp_hour = alarm_hours[alarm];
while (true){
display.clearDisplay();
print_line("Enter hour:" + String(temp_hour), 0, 0, 2);
int pressed = wait_for_button_press();
if(pressed == PB_UP){
delay(200);
temp_hour += 1;
temp_hour = temp_hour % 24;
}
else if(pressed == PB_DOWN){
delay(200);
temp_hour -= 1;
if (temp_hour<0){
temp_hour = 23;
}
}
else if(pressed == PB_OK){
delay(200);
alarm_hours[alarm] = temp_hour;
break;
}
else if(pressed == PB_CANCEL){
delay(200);
break;
}
}
int temp_minute = alarm_minutes[alarm];
while (true){
display.clearDisplay();
print_line("Enter minute:" + String(temp_minute), 0, 0, 2);
int pressed = wait_for_button_press();
if(pressed == PB_UP){
delay(200);
temp_minute += 1;
temp_minute = temp_minute % 60;
}
else if(pressed == PB_DOWN){
delay(200);
temp_minute -= 1;
if (temp_minute<0){
temp_minute = 59;
}
}
else if(pressed == PB_OK){
delay(200);
alarm_minutes[alarm] = temp_minute;
break;
}
else if(pressed == PB_CANCEL){
delay(200);
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 == 1 || mode ==2){
set_alarm(mode - 1);
}
else if (mode ==3){
alarm_enabled = false;
}
}
void check_temp () { // Fucnvtion check_temp
TempAndHumidity data = dhtSensor.getTempAndHumidity();
/*
if(data.temperature > 32) {
//display.clearDisplay();
print_line("TEMP HIGH", 0, 40, 1);
}
else if(data.temperature < 24) {
//display.clearDisplay();
print_line("TEMP LOW", 0, 40, 1);
}
else {
print_line("TEMP OK", 0, 40, 1);
}
if(data.humidity > 80) {
//display.clearDisplay();
print_line("HUMIDITY HIGH", 0, 50, 1);
}
else if(data.humidity < 65) {
//display.clearDisplay();
print_line("HUMIDITY LOW", 0, 50, 1);
}
else {
print_line("HUMIDITY OK", 0, 50, 1);
}
*/
if(data.temperature > 32 || data.temperature < 24 || data.humidity > 80 || data.humidity < 65) {
digitalWrite(LED_1, HIGH);
tone(BUZZER, 1000, 500);
}
else {
digitalWrite(LED_1, LOW);
noTone(BUZZER);
}
display.display();
delay (1000);
}