├── .gitattributes ├── box ├── ClaudioBoxBack.jpg ├── ClaudioBoxBack.stl ├── ClaudioBoxBase.jpg ├── ClaudioBoxBase.stl ├── ClaudioBoxCover.jpg ├── ClaudioBoxCover.stl ├── ClaudioBoxFront.jpg └── ClaudioBoxFront.stl ├── hardware ├── COVER_REMOVED.jpg ├── PASSIVE_BUZZER.jpg ├── ESP32_DEV_BOARD.jpg ├── BH1750FVI_LUX_METER.jpg ├── CLAUDIO_MAIN_SCREEN.jpg ├── Claudio_Wiring_Diagram.png ├── DHT11_TEMP_HUMID_SENSOR.jpg ├── ILI9341_SPI_TFT_DISPLAY.jpg ├── CLAUDIO_PROTOTYPE_MOUNTED.jpg └── 5_CENTS_EURO_COIN_TOUCH_SENSOR.jpg ├── LICENSE ├── README.md └── Claudio.ino /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /box/ClaudioBoxBack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/box/ClaudioBoxBack.jpg -------------------------------------------------------------------------------- /box/ClaudioBoxBack.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/box/ClaudioBoxBack.stl -------------------------------------------------------------------------------- /box/ClaudioBoxBase.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/box/ClaudioBoxBase.jpg -------------------------------------------------------------------------------- /box/ClaudioBoxBase.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/box/ClaudioBoxBase.stl -------------------------------------------------------------------------------- /box/ClaudioBoxCover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/box/ClaudioBoxCover.jpg -------------------------------------------------------------------------------- /box/ClaudioBoxCover.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/box/ClaudioBoxCover.stl -------------------------------------------------------------------------------- /box/ClaudioBoxFront.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/box/ClaudioBoxFront.jpg -------------------------------------------------------------------------------- /box/ClaudioBoxFront.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/box/ClaudioBoxFront.stl -------------------------------------------------------------------------------- /hardware/COVER_REMOVED.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/hardware/COVER_REMOVED.jpg -------------------------------------------------------------------------------- /hardware/PASSIVE_BUZZER.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/hardware/PASSIVE_BUZZER.jpg -------------------------------------------------------------------------------- /hardware/ESP32_DEV_BOARD.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/hardware/ESP32_DEV_BOARD.jpg -------------------------------------------------------------------------------- /hardware/BH1750FVI_LUX_METER.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/hardware/BH1750FVI_LUX_METER.jpg -------------------------------------------------------------------------------- /hardware/CLAUDIO_MAIN_SCREEN.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/hardware/CLAUDIO_MAIN_SCREEN.jpg -------------------------------------------------------------------------------- /hardware/Claudio_Wiring_Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/hardware/Claudio_Wiring_Diagram.png -------------------------------------------------------------------------------- /hardware/DHT11_TEMP_HUMID_SENSOR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/hardware/DHT11_TEMP_HUMID_SENSOR.jpg -------------------------------------------------------------------------------- /hardware/ILI9341_SPI_TFT_DISPLAY.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/hardware/ILI9341_SPI_TFT_DISPLAY.jpg -------------------------------------------------------------------------------- /hardware/CLAUDIO_PROTOTYPE_MOUNTED.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/hardware/CLAUDIO_PROTOTYPE_MOUNTED.jpg -------------------------------------------------------------------------------- /hardware/5_CENTS_EURO_COIN_TOUCH_SENSOR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pangodream/Claudio/HEAD/hardware/5_CENTS_EURO_COIN_TOUCH_SENSOR.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 pangodream 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Claudio 2 | Claudio is a wake up alarm based on ESP32 by Espressif Systems and programmed with Arduino IDE 3 | 4 | ![Claudio Main Screen](https://raw.githubusercontent.com/pangodream/Claudio/master/hardware/CLAUDIO_MAIN_SCREEN.jpg) 5 | 6 | Folders: 7 | 8 | / Arduino IDE code 9 | 10 | /box Prototype print 3d files 11 | 12 | /hardware Hardware pictures 13 | 14 | 15 | 16 | More info and demos at: https://www.youtube.com/watch?v=NURag-YYxIY 17 | 18 | # WIRING DIAGRAM 19 | ![Claudio Main Screen](https://raw.githubusercontent.com/pangodream/Claudio/master/hardware/Claudio_Wiring_Diagram.png) 20 | 21 | # REMOTE CONFIGURATION 22 | By default, Claudio is listening on port 1234 for incoming connections. 23 | 24 | These connections allow a remote system to configure or perform some actions on the system. (Change parameters, Set alarm time, Deactivate alarm, ...) 25 | 26 | Once the remote client is connected to claudio, commands are sent concatenated to items and values all in upper case. 27 | 28 | For instance, if we want to know the number of beeps to sound during an alarm, we must use the command GET followed by the item ALBEEP: 29 | ```bash 30 | GETALBEEP 31 | ``` 32 | If all succeed, the system will reply 33 | ```bash 34 | 90 35 | ``` 36 | which is the value cofigured for this parameter. Otherwise, the system could reply "Invalid Command" or "Invalid Item" 37 | 38 | If we want to change the value of this parameter, for instance to 120, we should send 39 | ```bash 40 | SETALBEEP120 41 | ``` 42 | and the system should reply 43 | ```bash 44 | OK 45 | ``` 46 | 47 | 48 | ## Available commands 49 | **GET** 50 | Retrieves the value of the specified item. 51 | 52 | **SET** 53 | Stores the specified value in the specified item. 54 | 55 | **GET** 56 | Retrieves all the items value in a concatenated string ITEM1 + VALUE1 + ; + ... + ITEMn + VALUEn + ; 57 | 58 | For instance: 59 | ```bash 60 | BOOTWT5;TOUCHR120;THTCHR70;THTCHM65;THTCHL65;LTCHTH12;... 61 | ``` 62 | 63 | **RST** 64 | Reboot the system. 65 | 66 | **TSS** 67 | Stops and deactivates alarm, even while alarm is being executed. 68 | 69 | ## Available items 70 | **BOOTWT** 71 | 72 | Number of seconds (aprox.) to wait after boot screen to start the normal operation 73 | 74 | EEPROM stored: Yes 75 | 76 | Default value: 20 77 | 78 | **TOUCHR** 79 | 80 | Number of readings to calculate sensor capacitance average value 81 | 82 | EEPROM stored: Yes 83 | 84 | Default value: 120 85 | 86 | **THTCHR** 87 | 88 | Average capacitance threshold value for Right sensor. Under this value the sensor is considered activated 89 | 90 | EEPROM stored: Yes 91 | 92 | Default value: 70 93 | 94 | **THTCHM** 95 | 96 | Average capacitance threshold value for Middle sensor. Under this value the sensor is considered activated 97 | 98 | EEPROM stored: Yes 99 | 100 | Default value: 65 101 | 102 | **THTCHL** 103 | 104 | Average capacitance threshold value for Left sensor. Under this value the sensor is considered activated 105 | 106 | EEPROM stored: Yes 107 | 108 | Default value: 65 109 | 110 | **LTCHTH** 111 | 112 | Long touch threshold. Number of tenths of a second to consider a sensor has been long touched. 113 | 114 | EEPROM stored: Yes 115 | 116 | Default value: 12 (1.2 secs) 117 | 118 | **SNZMIN** 119 | 120 | Number of minutes to postpone alarm time (Snooze) 121 | 122 | EEPROM stored: Yes 123 | 124 | Default value: 9 125 | 126 | **ALBEEP** 127 | 128 | Number of beeps to sound during alarm 129 | 130 | EEPROM stored: Yes 131 | 132 | Default value: 90 133 | 134 | **MAXLUX** 135 | 136 | Maximum lux value to take into account. Above this any value is just considered maximum value. 137 | 138 | When ambient light reaches this value, the display backlight is set to 100% power. 139 | 140 | EEPROM stored: Yes 141 | 142 | Default value: 20 143 | 144 | **MINLUX** 145 | 146 | Minimum lux value to take into account. Below this any value is just considered minimum value. 147 | 148 | When ambient light goes down to this value, the display backlight is set to Minimun Brightness value. (see next item)) 149 | 150 | EEPROM stored: Yes 151 | 152 | Default value: 0 153 | 154 | **MINBRG** 155 | 156 | When ambient light reaches its minimum value, display backlight power is set to this value. 157 | 158 | This is commonly used to set the backlight level we want while sleeping. 159 | 160 | EEPROM stored: Yes 161 | 162 | Default value: 10 163 | 164 | **ALARHO** 165 | 166 | Defines the hour part of alarm time 167 | 168 | EEPROM stored: No 169 | 170 | Default value: No default value 171 | 172 | **ALARMI** 173 | 174 | Defines the minutes part of alarm time 175 | 176 | EEPROM stored: No 177 | 178 | Default value: No default value 179 | 180 | **DOALAR** 181 | 182 | Switch ON/OFF alarm by sending 1/0 value for this item 183 | 184 | EEPROM stored: No 185 | 186 | Default value: No default value 187 | 188 | **ONALAR** 189 | 190 | Indicates whether the alarm is beeping or not. As well, it stops alarm beeping if its value is set to 0 191 | 192 | EEPROM stored: No 193 | 194 | Default value: No default value 195 | 196 | 197 | To test remote configuration capabilities you can use Claudio Remote, an Android app to change configuration values easily: 198 | https://github.com/pangodream/ClaudioRemote -------------------------------------------------------------------------------- /Claudio.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * GLOBAL PIN CONFIGURATION 3 | */ 4 | 5 | const int TFT_CS = 15; 6 | const int TFT_DC = 4; 7 | const int TFT_MOSI = 23; 8 | const int TFT_SLK = 18; 9 | const int TFT_RST = 2; 10 | const int TFT_LED = 19; 11 | const int BUZZER = 5; 12 | const int LUX_SDA = 21; 13 | const int LUX_SCL = 22; 14 | const int DHT_OUT = 27; 15 | /** 16 | * EEPROM libraries and resources 17 | */ 18 | #include "EEPROM.h" 19 | #define EEPROM_SIZE 64 20 | 21 | /** 22 | * ILI9341 TFT libraries and resources 23 | */ 24 | #include "SPI.h" 25 | #include "Adafruit_GFX.h" 26 | #include "Adafruit_ILI9341.h" 27 | // cs dc mosi slk rst 28 | Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SLK, TFT_RST); 29 | 30 | #define ILI9341_LCYAN 0x0418 31 | #define ILI9341_LORANGE 0xFC08 32 | #define ILI9341_LGREEN 0x87F0 33 | #define ILI9341_LGRAY 0x8410 34 | 35 | /** 36 | * BH1750 Lux meter libraries and resources 37 | */ 38 | #include 39 | // Create the Lightsensor instance 40 | BH1750FVI LightSensor(BH1750FVI::k_DevModeContHighRes); 41 | 42 | /** 43 | * DHT-11 Temp and humidity sensor libraries and resources 44 | */ 45 | #include "DHT.h" 46 | #define DHTTYPE DHT11 47 | DHT dht(DHT_OUT, DHTTYPE); 48 | 49 | /** 50 | * WIFI Libraries and resources 51 | */ 52 | #include 53 | //Absolute path to file containing WiFi credentials 54 | //const char* ssid = "MyApSSID"; 55 | //const char* password = "MyApPassphrase"; 56 | #include 57 | const int connTimeout = 10; //Seconds 58 | 59 | WiFiServer wifiServer(1234); 60 | 61 | 62 | /** 63 | * TIME libraries and resources 64 | */ 65 | #include "time.h" 66 | const char* ntpServer = "pool.ntp.org"; 67 | const long gmtOffset_sec = 3600; 68 | const int daylightOffset_sec = 3600; 69 | 70 | /** 71 | * PWM Constants 72 | */ 73 | const int freq = 5000; 74 | const int tftledChannel = 0; 75 | const int resolution = 8; 76 | /** 77 | * TFT Display Constants 78 | */ 79 | const int xTime = 14; 80 | const int yTime = 14; 81 | const int tftBG = ILI9341_BLACK; 82 | const int tftTimeFG = ILI9341_RED; 83 | 84 | 85 | 86 | /** 87 | * GLOBALS 88 | */ 89 | String prevTime = ""; 90 | String currTime = ""; 91 | String prevDate = ""; 92 | String currDate = ""; 93 | uint16_t prevLux = 0; 94 | uint16_t currLux = 0; 95 | float prevTemp = 0; 96 | float currTemp = 0; 97 | float prevHumi = 0; 98 | float currHumi = 0; 99 | bool onWifi = false; 100 | String weekDays[] = {"", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab", "Dom"}; 101 | String months[] = {"", " Ene ", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"}; 102 | int pinTouchR = 14; 103 | int pinTouchM = 13; 104 | int pinTouchL = 12; 105 | int statusTouchR = 0; 106 | int statusTouchM = 0; 107 | int statusTouchL = 0; 108 | ulong lastTouchR; 109 | ulong lastTouchM; 110 | ulong lastTouchL; 111 | bool doAlarm; 112 | String alarmTime; 113 | bool onAlarm; 114 | bool waitingToTouch = false; 115 | bool onConfig = false; 116 | 117 | //Configurable values 118 | int bootWait; //Seconds 119 | int touchReadings; 120 | int thresholdTouchR; 121 | int thresholdTouchM; 122 | int thresholdTouchL; 123 | int longTouchThreshold; // Tenths of second 124 | int snoozeMinutes; 125 | int alarmBeeps; 126 | byte maxLux; 127 | byte minLux; 128 | byte minBrightness; 129 | 130 | 131 | 132 | void setup() { 133 | /** 134 | * Serial port 135 | */ 136 | Serial.begin(115200); 137 | 138 | /** 139 | * EEPROM 140 | */ 141 | EEPROM.begin(EEPROM_SIZE); 142 | /** 143 | * Loads EEPROM configuration 144 | */ 145 | loadConfiguration(); 146 | 147 | /** 148 | * TFT DISPLAY 149 | */ 150 | //Background light PWM 151 | ledcSetup(tftledChannel, freq, resolution); 152 | ledcAttachPin(TFT_LED, tftledChannel); 153 | //Start with high intensity 154 | setBGLuminosity(255); 155 | tft.begin(); 156 | tft.setRotation(3); 157 | yield(); 158 | 159 | //Boot screen 160 | tft.fillScreen(ILI9341_BLACK); 161 | yield(); 162 | tft.setTextSize(4); 163 | tft.setTextColor(ILI9341_LORANGE); 164 | tft.println("Claudio!"); 165 | tft.setTextSize(1); 166 | tft.setTextColor(ILI9341_WHITE); 167 | tft.println(""); 168 | tft.println("Booting..."); 169 | tft.println("Setting up devices..."); 170 | /** 171 | * BUZZER 172 | */ 173 | pinMode(BUZZER, OUTPUT); 174 | /** 175 | * Light sensor 176 | */ 177 | LightSensor.begin(); 178 | /** 179 | * Temperature and humidity sensor 180 | */ 181 | dht.begin(); 182 | tft.print("Connecting to WiFi AP "); 183 | tft.println(ssid); 184 | /** 185 | * Wifi connect 186 | */ 187 | wifiConnect(); 188 | if(onWifi == true){ 189 | tft.print(" Connection succeed, obtained IP "); 190 | tft.println(WiFi.localIP()); 191 | }else{ 192 | tft.println(" Connection failed. Unexpected operation results."); 193 | } 194 | tft.println("Obtaining NTP time from remote server..."); 195 | /** 196 | * NTP Time 197 | */ 198 | getNtpTime(); 199 | delay(100); //We need a delay to allow info propagation 200 | 201 | /** 202 | * Wifi Server for configuration 203 | */ 204 | tft.println("Starting remote configuration server..."); 205 | wifiServer.begin(); 206 | 207 | tft.println("End of booting process."); 208 | 209 | //Wait twenty seconds or until the user touches a button 210 | waitTouch(bootWait); 211 | 212 | //Prepare screen for normal operation 213 | setBGLuminosity(0); 214 | tft.fillScreen(ILI9341_BLACK); 215 | yield(); 216 | 217 | //Paint elements 218 | displayTime(); 219 | displayDate(); 220 | displayAlarm(); 221 | displayTemp(); 222 | displayHumi(); 223 | displayLux(); 224 | displayButton(0, false, false); 225 | displayButton(1, false, false); 226 | displayButton(2, false, false); 227 | setBGLuminosity(255); 228 | /** 229 | * TESTING 230 | */ 231 | 232 | 233 | } 234 | 235 | void loop() { 236 | getCurrentLux(); 237 | getCurrentTemp(); 238 | getCurrentHumi(); 239 | refreshTime(); 240 | readTouch(); 241 | configMode(); 242 | delay(100); 243 | } 244 | 245 | /** 246 | * Checks for next alarm in queue 247 | */ 248 | void checkAlarm(){ 249 | //TODO: Check in queue what is the nex alarm to be activated... 250 | alarmTime = hourMinuteToTime(getAlarmHour(), getAlarmMinute()); 251 | doAlarm = true; 252 | displayAlarm(); 253 | } 254 | /** 255 | * Connects to WIFI 256 | */ 257 | 258 | bool wifiConnect(){ 259 | onWifi = false; 260 | int retries = 0; 261 | Serial.printf("Connecting to %s ", ssid); 262 | WiFi.begin(ssid, password); 263 | while (WiFi.status() != WL_CONNECTED) { 264 | delay(500); 265 | Serial.print("."); 266 | retries++; 267 | if(retries == (connTimeout * 2)){ 268 | Serial.println(" TIMEOUT"); 269 | break; 270 | } 271 | } 272 | if(WiFi.status() == WL_CONNECTED){ 273 | onWifi = true; 274 | Serial.println(" CONNECTED"); 275 | } 276 | return onWifi; 277 | } 278 | /** 279 | * Obtains time from NTP server 280 | */ 281 | bool getNtpTime(){ 282 | bool result = false; 283 | if(onWifi == true){ 284 | configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); 285 | result = true; 286 | }else{ 287 | Serial.println("getNtpTime: Not connected to wifi!"); 288 | } 289 | return result; 290 | } 291 | 292 | /** 293 | * Returns day of week (1-Mon, 2-Tue, ...., 7-Sun) 294 | */ 295 | int getDayOfWeek(){ //1-Mon, 2-Tue, ...., 7-Sun 296 | int wDay; 297 | time_t now; 298 | struct tm * timeinfo; 299 | time(&now); 300 | timeinfo = localtime(&now); 301 | wDay = timeinfo->tm_wday; 302 | if(wDay == 0){ 303 | wDay = 7; 304 | } 305 | return wDay; 306 | } 307 | /** 308 | * Adds a number of snooze minutes to s String time 309 | */ 310 | String addSnooze(String sTime, int snooze){ 311 | int hour; 312 | int minute; 313 | int tMinutes; 314 | int tHours; 315 | String newTime; 316 | char cTime[5]=" "; 317 | hour = sTime.substring(0,2).toInt(); 318 | minute = sTime.substring(3,5).toInt(); 319 | tMinutes = (minute+snooze) % 60; 320 | tHours = (hour + ((minute+snooze) / 60)) % 24; 321 | 322 | sprintf(cTime, "%02d:%02d", tHours, tMinutes); 323 | newTime = (char*)cTime; 324 | return newTime; 325 | } 326 | /** 327 | * Returns a string formatted HH:MM based on hours and minutes 328 | */ 329 | String hourMinuteToTime(int hour, int minute){ 330 | String sTime; 331 | char cTime[5]=" "; 332 | sprintf(cTime, "%02d:%02d", hour, minute); 333 | sTime = (char*)cTime; 334 | return sTime; 335 | } 336 | /* 337 | * Returns current time in HH:MM format 338 | */ 339 | String refreshTime(){ 340 | //Time 341 | time_t now; 342 | struct tm * timeinfo; 343 | time(&now); 344 | timeinfo = localtime(&now); 345 | prevTime = currTime; 346 | currTime = hourMinuteToTime(timeinfo->tm_hour, timeinfo->tm_min); 347 | if(prevTime != currTime){ 348 | timeChanged(prevTime, currTime); 349 | //If time has changed, lets check if date has changed too 350 | //Date 351 | int wDay; 352 | wDay = timeinfo->tm_wday; 353 | if(wDay == 0){ 354 | wDay = 7; 355 | } 356 | String calDate = ""; 357 | char cDate[30]=" "; 358 | //Serial.println(weekDays[wDay]); 359 | //sprintf(cDate, "%s, %i de %s de %i", weekDays[wDay], timeinfo->tm_mday, months[(timeinfo->tm_mon + 1)],(timeinfo->tm_year + 1900)); 360 | calDate = calDate + weekDays[wDay]; 361 | calDate = calDate + ", "; 362 | calDate = calDate + timeinfo->tm_mday; 363 | calDate = calDate + " "; 364 | calDate = calDate + months[(timeinfo->tm_mon + 1)]; 365 | calDate = calDate + " "; 366 | calDate = calDate + (timeinfo->tm_year + 1900); 367 | if(calDate.length() == 21){ 368 | calDate = " " + calDate; 369 | } 370 | prevDate = currDate; 371 | currDate = calDate; 372 | if(prevDate != currDate){ 373 | dateChanged(prevDate, currDate); 374 | } 375 | } 376 | } 377 | 378 | /** 379 | * Displays time string erasing the previous one 380 | */ 381 | void displayTime(){ 382 | tft.setTextSize(10); 383 | tft.setCursor(xTime, yTime); 384 | tft.setTextColor(tftBG); 385 | yield(); 386 | tft.println(prevTime); 387 | yield(); 388 | tft.setCursor(xTime, yTime); 389 | tft.setTextColor(tftTimeFG); 390 | yield(); 391 | tft.println(currTime); 392 | yield(); 393 | } 394 | /** 395 | * Displays date string 396 | */ 397 | void displayDate(){ 398 | tft.fillRect(14, 94, 192, 30, ILI9341_BLACK); 399 | tft.setTextSize(3); 400 | tft.setCursor(26, 94); 401 | tft.setTextColor(ILI9341_LGREEN); 402 | yield(); 403 | tft.println(currDate); 404 | } 405 | /** 406 | * Displays temperature 407 | */ 408 | void displayTemp(){ 409 | int bgColor = 0; 410 | if(currTemp == prevTemp){ 411 | bgColor = ILI9341_LGREEN; 412 | }else if(currTemp < prevTemp){ 413 | bgColor = ILI9341_LCYAN; 414 | }else{ 415 | bgColor = ILI9341_LORANGE; 416 | } 417 | 418 | tft.setTextColor(ILI9341_BLACK); 419 | yield(); 420 | tft.fillRect(14, 170, 92, 60, bgColor); 421 | tft.drawRect(14, 170, 92, 60, ILI9341_WHITE); 422 | yield(); 423 | tft.setTextSize(2); 424 | tft.setCursor(34, 174); 425 | tft.print("TEMP"); 426 | tft.setTextSize(3); 427 | tft.setCursor(16, 200); 428 | tft.print(currTemp); 429 | } 430 | /** 431 | * Displays relative humidity 432 | */ 433 | void displayHumi(){ 434 | int bgColor = 0; 435 | if(currHumi == prevHumi){ 436 | bgColor = ILI9341_LGREEN; 437 | }else if(currHumi < prevHumi){ 438 | bgColor = ILI9341_LCYAN; 439 | }else{ 440 | bgColor = ILI9341_LORANGE; 441 | } 442 | tft.setTextColor(ILI9341_BLACK); 443 | yield(); 444 | tft.fillRect(113, 170, 92, 60, bgColor); 445 | tft.drawRect(113, 170, 92, 60, ILI9341_WHITE); 446 | yield(); 447 | tft.setTextSize(2); 448 | tft.setCursor(135, 174); 449 | tft.print("H.R."); 450 | tft.setTextSize(3); 451 | tft.setCursor(115, 200); 452 | tft.print(currHumi); 453 | } 454 | /** 455 | * Displays lux 456 | */ 457 | void displayLux(){ 458 | int bgColor = 0; 459 | if(currLux == prevLux){ 460 | bgColor = ILI9341_LGREEN; 461 | }else if(currLux < prevLux){ 462 | bgColor = ILI9341_LCYAN; 463 | }else{ 464 | bgColor = ILI9341_LORANGE; 465 | } 466 | tft.setTextColor(ILI9341_BLACK); 467 | yield(); 468 | tft.fillRect(212, 170, 92, 60, bgColor); 469 | tft.drawRect(212, 170, 92, 60, ILI9341_WHITE); 470 | yield(); 471 | tft.setTextSize(2); 472 | tft.setCursor(242, 174); 473 | tft.print("LUX"); 474 | tft.setTextSize(3); 475 | tft.setCursor(214, 200); 476 | char cLux[5]=" "; 477 | sprintf(cLux, "%05d", currLux); 478 | //currTime = (char*)cTime; 479 | tft.print(cLux); 480 | } 481 | /** 482 | * Displays Alarm Time 483 | */ 484 | void displayAlarm(){ 485 | if(doAlarm == true){ 486 | tft.setTextColor(ILI9341_YELLOW); 487 | }else{ 488 | tft.setTextColor(ILI9341_LGRAY); 489 | } 490 | yield(); 491 | tft.fillRect(212, 129, 92, 36, ILI9341_BLACK); 492 | yield(); 493 | tft.setTextSize(3); 494 | tft.setCursor(214, 133); 495 | tft.print(alarmTime); 496 | } 497 | /** 498 | * Sets button status 499 | * 0 - Left 500 | * 1 - Middle 501 | * 2 - Right 502 | */ 503 | void displayButton(int button, bool activated, bool longTouch){ 504 | int bgColor; 505 | int x; 506 | if(activated == true){ 507 | if(longTouch == true){ 508 | bgColor = ILI9341_RED; 509 | }else{ 510 | bgColor = ILI9341_YELLOW; 511 | } 512 | }else{ 513 | bgColor = ILI9341_LGRAY; 514 | } 515 | yield(); 516 | x = 128 + (button * 30); 517 | tft.fillCircle(x, 144, 11,bgColor); 518 | tft.drawCircle(x, 144, 11,ILI9341_WHITE); 519 | yield(); 520 | } 521 | 522 | 523 | /** 524 | * Sets TFT background luminosity (0-255) 525 | */ 526 | void setBGLuminosity(int level){ 527 | ledcWrite(tftledChannel, level); 528 | } 529 | /** 530 | * Plays beep on buzzer a number of times 531 | */ 532 | void playBuzzer(int times){ 533 | onAlarm = true; 534 | for(int t=0; t< times; t++){ 535 | if(onAlarm == false){ 536 | break; 537 | } 538 | for(int i=0; i< 200; i++) 539 | { 540 | digitalWrite(BUZZER, HIGH); 541 | delay(1); 542 | digitalWrite(BUZZER, LOW); 543 | delay(1); 544 | } 545 | //Read touch sensor to check if alarm is stopped manually 546 | readTouch(); 547 | //Check if remote management is requested (to stop alarm remotely) 548 | configMode(); 549 | delay(10); 550 | } 551 | } 552 | /** 553 | * Waits for the user to touch a button 554 | * Timeout in seconds (aprox.) 555 | */ 556 | void waitTouch(int timeout){ 557 | waitingToTouch = true; 558 | for(int t=0; t< (timeout * 3.6); t++){ 559 | readTouch(); 560 | if(waitingToTouch == false){ 561 | break; 562 | } 563 | delay(100); 564 | } 565 | } 566 | /** 567 | * Returns ambient light luxes 568 | */ 569 | uint16_t getCurrentLux(){ 570 | prevLux = currLux; 571 | currLux = LightSensor.GetLightIntensity(); 572 | if(prevLux != currLux){ 573 | luxChanged(prevLux , currLux); 574 | } 575 | return currLux; 576 | } 577 | /** 578 | * Calculates and sets screen backlight brightness 579 | */ 580 | void calculateAndSetBGLuminosity(uint16_t currLux){ 581 | int finalLux = currLux; 582 | if(finalLux > maxLux){ 583 | finalLux = maxLux; 584 | } 585 | if(finalLux < minLux){ 586 | finalLux = minLux; 587 | } 588 | double levelsWidth = maxLux - minLux; 589 | double level = finalLux - minLux; 590 | double ratio = level / levelsWidth; 591 | double brightnessWidth = 255 - minBrightness; 592 | int brightnessValue = (brightnessWidth * ratio) + minBrightness; 593 | setBGLuminosity(brightnessValue); 594 | } 595 | /** 596 | * Returns temperature 597 | */ 598 | float getCurrentTemp(){ 599 | prevTemp = currTemp; 600 | currTemp = dht.readTemperature();; 601 | if(prevTemp != currTemp){ 602 | tempChanged(prevTemp , currTemp); 603 | } 604 | return currTemp; 605 | } 606 | /** 607 | * Returns humidity 608 | */ 609 | float getCurrentHumi(){ 610 | prevHumi = currHumi; 611 | currHumi = dht.readHumidity(); 612 | if(prevHumi != currHumi){ 613 | humiChanged(prevHumi , currHumi); 614 | } 615 | return currHumi; 616 | } 617 | /** 618 | * Reads touch buttons status and launches events 619 | */ 620 | void readTouch(){ 621 | int avgTouchR = 0; int avgTouchM = 0; int avgTouchL = 0; 622 | for(int i=0; i< touchReadings; i++){ 623 | avgTouchR += touchRead(pinTouchR); 624 | avgTouchM += touchRead(pinTouchM); 625 | avgTouchL += touchRead(pinTouchL); 626 | } 627 | yield(); 628 | avgTouchR = avgTouchR / touchReadings; 629 | avgTouchM = avgTouchM / touchReadings; 630 | avgTouchL = avgTouchL / touchReadings; 631 | 632 | //LEFT BUTTON 633 | if(avgTouchL < thresholdTouchL){ 634 | if(statusTouchL == 0){ 635 | lastTouchL = millis(); 636 | touchL(); 637 | statusTouchL = 1; 638 | }else if(statusTouchL == 1){ 639 | if((millis() - lastTouchL) > (longTouchThreshold * 100)){ 640 | statusTouchL = 2; 641 | touchLongL(); 642 | } 643 | } 644 | }else{ 645 | if(statusTouchL != 0){ 646 | releaseL(); 647 | } 648 | statusTouchL = 0; 649 | } 650 | //MIDDLE BUTTON 651 | if(avgTouchM < thresholdTouchM){ 652 | if(statusTouchM == 0){ 653 | lastTouchM = millis(); 654 | touchM(); 655 | statusTouchM = 1; 656 | }else if(statusTouchM == 1){ 657 | if((millis() - lastTouchM) > (longTouchThreshold * 100)){ 658 | statusTouchM = 2; 659 | touchLongM(); 660 | } 661 | } 662 | }else{ 663 | if(statusTouchM != 0){ 664 | releaseM(); 665 | } 666 | statusTouchM = 0; 667 | } 668 | //RIGHT BUTTON 669 | if(avgTouchR < thresholdTouchR){ 670 | if(statusTouchR == 0){ 671 | lastTouchR = millis(); 672 | touchR(); 673 | statusTouchR = 1; 674 | }else if(statusTouchR == 1){ 675 | if((millis() - lastTouchR) > (longTouchThreshold * 100)){ 676 | statusTouchR = 2; 677 | touchLongR(); 678 | } 679 | } 680 | }else{ 681 | if(statusTouchR != 0){ 682 | releaseR(); 683 | } 684 | statusTouchR = 0; 685 | } 686 | } 687 | 688 | /** 689 | * EVENTS 690 | */ 691 | /** 692 | * Event for change of time HH:MM 693 | */ 694 | void timeChanged(String prevTime, String currTime){ 695 | //Serial.println("timeChanged event fired!"); 696 | displayTime(); 697 | if(currTime == alarmTime){ 698 | if(doAlarm == true){ 699 | if(onAlarm == false){ 700 | playBuzzer(alarmBeeps); 701 | doAlarm = false; 702 | } 703 | } 704 | } 705 | } 706 | /** 707 | * Event for change of date weekDay, day de Month de Year 708 | */ 709 | void dateChanged(String prevDate, String currDate){ 710 | //Serial.print("dateChanged event fired! "); 711 | //Serial.println(currDate); 712 | displayDate(); 713 | //New day, lets check for the next alarm 714 | checkAlarm(); 715 | } 716 | /** 717 | * Event for change of ambient light 718 | */ 719 | void luxChanged(uint16_t prevLux, uint16_t currLux){ 720 | //Serial.print("luxChanged event fired! "); 721 | //Serial.println(currLux); 722 | displayLux(); 723 | calculateAndSetBGLuminosity(currLux); 724 | } 725 | 726 | /** 727 | * Event for change of temperature 728 | */ 729 | void tempChanged(float prevTemp, float currTemp){ 730 | //Serial.print("tempChanged event fired! "); 731 | //Serial.println(currTemp); 732 | displayTemp(); 733 | } 734 | /** 735 | * Event for change of humidity 736 | */ 737 | void humiChanged(float prevHumi, float currHumi){ 738 | //Serial.println("humiChanged event fired!"); 739 | displayHumi(); 740 | 741 | } 742 | /** 743 | * Touch buttons events 744 | */ 745 | void touchR(){ 746 | Serial.println("Touch Right"); 747 | displayButton(2, true, false); 748 | touchAny(); 749 | } 750 | void touchLongR(){ 751 | Serial.println("Touch Long Right"); 752 | displayButton(2, true, true); 753 | touchLongAny(); 754 | } 755 | void releaseR(){ 756 | Serial.println("Release Right"); 757 | displayButton(2, false, false); 758 | releaseAny(); 759 | } 760 | 761 | void touchM(){ 762 | Serial.println("Touch Middle"); 763 | displayButton(1, true, false); 764 | touchAny(); 765 | } 766 | void touchLongM(){ 767 | Serial.println("Touch Long Middle"); 768 | displayButton(1, true, true); 769 | touchLongAny(); 770 | } 771 | void releaseM(){ 772 | Serial.println("Release Middle"); 773 | displayButton(1, false, false); 774 | releaseAny(); 775 | } 776 | 777 | void touchL(){ 778 | Serial.println("Touch Left"); 779 | displayButton(0, true, false); 780 | touchAny(); 781 | } 782 | void touchLongL(){ 783 | Serial.println("Touch Long Left"); 784 | displayButton(0, true, true); 785 | touchLongAny(); 786 | } 787 | void releaseL(){ 788 | Serial.println("Release Left"); 789 | displayButton(0, false, false); 790 | releaseAny(); 791 | } 792 | 793 | void touchAny(){ 794 | waitingToTouch = false; 795 | if(onAlarm == true){ 796 | onAlarm = false; 797 | doAlarm = false; 798 | displayAlarm(); 799 | } 800 | } 801 | void touchLongAny(){ 802 | Serial.println("Touch Long Any"); 803 | //Extra alarma functionalities (Alarm Off, Alarm On and Snooze) 804 | //Check if event occurs during first alarm minute 805 | if(alarmTime == currTime){ 806 | //Add Snooze time to alarmTime 807 | alarmTime = addSnooze(alarmTime, snoozeMinutes); 808 | doAlarm = true; 809 | displayAlarm(); 810 | }else{ 811 | //Switch On/Off alarm 812 | doAlarm = !doAlarm; 813 | displayAlarm(); 814 | } 815 | 816 | //Only for testing!!! 817 | //Set alarm time equal to current time if left and right buttons are longTouched simultaneously 818 | if(statusTouchL == 2 && statusTouchR == 2){ 819 | alarmTime = currTime; 820 | displayAlarm(); 821 | timeChanged(currTime, currTime); 822 | } 823 | } 824 | void releaseAny(){ 825 | 826 | } 827 | void configOn(){ 828 | Serial.println("Entered config mode"); 829 | } 830 | void configOff(){ 831 | Serial.println("Exited config mode"); 832 | } 833 | 834 | 835 | /** 836 | * Remote configuration 837 | */ 838 | void configMode(){ 839 | String instruction = ""; 840 | String reply = ""; 841 | WiFiClient client = wifiServer.available(); 842 | if (client) { 843 | onConfig = true; 844 | configOn(); 845 | while (client.connected()) { 846 | while (client.available()>0) { 847 | char c = client.read(); 848 | if(c == 10){ 849 | reply = configExecute(instruction); 850 | instruction = ""; 851 | client.println(reply); 852 | }else{ 853 | instruction = instruction + c; 854 | } 855 | 856 | } 857 | delay(10); 858 | } 859 | client.stop(); 860 | onConfig = false; 861 | configOff(); 862 | } 863 | } 864 | String configExecute(String instruction){ 865 | String command; 866 | String item; 867 | String value; 868 | int setValue; 869 | command = instruction.substring(0, 3); 870 | item = instruction.substring(3, 9); 871 | Serial.print("Remote config: ");Serial.println(instruction); 872 | if(command == "GET"){ 873 | value = getConfigValue(item); 874 | }else if(command == "SET"){ 875 | setValue = instruction.substring(9, 12).toInt(); 876 | value = setConfigValue(item, setValue); 877 | }else if(command == "ALL"){ 878 | value = getAllItems(); 879 | }else if(command == "RST"){ 880 | ESP.restart(); 881 | }else if(command == "TSS"){ 882 | onAlarm = false; 883 | doAlarm = false; 884 | displayAlarm(); 885 | }else{ 886 | value = "Invalid command"; 887 | } 888 | return value; 889 | } 890 | String getConfigValue(String item){ 891 | String value; 892 | if(item == "BOOTWT"){ 893 | value = (String) getBootWait(); 894 | }else if(item == "TOUCHR"){ 895 | value = (String) getTouchReadings(); 896 | }else if(item == "THTCHR"){ 897 | value = (String) getThresholdTouchR(); 898 | }else if(item == "THTCHM"){ 899 | value = (String) getThresholdTouchM(); 900 | }else if(item == "THTCHL"){ 901 | value = (String) getThresholdTouchL(); 902 | }else if(item == "LTCHTH"){ 903 | value = (String) getLongTouchThreshold(); 904 | }else if(item == "SNZMIN"){ 905 | value = (String) getSnoozeMinutes(); 906 | }else if(item == "ALBEEP"){ 907 | value = (String) getAlarmBeeps(); 908 | }else if(item == "MAXLUX"){ 909 | value = (String) getMaxLux(); 910 | }else if(item == "MINLUX"){ 911 | value = (String) getMinLux(); 912 | }else if(item == "MINBRG"){ 913 | value = (String) getMinBrightness(); 914 | }else if(item == "ALARHO"){ 915 | value = (String) getAlarmHour(); 916 | }else if(item == "ALARMI"){ 917 | value = (String) getAlarmMinute(); 918 | }else if(item == "DOALAR"){ 919 | value = (String) getDoAlarm(); 920 | }else if(item == "ONALAR"){ 921 | value = (String) getOnAlarm(); 922 | }else{ 923 | value = "Invalid item"; 924 | } 925 | return value; 926 | } 927 | String setConfigValue(String item, int setValue){ 928 | String value = "OK"; 929 | if(item == "BOOTWT"){ 930 | setBootWait(setValue); 931 | }else if(item == "TOUCHR"){ 932 | setTouchReadings(setValue); 933 | }else if(item == "THTCHR"){ 934 | setThresholdTouchR(setValue); 935 | }else if(item == "THTCHM"){ 936 | setThresholdTouchM(setValue); 937 | }else if(item == "THTCHL"){ 938 | setThresholdTouchL(setValue); 939 | }else if(item == "LTCHTH"){ 940 | setLongTouchThreshold(setValue); 941 | }else if(item == "SNZMIN"){ 942 | setSnoozeMinutes(setValue); 943 | }else if(item == "ALBEEP"){ 944 | setAlarmBeeps(setValue); 945 | }else if(item == "MAXLUX"){ 946 | setMaxLux(setValue); 947 | }else if(item == "MINLUX"){ 948 | setMinLux(setValue); 949 | }else if(item == "MINBRG"){ 950 | setMinBrightness(setValue); 951 | }else if(item == "ALARHO"){ 952 | setAlarmHour(setValue); 953 | }else if(item == "ALARMI"){ 954 | setAlarmMinute(setValue); 955 | }else if(item == "DOALAR"){ 956 | setDoAlarm(setValue); 957 | }else if(item == "ONALAR"){ 958 | setOnAlarm(setValue); 959 | }else{ 960 | value = "Invalid item"; 961 | } 962 | return value; 963 | } 964 | String getAllItems(){ 965 | String result = ""; 966 | result = result + "BOOTWT"; 967 | result = result + (String) getBootWait(); 968 | result = result + ";"; 969 | result = result + "TOUCHR"; 970 | result = result + (String) getTouchReadings(); 971 | result = result + ";"; 972 | result = result + "THTCHR"; 973 | result = result + (String) getThresholdTouchR(); 974 | result = result + ";"; 975 | result = result + "THTCHM"; 976 | result = result + (String) getThresholdTouchM(); 977 | result = result + ";"; 978 | result = result + "THTCHL"; 979 | result = result + (String) getThresholdTouchL(); 980 | result = result + ";"; 981 | result = result + "LTCHTH"; 982 | result = result + (String) getLongTouchThreshold(); 983 | result = result + ";"; 984 | result = result + "SNZMIN"; 985 | result = result + (String) getSnoozeMinutes(); 986 | result = result + ";"; 987 | result = result + "ALBEEP"; 988 | result = result + (String) getAlarmBeeps(); 989 | result = result + ";"; 990 | result = result + "MAXLUX"; 991 | result = result + (String) getMaxLux(); 992 | result = result + ";"; 993 | result = result + "MINLUX"; 994 | result = result + (String) getMinLux(); 995 | result = result + ";"; 996 | result = result + "MINBRG"; 997 | result = result + (String) getMinBrightness(); 998 | result = result + ";"; 999 | result = result + "ALARHO"; 1000 | result = result + (String) getAlarmHour(); 1001 | result = result + ";"; 1002 | result = result + "ALARMI"; 1003 | result = result + (String) getAlarmMinute(); 1004 | result = result + ";"; 1005 | result = result + "DOALAR"; 1006 | result = result + (String) getDoAlarm(); 1007 | result = result + ";"; 1008 | result = result + "ONALAR"; 1009 | result = result + (String) getOnAlarm(); 1010 | result = result + ";"; 1011 | result = result + "CURTIM"; 1012 | result = result + currTime; 1013 | result = result + ";"; 1014 | result = result + "CURDAT"; 1015 | result = result + currDate; 1016 | result = result + ";"; 1017 | result = result + "ALARTM"; 1018 | result = result + alarmTime; 1019 | result = result + ";"; 1020 | result = result + "CURTMP"; 1021 | result = result + (String) currTemp; 1022 | result = result + ";"; 1023 | result = result + "CURHUM"; 1024 | result = result + (String) currHumi; 1025 | result = result + ";"; 1026 | result = result + "CURLUX"; 1027 | result = result + (String) currLux; 1028 | result = result + ";"; 1029 | return result; 1030 | } 1031 | 1032 | /** 1033 | * Load Configuration from EEPROM 1034 | */ 1035 | void loadConfiguration(){ 1036 | bootWait = getBootWait(); 1037 | touchReadings = getTouchReadings(); 1038 | thresholdTouchR = getThresholdTouchR(); 1039 | thresholdTouchM = getThresholdTouchM(); 1040 | thresholdTouchL = getThresholdTouchL(); 1041 | longTouchThreshold = getLongTouchThreshold(); 1042 | snoozeMinutes = getSnoozeMinutes(); 1043 | alarmBeeps = getAlarmBeeps(); 1044 | maxLux = getMaxLux(); 1045 | minLux = getMinLux(); 1046 | minBrightness = getMinBrightness(); 1047 | } 1048 | /** 1049 | * Boot Wait 1050 | * Address 0 1051 | */ 1052 | byte getBootWait(){ 1053 | byte value = byte(EEPROM.read(0)); 1054 | if(value == 255){ 1055 | value = 20; 1056 | } 1057 | return value; 1058 | } 1059 | void setBootWait(byte value){ 1060 | EEPROM.write(0, value); 1061 | EEPROM.commit(); 1062 | bootWait = value; 1063 | } 1064 | /* Touch readings 1065 | * Address 1 1066 | */ 1067 | byte getTouchReadings(){ 1068 | byte value = byte(EEPROM.read(1)); 1069 | if(value == 255){ 1070 | value = 120; 1071 | } 1072 | return value; 1073 | } 1074 | void setTouchReadings(byte value){ 1075 | EEPROM.write(1, value); 1076 | EEPROM.commit(); 1077 | touchReadings = value; 1078 | } 1079 | /* thresholdTouchR 1080 | * Address 2 1081 | */ 1082 | byte getThresholdTouchR(){ 1083 | byte value = byte(EEPROM.read(2)); 1084 | if(value == 255){ 1085 | value = 70; 1086 | } 1087 | return value; 1088 | } 1089 | void setThresholdTouchR(byte value){ 1090 | EEPROM.write(2, value); 1091 | EEPROM.commit(); 1092 | thresholdTouchR = value; 1093 | } 1094 | /* thresholdTouchM 1095 | * Address 3 1096 | */ 1097 | byte getThresholdTouchM(){ 1098 | byte value = byte(EEPROM.read(3)); 1099 | if(value == 255){ 1100 | value = 65; 1101 | } 1102 | return value; 1103 | } 1104 | void setThresholdTouchM(byte value){ 1105 | EEPROM.write(3, value); 1106 | EEPROM.commit(); 1107 | thresholdTouchM = value; 1108 | } 1109 | /* thresholdTouchL 1110 | * Address 4 1111 | */ 1112 | byte getThresholdTouchL(){ 1113 | byte value = byte(EEPROM.read(4)); 1114 | if(value == 255){ 1115 | value = 65; 1116 | } 1117 | return value; 1118 | } 1119 | void setThresholdTouchL(byte value){ 1120 | EEPROM.write(4, value); 1121 | EEPROM.commit(); 1122 | thresholdTouchL = value; 1123 | } 1124 | /* longTouchThreshold 1125 | * Address 5 1126 | */ 1127 | byte getLongTouchThreshold(){ 1128 | byte value = byte(EEPROM.read(5)); 1129 | if(value == 255){ 1130 | value = 12; 1131 | } 1132 | return value; 1133 | } 1134 | void setLongTouchThreshold(byte value){ 1135 | EEPROM.write(5, value); 1136 | EEPROM.commit(); 1137 | longTouchThreshold = value; 1138 | } 1139 | /* snoozeMinutes 1140 | * Address 6 1141 | */ 1142 | byte getSnoozeMinutes(){ 1143 | byte value = byte(EEPROM.read(6)); 1144 | if(value == 255){ 1145 | value = 9; 1146 | } 1147 | return value; 1148 | } 1149 | void setSnoozeMinutes(byte value){ 1150 | EEPROM.write(6, value); 1151 | EEPROM.commit(); 1152 | snoozeMinutes = value; 1153 | } 1154 | /* alarmBeeps 1155 | * Address 7 1156 | */ 1157 | byte getAlarmBeeps(){ 1158 | byte value = byte(EEPROM.read(7)); 1159 | if(value == 255){ 1160 | value = 90; 1161 | } 1162 | return value; 1163 | } 1164 | void setAlarmBeeps(byte value){ 1165 | EEPROM.write(7, value); 1166 | EEPROM.commit(); 1167 | alarmBeeps = value; 1168 | } 1169 | /* maxLux 1170 | * Address 8 1171 | */ 1172 | byte getMaxLux(){ 1173 | byte value = byte(EEPROM.read(8)); 1174 | if(value == 255){ 1175 | value = 20; 1176 | } 1177 | return value; 1178 | } 1179 | void setMaxLux(byte value){ 1180 | EEPROM.write(8, value); 1181 | EEPROM.commit(); 1182 | maxLux = value; 1183 | calculateAndSetBGLuminosity(currLux); 1184 | } 1185 | /* minLux 1186 | * Address 9 1187 | */ 1188 | byte getMinLux(){ 1189 | byte value = byte(EEPROM.read(9)); 1190 | if(value == 255){ 1191 | value = 0; 1192 | } 1193 | return value; 1194 | } 1195 | void setMinLux(byte value){ 1196 | EEPROM.write(9, value); 1197 | EEPROM.commit(); 1198 | minLux = value; 1199 | calculateAndSetBGLuminosity(currLux); 1200 | } 1201 | /* minBrightness 1202 | * Address 10 1203 | */ 1204 | byte getMinBrightness(){ 1205 | byte value = byte(EEPROM.read(10)); 1206 | if(value == 255){ 1207 | value = 10; 1208 | } 1209 | return value; 1210 | } 1211 | void setMinBrightness(byte value){ 1212 | EEPROM.write(10, value); 1213 | EEPROM.commit(); 1214 | minBrightness = value; 1215 | calculateAndSetBGLuminosity(currLux); 1216 | } 1217 | /* alarmHour 1218 | * Address 11 1219 | */ 1220 | byte getAlarmHour(){ 1221 | byte value = byte(EEPROM.read(11)); 1222 | if(value == 255){ 1223 | value = 8; 1224 | } 1225 | return value; 1226 | } 1227 | void setAlarmHour(byte value){ 1228 | EEPROM.write(11, value); 1229 | EEPROM.commit(); 1230 | alarmTime = hourMinuteToTime(value, getAlarmMinute()); 1231 | displayAlarm(); 1232 | } 1233 | /* alarmMinute 1234 | * Address 12 1235 | */ 1236 | byte getAlarmMinute(){ 1237 | byte value = byte(EEPROM.read(12)); 1238 | if(value == 255){ 1239 | value = 0; 1240 | } 1241 | return value; 1242 | } 1243 | void setAlarmMinute(byte value){ 1244 | EEPROM.write(12, value); 1245 | EEPROM.commit(); 1246 | alarmTime = hourMinuteToTime(getAlarmHour(), value); 1247 | displayAlarm(); 1248 | } 1249 | /* doAlarm 1250 | * Address --- Not stored into EEPROM 1251 | */ 1252 | byte getDoAlarm(){ 1253 | byte value; 1254 | if(doAlarm == true){ 1255 | value = 1; 1256 | }else{ 1257 | value = 0; 1258 | } 1259 | return value; 1260 | } 1261 | void setDoAlarm(byte value){ 1262 | if(value == 1){ 1263 | doAlarm = true; 1264 | }else{ 1265 | doAlarm = false; 1266 | } 1267 | displayAlarm(); 1268 | } 1269 | /* onAlarm 1270 | * Address --- Not stored into EEPROM 1271 | */ 1272 | byte getOnAlarm(){ 1273 | byte value; 1274 | if(onAlarm == true){ 1275 | value = 1; 1276 | }else{ 1277 | value = 0; 1278 | } 1279 | return value; 1280 | } 1281 | void setOnAlarm(byte value){ 1282 | if(value == 1){ 1283 | onAlarm = true; 1284 | }else{ 1285 | onAlarm = false; 1286 | } 1287 | displayAlarm(); 1288 | } 1289 | --------------------------------------------------------------------------------