//added 2024.1.16 , //if flash_back_light_check_tag ==1, wil flash if needed. // flash_back_light_check_tag==0, no flashing,it is a pure clock ///2024.jan 16 (for non-backlight-flashing clock) % 2023.12.14a, 2023.12.13a,2023.12.04a, 2023.11.27 add button fto control backlight // 2023.8.30 fix the bug of resetting the clock // use setup_new_time_RTC_DS3231 for setting the clock // //remember to comment all after time is set correctly. Otherewise when power off it will affect the current time. // 2022.3.16 rtc3b5.ino See http://misclab.umeoce.maine.edu/boss/Arduino/bensguides/DS3231_Arduino_Clock_Instructions.pdf /* khwong 2020 march 22, combining DS3231+LCD+serail-port display using DS3231 library, by Andrew Wickert, Eric Ayars, Jean-Claude Wippler version 1.02 installation: //Sketch/inlucde_library/manage librray/type DS3231, Can try examples : Files/Exaples/DS3231/ Reference :DS3231_test.pde Eric Ayars 4/11 Test/demo of read routines for a DS3231 RTC. Turn on the serial monitor after loading this to check if things are working as they should. */ /* DS3231_test.pde Eric Ayars 4/11 Test/demo of read routines for a DS3231 RTC. Turn on the serial monitor after loading this to check if things are working as they should. */ //////////////////////// LCD ////////////////////// #include #include "DHT.h" #define DHTPIN 7 #define DHTTYPE DHT11 const int buttonPin = 2; // the number of the pushbutton pin const int backlight_pin = 4; // High=light_on, Low =light_off // variables will change: int buttonState = 0; // variable for reading the pushbutton status int count1, count2; int sval; int command_tag1 = 0; int old_sval = 1; #include "U8glib.h" // for lcd 128x64 display U8GLIB_ST7920_128X64_4X u8g(10); DHT dht(DHTPIN, DHTTYPE); #include LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display //LiquidCrystal_I2C lcd(0x3F,20,2); // set the LCD address to 0x27 for a 16 chars and 2 line display //LiquidCrystal_I2C lcd(0x3F,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display float dht11_temperature, dht11_humidity; // make global because many modules are using it int flash_tag_am, flash_tag_pm; int flash_back_light_check_tag;//added 2024.1.16 , //if flash_back_light_check_tag ==1, wil flash if neede. // flash_back_light_check_tag==0, no flashing,it is a pure clock //int minute_count = 0; void setup() { flash_back_light_check_tag=0; // u8g.setRot90();// u8g.setRot180(); Serial.begin(9600); lcd.init(); // initialize the lcd lcd.backlight(); lcd.setCursor(3, 0); //first row: line 0,cursor index 3. first postion is index 0 lcd.print("By KH WONG"); lcd.setCursor(0, 1); //second row : line 1, position index 2 lcd.print("ver. 2023.08.30"); delay(1000); lcd.clear(); //////////backlight_setup ////////////////////////// pinMode(backlight_pin, OUTPUT); //botton and backlight pinMode(buttonPin, INPUT); //// initialize the pushbutton pin as an input: //////////////////////////////// setup_new_time_RTC_DS3231(); // if you want to change the time//////////////// Serial.println("DHTxx test!"); dht.begin(); pinMode(2, INPUT_PULLUP); //google input pin (yellow reset button) digitalWrite(backlight_pin, HIGH); // backlight, HIGH = on;LOW = off flash_tag_am = 1; flash_tag_pm = 1; } #include #include DS3231 Clock; bool Century = false; bool h12; bool PM; byte ADay, AHour, AMinute, ASecond, ABits; bool ADy, A12h, Apm; //remember to comment all after time is set correctly. Otherewise when power off it will affect the current time. void setup_new_time_RTC_DS3231() { // edit the following for clock adjustment /* Clock.setSecond(00);//Set the second Clock.setMinute(53);//Set the minute Clock.setHour(14); //Set the hour Clock.setDoW(3); //Set the day of the week` Clock.setDate(13); //Set the date of the month Clock.setMonth(12); //Set the month of the year Clock.setYear(23); //Set the year (Last two digits of the year) */ //Clock.setHour(9); //Set the hour // Clock.setMinute(30);//Set the minute } void clear_screen_12864() { uint8_t x, y; u8g.setColorIndex(0); for (y = 0; y < 128; y++) { for (x = 0; x < 64; x++) { u8g.drawPixel(x, y); } } u8g.setColorIndex(1); //restore color to 1 } void u8g_prepare(void) { u8g.setFont(u8g_font_6x10); u8g.setFontRefHeightExtendedText(); u8g.setDefaultForegroundColor(); u8g.setFontPosTop(); } void u8g_drawStr_12864_2digits(int x, int y, int val) { char buf[12]; if (val <= 9) { u8g.drawStr(x, y, "0"); u8g.drawStr(x + 8, y, itoa(val, buf, 10)); } else { u8g.drawStr(x, y, itoa(val, buf, 10)); } } /////////////////////////////////////////////////////////////////////////// void draw_vert_hk_uk_usa_time_LCD12864(int month, int date, int dow, int hour, int minute, int second) { // graphic commands to redraw the complete screen should be placed here u8g.setRot270(); u8g.setFont(u8g_font_unifont); u8g.setFontPosTop(); //////////// draw style 2 ////////////////// //-------------HK ---------------------------------------- u8g.setScale2x2(); // Scale up all draw procedures char buf[12]; // "-2147483648\0" u8g_drawStr_12864_2digits(0, 0, hour); u8g_drawStr_12864_2digits(0 + 1, 0, hour); u8g_drawStr_12864_2digits(16, 0, minute); u8g_drawStr_12864_2digits(16 + 1, 0, minute); //-------------UK ---------------------------------------- byte summer_uk; //////////////////////////////////////////////////////////////////// //UK 2022 27 March sunday begins, 30 October sunday ends, Last sunday of march/oct if (3 < month || month > 10) { summer_uk = 0; } if (month >= 3 && month <= 10) { summer_uk = 1; } if (month == 3 && ((31 - date) - dow) >= 0) { // for march only ?????? summer_uk = 0; } if (month == 10 && ((30 - date) - dow) <= 0) { // for nov only ???? summer_uk = 1; } //////////////////////////////////////////////////////////////// if (summer_uk == 1) { u8g_drawStr_12864_2digits(0, 11, (hour + 16 + 1) % 24); u8g_drawStr_12864_2digits(0 + 1, 11, (hour + 16 + 1) % 24); } else { u8g_drawStr_12864_2digits(0, 11, (hour + 16) % 24); u8g_drawStr_12864_2digits(0 + 1, 11, (hour + 16) % 24); } u8g_drawStr_12864_2digits(16, 11, minute); u8g_drawStr_12864_2digits(16 + 1, 11, minute); //-------------US ---------------------------------------- // handle day_light_saving_us ////////////////////////////////////// // https://stackoverflow.com/questions/5590429/calculating-daylight-saving-time-from-only-date byte summer_us; //////////////////////////////////////////////////////////////////// //USA summer time: //begin march 13 sunday; //end Nov.6 sunday //January, february, and december are out. if (3 < month || month > 11) { summer_us = 0; } if (month >= 3 && month <= 11) { summer_us = 1; } if (month == 3 && (date - dow) < 0) { // for march only summer_us = 0; } if (month == 11 && (date - dow) > 0) { // for nov only summer_us = 0; } //////////////////////////////////////////////////////////////// if (summer_us == 1) { u8g_drawStr_12864_2digits(0, 22, ((hour + 8 + 1) % 24)); //summer ; day light saving :usa time u8g_drawStr_12864_2digits(0 + 1, 22, ((hour + 8 + 1) % 24)); //summer; day light saving :write again to make font larger } else { u8g_drawStr_12864_2digits(0, 22, ((hour + 8) % 24)); //usa time u8g_drawStr_12864_2digits(0 + 1, 22, ((hour + 8) % 24)); //write again to make font larger } u8g_drawStr_12864_2digits(16, 22, minute); u8g_drawStr_12864_2digits(16 + 1, 22, minute); //---- second u8g.drawStr(0, 33, ":"); u8g.drawStr(0 + 1, 33, ":"); u8g_drawStr_12864_2digits(6, 33, second); u8g_drawStr_12864_2digits(6 + 1, 33, second); ////////////////////////////////////////////////////////////// u8g.undoScale(); // IMPORTANT: Switch back to normal mode // u8g.drawStr(112, 10, "HK"); // u8g.drawStr(112 + 1, 10, "HK"); if (summer_uk == 1) { int y_pos_s = 90; //display light saving logo int x_pos_s = 55; //display light saving logo u8g.drawStr(x_pos_s, y_pos_s, "*"); //display light saving logo * } if (summer_us == 1) { int y_pos_s = 90; //display light saving logo int x_pos_s = 55; //display light saving logo u8g.drawStr(x_pos_s, y_pos_s, "+"); //display light saving logo + } } ////////////////////////////////////////////////////////////////////////////// void draw_vert_year_date_temp_humidity_LCD12864() { char buf[12]; // "-2147483648\0" int y_pos = 90; int x_pos = 0; ////u8g.drawStr(x_pos,y_pos,"20"); //u8g_drawStr_12864_2digits(0,y_pos,Clock.getYear()); int x_pos1 = 0; switch (Clock.getMonth(Century)) { case 1: u8g.drawStr(x_pos1, y_pos, "Jan"); u8g.drawStr(x_pos1 + 1, y_pos, "Jan"); break; case 2: u8g.drawStr(x_pos1, y_pos, "Feb"); u8g.drawStr(x_pos1 + 1, y_pos, "Feb"); break; case 3: u8g.drawStr(x_pos1, y_pos, "Mar"); u8g.drawStr(x_pos1 + 1, y_pos, "Mar"); break; case 4: u8g.drawStr(x_pos1, y_pos, "Apr"); u8g.drawStr(x_pos1 + 1, y_pos, "Apr"); break; case 5: u8g.drawStr(x_pos1, y_pos, "May"); u8g.drawStr(x_pos1 + 1, y_pos, "May"); break; case 6: u8g.drawStr(x_pos1, y_pos, "Jun"); u8g.drawStr(x_pos1 + 1, y_pos, "Jun"); break; case 7: u8g.drawStr(x_pos1, y_pos, "Jul"); u8g.drawStr(x_pos1 + 1, y_pos, "Jul"); break; case 8: u8g.drawStr(x_pos1, y_pos, "Aug"); u8g.drawStr(x_pos1 + 1, y_pos, "Aug"); break; case 9: u8g.drawStr(x_pos1, y_pos, "Sep"); u8g.drawStr(x_pos1 + 1, y_pos, "Sep"); break; case 10: u8g.drawStr(x_pos1, y_pos, "Oct"); u8g.drawStr(x_pos1 + 1, y_pos, "Oct"); break; case 11: u8g.drawStr(x_pos1, y_pos, "Nov"); u8g.drawStr(x_pos1 + 1, y_pos, "Nov"); break; case 12: u8g.drawStr(x_pos1, y_pos, "Dec"); u8g.drawStr(x_pos1 + 1, y_pos, "Dec"); break; default: lcd.print("???"); break; } // u8g.drawStr(22, 46, "."); // u8g.drawStr(22 + 1, 46, "."); u8g_drawStr_12864_2digits(x_pos + 28, y_pos, Clock.getDate()); u8g_drawStr_12864_2digits(x_pos + 28 + 1, y_pos, Clock.getDate()); //u8g.drawStr(40, y_pos, "("); int x_pos2 = 0; int y_pos2 = 101; int x_pos3 = 0; int y_pos3 = 113; // u8g_drawStr_12864_2digits(90-38,46,Clock.getDoW()); switch (Clock.getDoW()) { case 1: u8g.drawStr(x_pos2, y_pos2, "Mon"); u8g.drawStr(x_pos2 + 1, y_pos2, "Mon"); break; case 2: u8g.drawStr(x_pos2, y_pos2, "Tue"); u8g.drawStr(x_pos2 + 1, y_pos2, "Tue"); break; case 3: u8g.drawStr(x_pos2, y_pos2, "Wed"); u8g.drawStr(x_pos2 + 1, y_pos2, "Wed"); break; case 4: u8g.drawStr(x_pos2, y_pos2, "Thu"); u8g.drawStr(x_pos2 + 1, y_pos2, "Thu"); break; case 5: u8g.drawStr(x_pos2, y_pos2, "Fri"); u8g.drawStr(x_pos2 + 1, y_pos2, "Fri"); break; case 6: u8g.drawStr(x_pos2, y_pos2, "Sat"); u8g.drawStr(x_pos2 + 1, y_pos2, "Sat"); break; case 7: u8g.drawStr(x_pos2, y_pos2, "Sun"); u8g.drawStr(x_pos2 + 1, y_pos2, "Sun"); break; default: u8g.drawStr(x_pos2, y_pos2, "???"); break; } u8g.drawStr(30, y_pos2, "20"); u8g_drawStr_12864_2digits(46, y_pos2, Clock.getYear()); //u8g.drawStr(68, y_pos, ")"); /////////////////////////////////////////////////////////////// //////// draw temperture/ humidity ////////////////////// u8g.drawStr(x_pos3, y_pos3, itoa(dht11_temperature, buf, 10)); u8g.drawStr(x_pos3 + 1, y_pos3, itoa(dht11_temperature, buf, 10)); u8g.drawStr(x_pos3 + 17, y_pos3, "C"); u8g.drawStr(x_pos3 + 30, y_pos3, itoa(dht11_humidity, buf, 10)); u8g.drawStr(x_pos3 + 30 + 1, y_pos3, itoa(dht11_humidity, buf, 10)); u8g.drawStr(x_pos3 + 47, y_pos3, "%"); switch (command_tag1) { case 0: u8g.drawLine(0, 126, 60, 126); break; case 1: u8g.drawLine(40, 126, 80, 126); break; case 2: u8g.drawLine(80, 126, 120, 126); break; } } void draw_vert_LCD12864() { char buf[12]; // "-2147483648\0" //int year = Clock.getYear(); int date = Clock.getDate(); int month = Clock.getMonth(Century); int dow = Clock.getDoW(); int hour = Clock.getHour(h12, PM); // (Clock.getHour(h12, PM) + 16) % 24); //uk time int minute = Clock.getMinute(); int second = Clock.getSecond(); draw_vert_hk_uk_usa_time_LCD12864(month, date, dow, hour, minute, second); // upper part draw_vert_year_date_temp_humidity_LCD12864(); //lower part //Serial.print(",sec="); //serial print second to show the clock is clicking //Serial.print(second); //added 2024.1.16 , if flash_back_light_check_tag==1, it is a pure clock //serial print second to show the clock is clicking if (flash_back_light_check_tag==1) {flash_back_light_check(hour, minute, second); } int dual_time_tag = 2; // 0 HK time only; 1= hk and uk time; 2 hk, uk and usa time ////////////////////////////////////////////////////////////// // if (dual_time_tag == 0) if (command_tag1 == 2) { //u8g.setRot270(); char buf[12]; // "-2147483648\0" } } void flash_back_light_func(int second) { if (second % 2 == 0) { digitalWrite(backlight_pin, HIGH); // backlight, HIGH = on;LOW = off } else { digitalWrite(backlight_pin, LOW); } // backlight, HIGH = on;LOW = off } void flash_back_light_check(int hour, int minute, int second) { if (hour >= 21 || (hour*60+minute <= 360)) {// sleep time, back light off, after 9pm, or before 6:30am digitalWrite(backlight_pin, LOW); //turn off from 9pm to 6am } else { if (flash_tag_am == 0 || flash_tag_pm == 0) {digitalWrite(backlight_pin, HIGH);}; // no flash tag on, turn on backlight //hour=6 am, 6*60+ 1 minute = =6am + 1 =361 minutes; hour 7:31pm =(19*60+71)=1171 minutes if (hour*60+minute == 361 ){flash_tag_am = 1;digitalWrite(backlight_pin, HIGH);};//set flash_tag_am,backlight on if (hour*60+minute == 1171){flash_tag_pm = 1;digitalWrite(backlight_pin, HIGH);};// set flash_tag_am,backlight on buttonState = digitalRead(buttonPin); /* //read button, pressed=0, unpressed=1 Serial.println("---"); Serial.print("buttonState="); Serial.print(buttonState); Serial.print("; flash_tag_am = "); Serial.print(flash_tag_am); Serial.print("; flash_tag_pm = "); Serial.print(flash_tag_pm ); */ if (buttonState == 0) { //clear flash if buttonState=0, (key depressed) flash_tag_am = 0; flash_tag_pm = 0; digitalWrite(backlight_pin, HIGH); // turn on back light } if (hour*60+minute > 361 && flash_tag_am == 1) { flash_back_light_func(second);} if (hour*60+minute > 1171 && flash_tag_pm == 1) { flash_back_light_func(second);} } } //////////////////////////////////////////////////////////// void loop() { ///////////// read dht tempertaure, humdity sensor //////// count2++; //since the loop is executed once in 1 second, 1 sec delay loop at if (count2 >= 3) // read temperature/ humdity at a period of 3 seconds { dht11_temperature = dht.readTemperature(); dht11_humidity = dht.readHumidity(); // Serial.println("; "); //serial print second to show the clock is clicking // Serial.print("dht11_temperature="); // Serial.print(dht11_temperature); // Serial.print("; dht11_humidity ="); // Serial.print(dht11_humidity); count2 = 0; } ////------------------------------------------------------------------- u8g.firstPage(); u8g_prepare(); clear_screen_12864(); draw_vert_LCD12864(); do { draw_vert_LCD12864(); } while (u8g.nextPage()); //minute_count++; delay(100); // rebuild the picture after some delay }