├── README.md ├── clock.h ├── clock.ino ├── cloud.ino ├── data ├── acpoint.htm.gz ├── backup.htm.gz ├── clock.htm.gz ├── config.json ├── default.htm.gz ├── disp.htm.gz ├── disp2.htm.gz ├── favicon.ico ├── filesystem.htm.gz ├── index.htm.gz ├── jquery.js.gz ├── login.htm.gz ├── network.htm.gz ├── restart.htm.gz ├── segmend.ttf.gz ├── segment.ttf.gz ├── sensors.htm.gz ├── update.htm.gz ├── user.htm.gz ├── user.us └── weather.htm.gz ├── firmware ├── Clock_BIM_v3.3.bin └── old_versions │ ├── Clock_BIM_v3.0.zip │ ├── Clock_BIM_v3.1.zip │ ├── Clock_BIM_v3.2.zip │ ├── clock2.1.zip │ ├── clock_1.0.zip │ ├── clock_2.0.zip │ ├── clock_OTA_v1.1.zip │ └── clock_v1.1.zip ├── img ├── DS3231.png ├── clock2.jpg ├── clock3.jpg ├── clock4.jpg ├── clock5.jpg ├── clock6.jpg ├── clock7.jpg ├── clock_pcb_v1.1.png ├── login.png ├── sett.png ├── tm1637.png ├── wemos.jpg └── youtube.png ├── languages.h ├── libraries.zip ├── pcb ├── Diptrace V3.0 TM1637-4.dip ├── Gerber V3.0 TM1637-4.zip └── Sprint_layout v3.0 TM1637-4.lay6 ├── schematic ├── ClockSchematicV1.0.zip ├── ClockSchematicV1.1.zip ├── clock_v1.0.gif ├── clock_v1.1.gif ├── clock_v2.0.png └── clock_v3.0.png └── web.ino /README.md: -------------------------------------------------------------------------------- 1 | # Very simple WiFi clock based on ESP8266 and (TM1637 or MAX7219) 2 | ## Clock BIM 3 |

4 | 6 |

7 | 8 | * Minimum details. 3 modules and 7 SMD components. 9 | * The clock keep good time with Internet access. Thanks to synchronization with NTP server. 10 | * Automatic daylight saving time only if needed. 11 | * Decreased display brightness in night mode. 12 | * Ability to set the time and brightness of night and day mode. 13 | * Ability to connect 1 or 2 displays at once and choose what to show where. 14 | * Display the temperature, humidity and pressure from wired sensors, from thingspeak.com and a weather forecast website. 15 | * Sending data to thingspeak.com. 16 | * Ability of correction of readings of wired sensors. 17 | * Remote access to the settings of the clock, via web-interface. 18 | * Simple and understandable even to an unprepared person settings. 19 | * Ability to update the firmware over the air. 20 | 21 | ## Schematics diagram 22 |

23 | 25 |

26 | 27 | U1 is the heart of the clock this is Wemos D1 mini module, it is a module on an ESP8266 chip with all the necessary environment besides a USB -> UART converter and a 3.3V converter are built into this module. 28 |

29 | 31 |

32 | The U3 display is a 0.5-inch 7-segment LED display module with an integrated TM1637 display control chip. Of course you can use the display and a smaller or bigger size but the board is made for this size. You can also use such a display with 6 digits, then seconds will be displayed. You can also apply a 6 or 8 digits display at MAX7219. 33 |

34 | 36 |

37 | The U2 clock module on the DS3231 chip is needed to support the clock in the event of the loss of the Internet. This module can be not installed if you have a stable Internet. Firmware will determine for itself whether the clock module is installed or not. 38 |

39 | 41 |

42 | Resistors R1 and R2 are only needed if you use a TM1637 display. The diode D1 is used to protect the pins of ESP8266 from overload. You can replace it with a jumper but it is unsafe. Filtering capacitors C1-C4 can be not installed but then possibly unstable clock's work, freezes, malfunctions. The buttons S1 and S2 are needed accordingly for resetting and entering the clock into the settings mode. Buttons as you may have guessed can also not be installed. J1 connector is used to connect the temperature, humidity and pressure sensors. Sensors should be located at a distance of at least 10 cm from the clock since the clock in operation is slightly warm and the sensors are very sensitive. If you don’t need temperature, humidity and/or pressure indications then you can not install the sensors respectively J1 connector will not be needed either. 43 |
44 | The clock supports the following sensors: BME280, BMP180, SHT21 (HTU21D), DHT22 and DS18B20. You can connect one or all the sensors together. In the settings you can choose which sensor where and when to display. The sensors are connected to connector J1, the pin assignment is shown in the schematics diagram. 45 |
46 | You can power the clock by any charger from the mobile phone with a voltage of 5V rated for a current of at least 0.5A with a micro USB connector. 47 |
48 |

49 | 51 |

52 |
53 | 54 |

55 | 57 |

58 |
59 |
60 | After assembly and flashing the clock needs to be set up. When you first turn on the clock themselves enter the settings mode. In the future, you can go to the clock settings by using the clock's ip address. Connect your laptop or smartphone to the network Clock password is 1234567890 and in the browser go to http://192.168.4.1 address. 61 | The default username is admin the password is 1111. 62 |

63 | 65 |

66 |

67 | 69 |

70 | -------------------------------------------------------------------------------- /clock.h: -------------------------------------------------------------------------------- 1 | String fw = "3.3"; 2 | String vers = "BIM v" + fw; 3 | int rssi = 0; 4 | File fsUploadFile; 5 | char text_buf[255] = ""; 6 | 7 | struct{ 8 | char ssid[40] = ""; 9 | char pass[40] = ""; 10 | char apssid[40] = "Clock"; 11 | char appass[40] = "1234567890"; 12 | char apip[16] = "192.168.4.1"; 13 | char apmask[16] = "255.255.255.0"; 14 | uint8_t chnl = 1; 15 | int8_t utc = 0; 16 | uint8_t daylight = 0; 17 | bool time_format = false; 18 | uint8_t day_bright = 0; 19 | uint8_t day_bright2 = 0; 20 | uint8_t night_bright = 0; 21 | uint8_t night_bright2 = 0; 22 | bool type = 0; 23 | char ip[16] = ""; 24 | char mask[16] = ""; 25 | char gw[16] = ""; 26 | char dns1[16] = ""; 27 | char dns2[16] = ""; 28 | int hd = 0; 29 | int hd2 = 0; 30 | int md = 0; 31 | int md2 = 0; 32 | int hn = 0; 33 | int hn2 = 0; 34 | int mn = 0; 35 | int mn2 = 0; 36 | char ntp[40] = "time.nist.gov"; 37 | uint32_t chid = 0; 38 | uint8_t disp = 1; 39 | uint8_t disp2 = 2; 40 | uint32_t ntp_period = 300; 41 | uint8_t tupd = 5; 42 | bool thngsend = false; 43 | bool thngrcv = false; 44 | uint8_t tf1 = 0; 45 | uint8_t tf2 = 0; 46 | uint8_t tf3 = 0; 47 | uint8_t tf4 = 0; 48 | uint8_t tf5 = 0; 49 | uint8_t tf6 = 0; 50 | uint8_t tf7 = 0; 51 | uint8_t tf8 = 0; 52 | char rdkey[40] = ""; 53 | char wrkey[40] = ""; 54 | uint8_t dp[6] = {6, 2, 0, 0, 0, 0}; 55 | uint8_t d2p[6] = {6, 2, 0, 0, 0, 0}; 56 | uint8_t dt[6] = {1, 1, 1, 1, 1, 1}; 57 | uint8_t d2t[6] = {1, 1, 1, 1, 1, 1}; 58 | char dc[6][5] = {"#FFF", "#FFF", "#FFF", "#FFF", "#FFF", "#FFF"}; 59 | char d2c[6][5] = {"#FFF", "#FFF", "#FFF", "#FFF", "#FFF", "#FFF"}; 60 | char ds[6][4] = {"C", "C", "C", "C", "C", "C"}; 61 | char d2s[6][4] = {"C", "C", "C", "C", "C", "C"}; 62 | char username[40] = "admin"; 63 | char password[40] = "1111"; 64 | uint8_t provider = 0; 65 | uint8_t citysearch = 0; 66 | char city[40] = ""; 67 | char lat[32] = ""; 68 | char lon[32] = ""; 69 | char cityid[12] = ""; 70 | char appid[40] = ""; 71 | char appkey[40] = ""; 72 | uint8_t bme_plc = 0; 73 | uint8_t bmp_plc = 0; 74 | uint8_t sht_plc = 0; 75 | uint8_t dht_plc = 0; 76 | uint8_t ds18_plc = 0; 77 | uint8_t ds32_plc = 0; 78 | uint8_t ths_plc = 0; 79 | uint8_t wet_plc = 0; 80 | uint8_t bme_plc2 = 0; 81 | uint8_t bmp_plc2 = 0; 82 | uint8_t sht_plc2 = 0; 83 | uint8_t dht_plc2 = 0; 84 | uint8_t ds18_plc2 = 0; 85 | uint8_t ds32_plc2 = 0; 86 | uint8_t ths_plc2 = 0; 87 | uint8_t wet_plc2 = 0; 88 | } config; 89 | 90 | struct{ 91 | int8_t clock_dig[2][8] = {{0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}}; 92 | int8_t clock_points[2][8] = {{0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}}; 93 | bool dots = true; 94 | bool dots2 = true; 95 | bool halb = false; 96 | bool weather_upd = true; 97 | bool thing_upd = true; 98 | bool thing_snd = true; 99 | uint8_t prev_sec = 60; 100 | bool clock_synchronized = false; 101 | time_t prev_millis = 0; 102 | time_t prev_millis2 = 0; 103 | uint8_t snum = 5; 104 | uint8_t snum2 = 5; 105 | float temp_web = 404.0; 106 | float hum_web = 202.0; 107 | float pres_web = 4040.0; 108 | float thing[9] = {4040.0, 4040.0, 4040.0, 4040.0, 4040.0, 4040.0, 4040.0, 4040.0, 4040.0}; 109 | time_t thing_tm = 0; 110 | time_t wet_tm = 0; 111 | bool is_day = true; 112 | bool is_day2 = true; 113 | // bool ap_mode = false; 114 | bool ip_mode = false; 115 | uint8_t ip_cnt = 0; 116 | } datas; 117 | 118 | struct{ 119 | bool bme280_det = false; 120 | bool bmp180_det = false; 121 | bool sht21_det = false; 122 | bool dht22_det = false; 123 | uint8_t ds18_det = 0; 124 | bool ds32_det = false; 125 | float bme280_temp = 404.0; 126 | float bme280_temp_corr = 0.0; 127 | float bme280_hum = 202.0; 128 | float bme280_hum_corr = 0.0; 129 | float bme280_pres = 4040.0; 130 | float bme280_pres_corr = 0.0; 131 | float bmp180_temp = 404.0; 132 | float bmp180_temp_corr = 0.0; 133 | float bmp180_pres = 4040.0; 134 | float bmp180_pres_corr = 0.0; 135 | float sht21_temp = 404.0; 136 | float sht21_temp_corr = 0.0; 137 | float sht21_hum = 202.0; 138 | float sht21_hum_corr = 0.0; 139 | float dht22_temp = 404.0; 140 | float dht22_temp_corr = 0.0; 141 | float dht22_hum = 202.0; 142 | float dht22_hum_corr = 0.0; 143 | float ds18_temp = 404.0; 144 | float ds18_temp_corr = 0.0; 145 | float ds32_temp = 404.0; 146 | float ds32_temp_corr = 0.0; 147 | } sensors; 148 | 149 | void half(void); 150 | void w_upd(void); 151 | void t_upd(void); 152 | void t_snd(void); 153 | void data_prep(void); 154 | void tm1637_fill(uint8_t type, uint8_t disp); 155 | void max7219_fill(uint8_t type1, uint8_t type2); 156 | void display_fill(void); 157 | bool get_clock(bool dots, uint8_t displ); 158 | bool get_date(uint8_t displ); 159 | bool get_temp(float temperature, uint8_t displ); 160 | bool get_hum(float humidity, uint8_t displ); 161 | bool get_pres(float pressure, uint8_t displ); 162 | void read_eeprom(void); 163 | void connectToWiFi(void); 164 | void sensors_init(void); 165 | void sensors_read(void); 166 | //String httpData = ""; 167 | void getWeatherNow(void); 168 | String weatherRequest(String url); 169 | void parseWeatherNow(String httpData); 170 | void thingspk_recv(void); 171 | String thingRequest(String url); 172 | void parseThing(String httpData); 173 | void thingspk_send(void); 174 | String getContentType(String filename); 175 | bool handleFileRead(String path); 176 | bool FileRead(String path); 177 | void handleFileUpload(void); 178 | void web_settings(void); 179 | -------------------------------------------------------------------------------- /clock.ino: -------------------------------------------------------------------------------- 1 | /* Clock BIM v3.3 2 | * © himikat123@gmail.com, Nürnberg, Deutschland, 2019-2024 3 | * https://github.com/himikat123/Clock 4 | */ 5 | // Board: Generic ESP8266 Module v2.5.2 6 | // 1MB (256kB SPIFFS) 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "TM1637_6D.h" 13 | #include "LedControl.h" 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "SHT21.h" 24 | #include "DHTesp.h" 25 | #include 26 | #include 27 | #include "clock.h" 28 | 29 | #define CLK 14 30 | #define DIO 12 31 | #define DAT 13 32 | #define CLOCK 15 33 | #define LOAD 4 34 | #define ONE_WIRE_BUS 0 35 | #define BUTTON 0 36 | #define SDA 2 37 | #define SCL 0 38 | #define CLOCK_ADDRESS 0x68 39 | 40 | int dhtPin = 5; 41 | 42 | ESP8266WebServer webServer(80); 43 | TM1637_6D tm1637_6D(CLK, DIO); 44 | Ticker half_sec; 45 | Ticker weather_upd; 46 | Ticker thing_upd; 47 | Ticker thing_send; 48 | ntpClient *ntp; 49 | DS3231 Clock; 50 | SHT21 SHT21; 51 | DHTesp dht; 52 | Adafruit_BMP085 bmp; 53 | Adafruit_BME280 bme; 54 | OneWire oneWire(ONE_WIRE_BUS); 55 | DallasTemperature term(&oneWire); 56 | DeviceAddress thermometer; 57 | LedControl lc = LedControl(DAT, CLOCK, LOAD, 1); 58 | Adafruit_Sensor *bme_temp = bme.getTemperatureSensor(); 59 | Adafruit_Sensor *bme_pressure = bme.getPressureSensor(); 60 | Adafruit_Sensor *bme_humidity = bme.getHumiditySensor(); 61 | 62 | void half(void){ 63 | datas.halb = true; 64 | } 65 | 66 | void w_upd(void){ 67 | datas.weather_upd = true; 68 | } 69 | 70 | void t_upd(void){ 71 | datas.thing_upd = true; 72 | } 73 | 74 | void t_snd(void){ 75 | datas.thing_snd = true; 76 | } 77 | 78 | void setup(void){ 79 | //Serial port 80 | Serial.begin(74880); 81 | while(!Serial); 82 | //PINs 83 | pinMode(BUTTON, INPUT); 84 | pinMode(ONE_WIRE_BUS, INPUT); 85 | pinMode(SDA, INPUT); 86 | //SPIFS 87 | if(!SPIFFS.begin()) while(1) yield(); 88 | //EEPROM 89 | read_eeprom(); 90 | ESP.rtcUserMemoryWrite(0, (uint32_t*) ESP8266TrueRandom.random(0, 1000), 10); 91 | //Display 92 | tm1637_6D.init(); 93 | tm1637_6D.set(3); 94 | tm1637_6D.display(datas.clock_dig[0], datas.clock_points[0]); 95 | lc.shutdown(0, false); 96 | lc.shutdown(1, false); 97 | lc.setIntensity(0, 7); 98 | lc.setIntensity(1, 7); 99 | lc.clearDisplay(0); 100 | lc.clearDisplay(1); 101 | lc.setChar(0, 7, '-', false); 102 | lc.setChar(0, 6, '-', false); 103 | lc.setChar(0, 5, '-', false); 104 | lc.setChar(0, 4, '-', false); 105 | lc.setChar(0, 3, '-', false); 106 | lc.setChar(0, 2, '-', false); 107 | lc.setChar(0, 1, '-', false); 108 | lc.setChar(0, 0, '-', false); 109 | lc.setChar(1, 7, '-', false); 110 | lc.setChar(1, 6, '-', false); 111 | lc.setChar(1, 5, '-', false); 112 | lc.setChar(1, 4, '-', false); 113 | lc.setChar(1, 3, '-', false); 114 | lc.setChar(1, 2, '-', false); 115 | lc.setChar(1, 1, '-', false); 116 | lc.setChar(1, 0, '-', false); 117 | //WIFI MODE 118 | WiFi.mode(WIFI_STA); 119 | connectToWiFi(); 120 | //Settings 121 | web_settings(); 122 | //NTP 123 | ntp = ntpClient::getInstance(config.ntp, 1); 124 | ntp -> setInterval(15, config.ntp_period * 60); 125 | ntp -> setTimeZone(config.utc); 126 | ntp -> setDayLight(config.daylight); 127 | ntp -> begin(); 128 | //settings 129 | if(!digitalRead(BUTTON) or String(config.ssid) == ""){ 130 | apMode(); 131 | } 132 | //i2c 133 | Wire.pins(SDA, SCL); 134 | //sensors 135 | sensors_init(); 136 | //Ticker 137 | weather_upd.attach_ms(1200000, w_upd); 138 | thing_upd.attach_ms(30000, t_upd); 139 | thing_send.attach_ms(300000, t_snd); 140 | // 141 | sensors_read(); 142 | data_prep(); 143 | display_fill(); 144 | } 145 | 146 | void loop(void){ 147 | if(!digitalRead(BUTTON) and !datas.ip_mode){ 148 | datas.ip_mode = true; 149 | datas.ip_cnt = 0; 150 | } 151 | 152 | if(WiFi.status() != WL_CONNECTED){ 153 | datas.weather_upd = true; 154 | datas.thing_upd = true; 155 | datas.thing_snd = true; 156 | connectToWiFi(); 157 | } 158 | 159 | if(datas.prev_sec != second()){ 160 | sensors_read(); 161 | datas.halb = false; 162 | half_sec.attach_ms(500, half); 163 | data_prep(); 164 | display_fill(); 165 | datas.prev_sec = second(); 166 | } 167 | 168 | if(datas.halb){ 169 | data_prep(); 170 | display_fill(); 171 | datas.halb = false; 172 | half_sec.detach(); 173 | } 174 | 175 | if(datas.weather_upd){ 176 | if((String(config.appid) != "" or String(config.appkey) != "") and WiFi.status() == WL_CONNECTED) getWeatherNow(); 177 | datas.weather_upd = false; 178 | } 179 | 180 | if(datas.thing_upd){ 181 | if(config.thngrcv and WiFi.status() == WL_CONNECTED) thingspk_recv(); 182 | datas.thing_upd = false; 183 | } 184 | 185 | if(datas.thing_snd){ 186 | if(config.thngsend and WiFi.status() == WL_CONNECTED) thingspk_send(); 187 | datas.thing_snd = false; 188 | } 189 | 190 | if(now() - ntp -> getLastNTPSync() < 2){ 191 | if(now() > 1617569756 and sensors.ds32_det){ 192 | bool a, b, c; 193 | if( 194 | Clock.getYear() + 2000 != year() or 195 | Clock.getMonth(c) != month() or 196 | Clock.getDate() != day() or 197 | Clock.getHour(a, b) != hour() or 198 | Clock.getMinute() != minute() or 199 | Clock.getSecond() != second() 200 | ){ 201 | Serial.printf("sync NTP at %02d:%02d:%02d %02d-%02d-%d\r\n", hour(), minute(), second(), day(), month(), year()); 202 | Clock.setYear(year() - 2000); 203 | Clock.setMonth(month()); 204 | Clock.setDate(day()); 205 | Clock.setHour(hour()); 206 | Clock.setMinute(minute()); 207 | Clock.setSecond(second()); 208 | } 209 | } 210 | } 211 | 212 | if(now() - ntp -> getLastNTPSync() < 1200) datas.clock_synchronized = true; 213 | else datas.clock_synchronized = false; 214 | 215 | webServer.handleClient(); 216 | } 217 | 218 | void data_prep(void){ 219 | if(datas.ip_mode) get_ip(); 220 | else{ 221 | if((millis() - datas.prev_millis >= config.dp[datas.snum] * 1000) or (config.dp[datas.snum] == 0)){ 222 | datas.snum++; 223 | for(uint8_t i=datas.snum; i<6; i++){ 224 | if(config.dp[datas.snum] == 0) datas.snum++; 225 | else break; 226 | } 227 | if(datas.snum > 5) datas.snum = 0; 228 | datas.prev_millis = millis(); 229 | } 230 | if((millis() - datas.prev_millis2 >= config.d2p[datas.snum2] * 1000) or (config.d2p[datas.snum2] == 0)){ 231 | datas.snum2++; 232 | for(uint8_t i=datas.snum2; i<6; i++){ 233 | if(config.d2p[datas.snum2] == 0) datas.snum2++; 234 | else break; 235 | } 236 | if(datas.snum2 > 5) datas.snum2 = 0; 237 | datas.prev_millis2 = millis(); 238 | } 239 | if(config.dp[datas.snum] > 0){ 240 | switch(config.dt[datas.snum]){ 241 | case 1: 242 | if(String(config.ds[datas.snum]) == "C") datas.dots = get_clock(datas.clock_synchronized ? datas.dots : false, 0); 243 | if(String(config.ds[datas.snum]) == "D") datas.dots = get_date(0); 244 | break; 245 | case 2: 246 | if(String(config.ds[datas.snum]) == "T") datas.dots = get_temp(sensors.bme280_temp, 0, config.bme_plc); 247 | if(String(config.ds[datas.snum]) == "H") datas.dots = get_hum((float)sensors.bme280_hum, 0, config.bme_plc); 248 | if(String(config.ds[datas.snum]) == "P") datas.dots = get_pres((float)sensors.bme280_pres, 0); 249 | break; 250 | case 3: 251 | if(String(config.ds[datas.snum]) == "T") datas.dots = get_temp(sensors.bmp180_temp, 0, config.bmp_plc); 252 | if(String(config.ds[datas.snum]) == "P") datas.dots = get_pres((float)sensors.bmp180_pres, 0); 253 | break; 254 | case 4: 255 | if(String(config.ds[datas.snum]) == "T") datas.dots = get_temp(sensors.sht21_temp, 0, config.sht_plc); 256 | if(String(config.ds[datas.snum]) == "H") datas.dots = get_hum((float)sensors.sht21_hum, 0, config.sht_plc); 257 | break; 258 | case 5: 259 | if(String(config.ds[datas.snum]) == "T") datas.dots = get_temp(sensors.dht22_temp, 0, config.dht_plc); 260 | if(String(config.ds[datas.snum]) == "H") datas.dots = get_hum((float)sensors.dht22_hum, 0, config.dht_plc); 261 | break; 262 | case 6: 263 | datas.dots = get_temp(sensors.ds18_temp, 0, config.ds18_plc); 264 | break; 265 | case 7: 266 | datas.dots = get_temp(sensors.ds32_temp, 0, config.ds32_plc); 267 | break; 268 | case 8://thingspeak 269 | if(now() - datas.thing_tm < 1200){ 270 | if(config.ds[datas.snum][0] == 'T') datas.dots = get_temp(datas.thing[String(config.ds[datas.snum][2]).toInt()], 0, config.ths_plc); 271 | if(config.ds[datas.snum][0] == 'H') datas.dots = get_hum(datas.thing[String(config.ds[datas.snum][2]).toInt()], 0, config.ths_plc); 272 | if(config.ds[datas.snum][0] == 'P') datas.dots = get_pres(datas.thing[String(config.ds[datas.snum][2]).toInt()], 0); 273 | } 274 | else{ 275 | if(config.ds[datas.snum][0] == 'T') datas.dots = get_temp(4040.0, 0, config.ths_plc); 276 | if(config.ds[datas.snum][0] == 'H') datas.dots = get_hum(4040.0, 0, config.ths_plc); 277 | if(config.ds[datas.snum][0] == 'P') datas.dots = get_pres(4040.0, 0); 278 | } 279 | break; 280 | case 9://weather 281 | if(now() - datas.wet_tm < 1200){ 282 | if(String(config.ds[datas.snum]) == "T") datas.dots = get_temp(datas.temp_web, 0, config.wet_plc); 283 | if(String(config.ds[datas.snum]) == "H") datas.dots = get_hum(datas.hum_web, 0, config.wet_plc); 284 | if(String(config.ds[datas.snum]) == "P") datas.dots = get_pres(datas.pres_web, 0); 285 | } 286 | else{ 287 | if(String(config.ds[datas.snum]) == "T") datas.dots = get_temp(4040.0, 0, config.wet_plc); 288 | if(String(config.ds[datas.snum]) == "H") datas.dots = get_hum(4040, 0, config.wet_plc); 289 | if(String(config.ds[datas.snum]) == "P") datas.dots = get_pres(4040, 0); 290 | } 291 | break; 292 | default:;; 293 | } 294 | } 295 | if(config.d2p[datas.snum2] > 0){ 296 | switch(config.d2t[datas.snum2]){ 297 | case 1: 298 | if(String(config.d2s[datas.snum2]) == "C") datas.dots2 = get_clock(datas.clock_synchronized ? datas.dots2 : false, 1); 299 | if(String(config.d2s[datas.snum2]) == "D") datas.dots2 = get_date(1); 300 | break; 301 | case 2: 302 | if(String(config.d2s[datas.snum2]) == "T") datas.dots2 = get_temp(sensors.bme280_temp, 1, config.bme_plc2); 303 | if(String(config.d2s[datas.snum2]) == "H") datas.dots2 = get_hum((float)sensors.bme280_hum, 1, config.bme_plc2); 304 | if(String(config.d2s[datas.snum2]) == "P") datas.dots2 = get_pres((float)sensors.bme280_pres, 1); 305 | break; 306 | case 3: 307 | if(String(config.d2s[datas.snum2]) == "T") datas.dots2 = get_temp(sensors.bmp180_temp, 1, config.bmp_plc2); 308 | if(String(config.d2s[datas.snum2]) == "P") datas.dots2 = get_pres((float)sensors.bmp180_pres, 1); 309 | break; 310 | case 4: 311 | if(String(config.d2s[datas.snum2]) == "T") datas.dots2 = get_temp(sensors.sht21_temp, 1, config.sht_plc2); 312 | if(String(config.d2s[datas.snum2]) == "H") datas.dots2 = get_hum((float)sensors.sht21_hum, 1, config.sht_plc2); 313 | break; 314 | case 5: 315 | if(String(config.d2s[datas.snum2]) == "T") datas.dots2 = get_temp(sensors.dht22_temp, 1, config.dht_plc2); 316 | if(String(config.d2s[datas.snum2]) == "H") datas.dots2 = get_hum((float)sensors.dht22_hum, 1, config.dht_plc2); 317 | break; 318 | case 6: 319 | datas.dots2 = get_temp(sensors.ds18_temp, 1, config.ds18_plc2); 320 | break; 321 | case 7: 322 | datas.dots2 = get_temp(sensors.ds32_temp, 1, config.ds32_plc2); 323 | break; 324 | case 8://thingspeak 325 | if(now() - datas.thing_tm < 1200){ 326 | if(config.d2s[datas.snum2][0] == 'T') datas.dots2 = get_temp(datas.thing[String(config.d2s[datas.snum2][2]).toInt()], 1, config.ths_plc2); 327 | if(config.d2s[datas.snum2][0] == 'H') datas.dots2 = get_hum(datas.thing[String(config.d2s[datas.snum2][2]).toInt()], 1, config.ths_plc2); 328 | if(config.d2s[datas.snum2][0] == 'P') datas.dots2 = get_pres(datas.thing[String(config.d2s[datas.snum2][2]).toInt()], 1); 329 | } 330 | else{ 331 | if(config.d2s[datas.snum2][0] == 'T') datas.dots2 = get_temp(4040.0, 1, config.ths_plc2); 332 | if(config.d2s[datas.snum2][0] == 'H') datas.dots2 = get_hum(4040.0, 1, config.ths_plc2); 333 | if(config.d2s[datas.snum2][0] == 'P') datas.dots2 = get_pres(4040.0, 1); 334 | } 335 | break; 336 | case 9://weather 337 | if(now() - datas.wet_tm < 1200){ 338 | if(String(config.d2s[datas.snum2]) == "T") datas.dots2 = get_temp(datas.temp_web, 1, config.wet_plc2); 339 | if(String(config.d2s[datas.snum2]) == "H") datas.dots2 = get_hum(datas.hum_web, 1, config.wet_plc2); 340 | if(String(config.d2s[datas.snum2]) == "P") datas.dots2 = get_pres(datas.pres_web, 1); 341 | } 342 | else{ 343 | if(String(config.d2s[datas.snum2]) == "T") datas.dots2 = get_temp(4040.0, 1, config.wet_plc2); 344 | if(String(config.d2s[datas.snum2]) == "H") datas.dots2 = get_hum(4040.0, 1, config.wet_plc2); 345 | if(String(config.d2s[datas.snum2]) == "P") datas.dots2 = get_pres(4040.0, 1); 346 | } 347 | break; 348 | default:;; 349 | } 350 | } 351 | } 352 | } 353 | 354 | void tm1637_fill(uint8_t type, uint8_t disp){ 355 | if(type == 0){ 356 | if(disp == 0) datas.clock_points[0][5] = datas.clock_points[0][4] = datas.clock_points[0][3] = datas.clock_points[0][0] = datas.dots ? POINT_ON : POINT_OFF; 357 | if(disp == 1) datas.clock_points[1][5] = datas.clock_points[1][4] = datas.clock_points[1][3] = datas.clock_points[1][0] = datas.dots2 ? POINT_ON : POINT_OFF; 358 | datas.clock_dig[disp][0] = datas.clock_dig[disp][5]; 359 | datas.clock_dig[disp][5] = datas.clock_dig[disp][4]; 360 | datas.clock_dig[disp][4] = datas.clock_dig[disp][3]; 361 | datas.clock_dig[disp][3] = datas.clock_dig[disp][2]; 362 | datas.clock_dig[disp][1] = datas.clock_dig[disp][2] = 0x0E; 363 | uint8_t bright = 10; 364 | if(disp == 0){ 365 | if(datas.is_day) bright = round(config.day_bright / 12); 366 | else bright = round(config.night_bright / 12); 367 | } 368 | if(disp == 1){ 369 | if(datas.is_day2) bright = round(config.day_bright2 / 12); 370 | else bright = round(config.night_bright2 / 12); 371 | } 372 | tm1637_6D.set(bright > 7 ? 7 : bright); 373 | tm1637_6D.display(datas.clock_dig[disp], datas.clock_points[disp]); 374 | } 375 | 376 | if(type == 1){ 377 | datas.clock_points[disp][5] = datas.clock_points[disp][3] = datas.clock_points[disp][1] = datas.clock_points[disp][0] = POINT_OFF; 378 | if(disp == 0) datas.clock_points[0][4] = datas.clock_points[0][2] = datas.dots ? POINT_ON : POINT_OFF; 379 | if(disp == 1) datas.clock_points[1][4] = datas.clock_points[1][2] = datas.dots2 ? POINT_ON : POINT_OFF; 380 | int8_t dig[6]; 381 | for(uint8_t i=0; i<6; i++) dig[i] = datas.clock_dig[disp][6 - i]; 382 | uint8_t bright = 10; 383 | if(disp == 0){ 384 | if(datas.is_day) bright = round(config.day_bright / 12); 385 | else bright = round(config.night_bright / 12); 386 | } 387 | if(disp == 1){ 388 | if(datas.is_day2) bright = round(config.day_bright2 / 12); 389 | else bright = round(config.night_bright2 / 12); 390 | } 391 | tm1637_6D.set(bright > 7 ? 7 : bright); 392 | tm1637_6D.display(dig, datas.clock_points[disp]); 393 | } 394 | } 395 | 396 | void max7219_fill(uint8_t type1, uint8_t type2){ 397 | uint8_t bright = 15; 398 | uint8_t bright2 = 15; 399 | if(datas.is_day) bright = round(config.day_bright / 6); 400 | else bright = round(config.night_bright / 6); 401 | if(datas.is_day2) bright2 = round(config.day_bright2 / 6); 402 | else bright2 = round(config.night_bright2 / 6); 403 | uint8_t msymb[2][20] = { 404 | { 405 | 0x7E, 0x30, 0x6D, 0x79, //0123 406 | 0x33, 0x5B, 0x5F, 0x70, //4567 407 | 0x7F, 0x7B, 0x63, 0x4F, //89°E 408 | 0x67, 0x37, 0x00, 0x0F, //PH t 409 | 0x01, 0x4E, 0x3D, 0x3B //-CdY 410 | }, 411 | { 412 | 0xFE, 0xB0, 0xED, 0xF9, //0.1.2.3. 413 | 0xB3, 0xDB, 0xDF, 0xF0, //4.5.6.7. 414 | 0xFF, 0xFB, 0xE3, 0xCF, //8.9.°.E. 415 | 0xE7, 0xB7, 0x80, 0x8F, //P.H. .t. 416 | 0x81, 0xCE, 0xBD, 0xBB //-.C.d.Y. 417 | }, 418 | }; 419 | 420 | if(((type1 == 2 || type1 == 3) && !(type2 == 2 || type2 == 3)) || (!(type1 == 2 || type1 == 3) && (type2 == 2 || type2 == 3))){ 421 | if(type1 == 2 || type1 == 3){ 422 | uint8_t dot = (type1 == 2) ? (datas.dots == true) ? 1 : 0 : 0; 423 | uint8_t typ = (type1 == 2) ? 1 : 0; 424 | lc.setIntensity(0, bright); 425 | lc.setRow(0, 0, msymb[0][datas.clock_dig[0][7 - typ]]); 426 | lc.setRow(0, 1, msymb[0][datas.clock_dig[0][6 - typ]]); 427 | lc.setRow(0, 2, msymb[dot][datas.clock_dig[0][5 - typ]]); 428 | lc.setRow(0, 3, msymb[0][datas.clock_dig[0][4 - typ]]); 429 | lc.setRow(0, 4, msymb[dot][datas.clock_dig[0][3 - typ]]); 430 | lc.setRow(0, 5, msymb[0][datas.clock_dig[0][2 - typ]]); 431 | lc.setRow(0, 6, (type1 == 2) ? 0 : msymb[0][datas.clock_dig[0][1]]); 432 | lc.setRow(0, 7, (type1 == 2) ? 0 : msymb[0][datas.clock_dig[0][0]]); 433 | } 434 | if(type2 == 2 || type2 == 3){ 435 | uint8_t dot = (type2 == 2) ? (datas.dots2 == true) ? 1 : 0 : 0; 436 | uint8_t typ = (type2 == 2) ? 1 : 0; 437 | lc.setIntensity(0, bright2); 438 | lc.setRow(0, 0, msymb[0][datas.clock_dig[1][7 - typ]]); 439 | lc.setRow(0, 1, msymb[0][datas.clock_dig[1][6 - typ]]); 440 | lc.setRow(0, 2, msymb[dot][datas.clock_dig[1][5 - typ]]); 441 | lc.setRow(0, 3, msymb[0][datas.clock_dig[1][4 - typ]]); 442 | lc.setRow(0, 4, msymb[dot][datas.clock_dig[1][3 - typ]]); 443 | lc.setRow(0, 5, msymb[0][datas.clock_dig[1][2 - typ]]); 444 | lc.setRow(0, 6, (type2 == 2) ? 0 : msymb[0][datas.clock_dig[1][1]]); 445 | lc.setRow(0, 7, (type2 == 2) ? 0 : msymb[0][datas.clock_dig[1][0]]); 446 | } 447 | } 448 | if((type1 == 2 || type1 == 3) && (type2 == 2 || type2 == 3)){ 449 | uint8_t dot = (type1 == 2) ? (datas.dots == true) ? 1 : 0 : 0; 450 | uint8_t typ = (type1 == 2) ? 1 : 0; 451 | lc.setIntensity(0, bright); 452 | lc.setRow(0, 0, msymb[0][datas.clock_dig[0][7 - typ]]); 453 | lc.setRow(0, 1, msymb[0][datas.clock_dig[0][6 - typ]]); 454 | lc.setRow(0, 2, msymb[dot][datas.clock_dig[0][5 - typ]]); 455 | lc.setRow(0, 3, msymb[0][datas.clock_dig[0][4 - typ]]); 456 | lc.setRow(0, 4, msymb[dot][datas.clock_dig[0][3 - typ]]); 457 | lc.setRow(0, 5, msymb[0][datas.clock_dig[0][2 - typ]]); 458 | lc.setRow(0, 6, (type1 == 2) ? 0 : msymb[0][datas.clock_dig[0][1]]); 459 | lc.setRow(0, 7, (type1 == 2) ? 0 : msymb[0][datas.clock_dig[0][0]]); 460 | dot = (type2 == 2) ? (datas.dots2 == true) ? 1 : 0 : 0; 461 | typ = (type2 == 2) ? 1 : 0; 462 | lc.setIntensity(1, bright2); 463 | lc.setRow(1, 0, msymb[0][datas.clock_dig[1][7 - typ]]); 464 | lc.setRow(1, 1, msymb[0][datas.clock_dig[1][6 - typ]]); 465 | lc.setRow(1, 2, msymb[dot][datas.clock_dig[1][5 - typ]]); 466 | lc.setRow(1, 3, msymb[0][datas.clock_dig[1][4 - typ]]); 467 | lc.setRow(1, 4, msymb[dot][datas.clock_dig[1][3 - typ]]); 468 | lc.setRow(1, 5, msymb[0][datas.clock_dig[1][2 - typ]]); 469 | lc.setRow(1, 6, (type2 == 2) ? 0 : msymb[0][datas.clock_dig[1][1]]); 470 | lc.setRow(1, 7, (type2 == 2) ? 0 : msymb[0][datas.clock_dig[1][0]]); 471 | } 472 | } 473 | 474 | void ws2812b_fill(uint8_t type1, uint8_t type2){ 475 | uint8_t bright = 25; 476 | if(datas.is_day) bright = config.day_bright; 477 | else bright = config.night_bright; 478 | uint8_t bright2 = 25; 479 | if(datas.is_day2) bright2 = config.day_bright2; 480 | else bright2 = config.night_bright2; 481 | if(bright < 1) bright = 1; 482 | if(bright > 100) bright = 100; 483 | if(bright2 < 1) bright2 = 1; 484 | if(bright2 > 100) bright2 = 100; 485 | if((type1 == 4 and type2 != 4) or (type1 != 4 and type2 == 4)){ 486 | uint8_t disp = (type2 == 4) ? 1 : 0; 487 | uint8_t dots = (disp == 0) ? (datas.dots) ? 1 : 0 : (datas.dots2) ? 1 : 0; 488 | StaticJsonDocument<400> doc; 489 | JsonArray data = doc.createNestedArray("ws2812"); 490 | data.add(datas.clock_dig[disp][2]); 491 | data.add(datas.clock_dig[disp][3]); 492 | data.add(datas.clock_dig[disp][4]); 493 | data.add(datas.clock_dig[disp][5]); 494 | data.add(dots); 495 | data.add(disp == 0 ? config.dc[datas.snum] : config.d2c[datas.snum2]); 496 | data.add(bright); 497 | data.add(0); 498 | data.add(0); 499 | data.add(0); 500 | data.add(0); 501 | data.add(0); 502 | data.add(0); 503 | data.add(0); 504 | serializeJson(doc, Serial); 505 | Serial.println(); 506 | } 507 | if(type1 == 4 and type2 == 4){ 508 | StaticJsonDocument<400> doc; 509 | JsonArray data = doc.createNestedArray("ws2812"); 510 | data.add(datas.clock_dig[0][2]); 511 | data.add(datas.clock_dig[0][3]); 512 | data.add(datas.clock_dig[0][4]); 513 | data.add(datas.clock_dig[0][5]); 514 | data.add((datas.dots) ? 1 : 0); 515 | data.add(config.dc[datas.snum]); 516 | data.add(bright); 517 | data.add(datas.clock_dig[1][2]); 518 | data.add(datas.clock_dig[1][3]); 519 | data.add(datas.clock_dig[1][4]); 520 | data.add(datas.clock_dig[1][5]); 521 | data.add((datas.dots2) ? 1 : 0); 522 | data.add(config.d2c[datas.snum2]); 523 | data.add(bright2); 524 | serializeJson(doc, Serial); 525 | Serial.println(); 526 | } 527 | } 528 | 529 | void display_fill(void){ 530 | tmElements_t daymode = {0, config.md, config.hd, weekday(), day(), month(), year() - 1970}; 531 | uint32_t fromT = makeTime(daymode); 532 | tmElements_t nightmode = {0, config.mn, config.hn, weekday(), day(), month(), year() - 1970}; 533 | uint32_t toT = makeTime(nightmode); 534 | if(fromT <= now() and now() <= toT) datas.is_day = true; 535 | else datas.is_day = false; 536 | tmElements_t daymode2 = {0, config.md2, config.hd2, weekday(), day(), month(), year() - 1970}; 537 | uint32_t fromT2 = makeTime(daymode2); 538 | tmElements_t nightmode2 = {0, config.mn2, config.hn2, weekday(), day(), month(), year() - 1970}; 539 | uint32_t toT2 = makeTime(nightmode2); 540 | if(fromT2 <= now() and now() <= toT2) datas.is_day2 = true; 541 | else datas.is_day2 = false; 542 | if(config.disp == 0) tm1637_fill(0, 0); 543 | if(config.disp2 == 0) tm1637_fill(0, 1); 544 | if(config.disp == 1) tm1637_fill(1, 0); 545 | if(config.disp2 == 1) tm1637_fill(1, 1); 546 | if(config.disp == 2 or config.disp == 3 or config.disp2 == 2 or config.disp2 == 3) max7219_fill(config.disp, config.disp2); 547 | if(config.disp == 4 or config.disp2 == 4) ws2812b_fill(config.disp, config.disp2); 548 | } 549 | 550 | uint8_t to_dig(char ch){ 551 | if(ch == ' ') return 0x0E; 552 | else if(ch == '.') return 0x10; 553 | else return int(ch) - 0x30; 554 | } 555 | 556 | void get_ip(void){ 557 | String ip = " " + WiFi.localIP().toString() + " "; 558 | datas.clock_dig[0][0] = datas.clock_dig[1][0] = to_dig(ip[datas.ip_cnt]); 559 | datas.clock_dig[0][1] = datas.clock_dig[1][1] = to_dig(ip[datas.ip_cnt + 1]); 560 | datas.clock_dig[0][2] = datas.clock_dig[1][2] = to_dig(ip[datas.ip_cnt + 2]); 561 | datas.clock_dig[0][3] = datas.clock_dig[1][3] = to_dig(ip[datas.ip_cnt + 3]); 562 | datas.clock_dig[0][4] = datas.clock_dig[1][4] = to_dig(ip[datas.ip_cnt + 4]); 563 | datas.clock_dig[0][5] = datas.clock_dig[1][5] = to_dig(ip[datas.ip_cnt + 5]); 564 | datas.clock_dig[0][6] = datas.clock_dig[1][6] = to_dig(ip[datas.ip_cnt + 6]); 565 | datas.clock_dig[0][7] = datas.clock_dig[1][7] = to_dig(ip[datas.ip_cnt + 7]); 566 | datas.ip_cnt++; 567 | if(datas.ip_cnt > ip.length() - 7){ 568 | datas.ip_cnt = 0; 569 | datas.ip_mode = false; 570 | } 571 | datas.dots = datas.dots2 = false; 572 | } 573 | 574 | bool get_clock(bool dots, uint8_t displ){ 575 | uint8_t hr = config.time_format ? hour() : hourFormat12(); 576 | uint8_t hh = hr < 10 ? 0x0E : hr / 10; 577 | uint8_t hl = hr % 10; 578 | uint8_t mh = minute() / 10; 579 | uint8_t ml = minute() % 10; 580 | uint8_t sh = second() / 10; 581 | uint8_t sl = second() % 10; 582 | uint8_t disp_tp = (displ == 0) ? config.disp : config.disp2; 583 | datas.clock_dig[displ][0] = (disp_tp == 3) ? hh : 0x0E; 584 | datas.clock_dig[displ][1] = (disp_tp == 0 || disp_tp == 4) ? 0x0E : (disp_tp == 3) ? hl : hh; 585 | datas.clock_dig[displ][2] = (disp_tp == 0 || disp_tp == 4) ? hh : (disp_tp == 3) ? dots ? 0x10 : 0x0E : hl; 586 | datas.clock_dig[displ][3] = (disp_tp == 0 || disp_tp == 4) ? hl : mh; 587 | datas.clock_dig[displ][4] = (disp_tp == 0 || disp_tp == 4) ? mh : ml; 588 | datas.clock_dig[displ][5] = (disp_tp == 0 || disp_tp == 4) ? ml : (disp_tp == 3) ? dots ? 0x10 : 0x0E : sh; 589 | datas.clock_dig[displ][6] = (disp_tp == 0 || disp_tp == 4) ? 0x0E : (disp_tp == 3) ? sh : sl; 590 | datas.clock_dig[displ][7] = (disp_tp == 3) ? sl : 0x0E; 591 | return !dots; 592 | } 593 | 594 | bool get_date(uint8_t displ){ 595 | uint8_t dh = day() / 10; 596 | uint8_t dl = day() % 10; 597 | uint8_t mh = month() / 10; 598 | uint8_t ml = month() % 10; 599 | uint8_t yh = (year() - 2000) / 10; 600 | uint8_t yl = (year() - 2000) % 10; 601 | uint8_t disp_tp = (displ == 0) ? config.disp : config.disp2; 602 | datas.clock_dig[displ][0] = (disp_tp == 3) ? dh : 0x0E; 603 | datas.clock_dig[displ][1] = (disp_tp == 0 || disp_tp == 4) ? 0x0E : (disp_tp == 3) ? dl : 0x0E; 604 | datas.clock_dig[displ][2] = (disp_tp == 0 || disp_tp == 4) ? dh : (disp_tp == 3) ? 0x10 : dh; 605 | datas.clock_dig[displ][3] = (disp_tp == 0 || disp_tp == 4) ? dl : (disp_tp == 3) ? mh : dl; 606 | datas.clock_dig[displ][4] = (disp_tp == 0 || disp_tp == 4) ? mh : (disp_tp == 3) ? ml : 0x10; 607 | datas.clock_dig[displ][5] = (disp_tp == 0 || disp_tp == 4) ? ml : (disp_tp == 3) ? 0x10 : mh; 608 | datas.clock_dig[displ][6] = (disp_tp == 0 || disp_tp == 4) ? 0x0E : (disp_tp == 3) ? yh : ml; 609 | datas.clock_dig[displ][7] = (disp_tp == 3) ? yl : 0x0E; 610 | return 0; 611 | } 612 | 613 | bool get_temp(float temperature, uint8_t displ, uint8_t plc){ 614 | int t = round(temperature); 615 | datas.clock_dig[displ][0] = datas.clock_dig[displ][6] = datas.clock_dig[displ][7] = 0x0E; 616 | if(t > 99 or t < -50){ 617 | datas.clock_dig[displ][1] = 0x0E; 618 | datas.clock_dig[displ][2] = datas.clock_dig[displ][3] = 0x10; 619 | datas.clock_dig[displ][4] = 0x0A; 620 | datas.clock_dig[displ][5] = 0x11; 621 | } 622 | else{ 623 | uint8_t th = floor(abs(t) / 10); 624 | uint8_t tl = abs(t) % 10; 625 | if(th == 0) th = 0x0E; 626 | uint8_t disp_tp = (displ == 0) ? config.disp : config.disp2; 627 | if(disp_tp == 3){ 628 | datas.clock_dig[displ][0] = (plc == 1) ? 0x12 : (plc == 2) ? 0x13 : 0x0E; 629 | datas.clock_dig[displ][1] = 0x0E; 630 | datas.clock_dig[displ][2] = (t < 0) ? (t < -9) ? 0x10 : 0x0E : 0x0E; 631 | datas.clock_dig[displ][3] = (t < 0) ? (t < -9) ? th : 0x10 : th; 632 | datas.clock_dig[displ][4] = tl; 633 | datas.clock_dig[displ][5] = 0x0A; 634 | datas.clock_dig[displ][6] = 0x11; 635 | } 636 | else{ 637 | datas.clock_dig[displ][1] = (disp_tp == 0 || disp_tp == 4) ? 0x0E : (t < 0) ? (t < -9) ? 0x10 : 0x0E : 0x0E; 638 | datas.clock_dig[displ][2] = (disp_tp == 0 || disp_tp == 4) ? (t < 0) ? 0x10 : th : (t < 0) ? (t < -9) ? th : 0x10 : th; 639 | datas.clock_dig[displ][3] = (disp_tp == 0 || disp_tp == 4) ? (t < 0) ? (t < -9) ? th : tl : tl : tl; 640 | datas.clock_dig[displ][4] = (disp_tp == 0 || disp_tp == 4) ? (t < 0) ? (t < -9) ? tl : 0x0A : 0x0A : 0x0A; 641 | datas.clock_dig[displ][5] = (disp_tp == 0 || disp_tp == 4) ? (t < 0) ? (t < -9) ? 0x0A : 0x11 : 0x11 : 0x11; 642 | } 643 | } 644 | return 0; 645 | } 646 | 647 | bool get_hum(float humidity, uint8_t displ, uint8_t plc){ 648 | uint8_t h = round(humidity); 649 | datas.clock_dig[displ][5] = 0x0D; 650 | datas.clock_dig[displ][0] = datas.clock_dig[displ][6] = datas.clock_dig[displ][7] = 0x0E; 651 | if(h > 100){ 652 | datas.clock_dig[displ][1] = datas.clock_dig[displ][4] = 0x0E; 653 | datas.clock_dig[displ][2] = datas.clock_dig[displ][3] = 0x10; 654 | } 655 | else{ 656 | uint8_t hh = h / 10; 657 | uint8_t hl = h % 10; 658 | if(hh == 0) hh = 0x0E; 659 | uint8_t disp_tp = (displ == 0) ? config.disp : config.disp2; 660 | datas.clock_dig[displ][0] = (disp_tp == 3) ? (plc == 1) ? 0x12 : (plc == 2) ? 0x13 : 0x0E : 0x0E; 661 | datas.clock_dig[displ][1] = (disp_tp == 0 || disp_tp == 4) ? 0x0E : (h > 99) ? 1 : 0x0E; 662 | datas.clock_dig[displ][2] = (disp_tp == 0 || disp_tp == 4) ? (h > 99) ? 1 : hh : (h > 99) ? 0 : hh; 663 | datas.clock_dig[displ][3] = (disp_tp == 0 || disp_tp == 4) ? (h > 99) ? 0 : hl : (h > 99) ? 0 : hl; 664 | datas.clock_dig[displ][4] = (disp_tp == 0 || disp_tp == 4) ? (h > 99) ? 0 : 0x0E : 0x0E; 665 | } 666 | return 0; 667 | } 668 | 669 | bool get_pres(float pressure, uint8_t displ){ 670 | uint16_t p = round(pressure); 671 | datas.clock_dig[displ][5] = 0x0C; 672 | datas.clock_dig[displ][0] = datas.clock_dig[displ][1] = datas.clock_dig[displ][6] = datas.clock_dig[displ][7] = 0x0E; 673 | if(p > 999){ 674 | datas.clock_dig[displ][2] = datas.clock_dig[displ][3] = datas.clock_dig[displ][4] = 0x10; 675 | } 676 | else{ 677 | datas.clock_dig[displ][2] = p / 100; 678 | datas.clock_dig[displ][3] = p % 100 / 10; 679 | datas.clock_dig[displ][4] = p % 10; 680 | } 681 | return 0; 682 | } 683 | 684 | void read_eeprom(void){ 685 | File file = SPIFFS.open("/config.json", "r"); 686 | while(file.available()){ 687 | String json = file.readString(); 688 | //Serial.println(json); 689 | DynamicJsonDocument conf(8192); 690 | DeserializationError error = deserializeJson(conf, json); 691 | if(!error){ 692 | strlcpy(config.ssid, conf["ssid"] | config.ssid, sizeof(config.ssid)); 693 | strlcpy(config.pass, conf["pass"] | config.pass, sizeof(config.pass)); 694 | strlcpy(config.mask, conf["mask"] | config.mask, sizeof(config.mask)); 695 | strlcpy(config.dns1, conf["dns1"] | config.dns1, sizeof(config.dns1)); 696 | strlcpy(config.dns2, conf["dns2"] | config.dns2, sizeof(config.dns2)); 697 | strlcpy(config.ip, conf["ip"] | config.ip, sizeof(config.ip)); 698 | strlcpy(config.gw, conf["gw"] | config.gw, sizeof(config.gw)); 699 | config.type = conf["type"].as() | config.type; 700 | strlcpy(config.apssid, conf["apssid"] | config.apssid, sizeof(config.apssid)); 701 | strlcpy(config.appass, conf["appass"] | config.appass, sizeof(config.appass)); 702 | strlcpy(config.apmask, conf["apmask"] | config.apmask, sizeof(config.apmask)); 703 | strlcpy(config.apip, conf["apip"] | config.apip, sizeof(config.apip)); 704 | config.chnl = conf["chnl"] | config.chnl; 705 | 706 | config.day_bright = conf["day_bright"] | config.day_bright; 707 | config.day_bright2 = conf["day_bright2"] | config.day_bright2; 708 | config.night_bright = conf["night_bright"] | config.night_bright; 709 | config.night_bright2 = conf["night_bright2"] | config.night_bright2; 710 | config.hd = conf["hd"] | config.hd; 711 | config.hd2 = conf["hd2"] | config.hd2; 712 | config.md = conf["md"] | config.md; 713 | config.md2 = conf["md2"] | config.md2; 714 | config.hn = conf["hn"] | config.hn; 715 | config.hn2 = conf["hn2"] | config.hn2; 716 | config.mn = conf["mn"] | config.mn; 717 | config.mn2 = conf["mn2"] | config.mn2; 718 | config.disp = conf["disp"] | config.disp; 719 | config.disp2 = conf["disp2"] | config.disp2; 720 | 721 | config.time_format = conf["time"].as() | config.time_format; 722 | config.utc = conf["utc"] | config.utc; 723 | config.daylight = conf["dlst"].as() | config.daylight; 724 | strlcpy(config.ntp, conf["ntp"] | config.ntp, sizeof(config.ntp)); 725 | config.ntp_period = conf["ntp_period"] | config.ntp_period; 726 | 727 | sensors.bme280_temp_corr = conf["bmet"] | sensors.bme280_temp_corr; 728 | sensors.bmp180_temp_corr = conf["bmpt"] | sensors.bmp180_temp_corr; 729 | sensors.sht21_temp_corr = conf["shtt"] | sensors.sht21_temp_corr; 730 | sensors.dht22_temp_corr = conf["dhtt"] | sensors.dht22_temp_corr; 731 | sensors.bme280_hum_corr = conf["bmeh"] | sensors.bme280_hum_corr; 732 | sensors.sht21_hum_corr = conf["shth"] | sensors.sht21_hum_corr; 733 | sensors.dht22_hum_corr = conf["dhth"] | sensors.dht22_hum_corr; 734 | sensors.bme280_pres_corr = conf["bmep"] | sensors.bme280_pres_corr; 735 | sensors.bmp180_pres_corr = conf["bmpp"] | sensors.bmp180_pres_corr; 736 | sensors.ds18_temp_corr = conf["ds18t"] | sensors.ds18_temp_corr; 737 | sensors.ds32_temp_corr = conf["ds32t"] | sensors.ds32_temp_corr; 738 | 739 | config.tupd = conf["tupd"] | config.tupd; 740 | config.thngsend = conf["thngsnd"] | config.thngsend; 741 | config.thngrcv = conf["thngrcv"] | config.thngrcv; 742 | 743 | config.tf1 = conf["tf1"] | config.tf1; 744 | config.tf2 = conf["tf2"] | config.tf2; 745 | config.tf3 = conf["tf3"] | config.tf3; 746 | config.tf4 = conf["tf4"] | config.tf4; 747 | config.tf5 = conf["tf5"] | config.tf5; 748 | config.tf6 = conf["tf6"] | config.tf6; 749 | config.tf7 = conf["tf7"] | config.tf7; 750 | config.tf8 = conf["tf8"] | config.tf8; 751 | strlcpy(config.rdkey, conf["rdkey"] | config.rdkey, sizeof(config.rdkey)); 752 | strlcpy(config.wrkey, conf["wrkey"] | config.wrkey, sizeof(config.wrkey)); 753 | config.chid = conf["chid"] | config.chid; 754 | 755 | config.dp[0] = conf["dp0"] | config.dp[0]; 756 | config.dp[1] = conf["dp1"] | config.dp[1]; 757 | config.dp[2] = conf["dp2"] | config.dp[2]; 758 | config.dp[3] = conf["dp3"] | config.dp[3]; 759 | config.dp[4] = conf["dp4"] | config.dp[4]; 760 | config.dp[5] = conf["dp5"] | config.dp[5]; 761 | config.dt[0] = conf["dt0"] | config.dt[0]; 762 | config.dt[1] = conf["dt1"] | config.dt[1]; 763 | config.dt[2] = conf["dt2"] | config.dt[2]; 764 | config.dt[3] = conf["dt3"] | config.dt[3]; 765 | config.dt[4] = conf["dt4"] | config.dt[4]; 766 | config.dt[5] = conf["dt5"] | config.dt[5]; 767 | strlcpy(config.dc[0], conf["dc0"] | config.dc[0], sizeof(config.dc[0])); 768 | strlcpy(config.dc[1], conf["dc1"] | config.dc[1], sizeof(config.dc[1])); 769 | strlcpy(config.dc[2], conf["dc2"] | config.dc[2], sizeof(config.dc[2])); 770 | strlcpy(config.dc[3], conf["dc3"] | config.dc[3], sizeof(config.dc[3])); 771 | strlcpy(config.dc[4], conf["dc4"] | config.dc[4], sizeof(config.dc[4])); 772 | strlcpy(config.dc[5], conf["dc5"] | config.dc[5], sizeof(config.dc[5])); 773 | strlcpy(config.ds[0], conf["ds0"] | config.ds[0], sizeof(config.ds[0])); 774 | strlcpy(config.ds[1], conf["ds1"] | config.ds[1], sizeof(config.ds[1])); 775 | strlcpy(config.ds[2], conf["ds2"] | config.ds[2], sizeof(config.ds[2])); 776 | strlcpy(config.ds[3], conf["ds3"] | config.ds[3], sizeof(config.ds[3])); 777 | strlcpy(config.ds[4], conf["ds4"] | config.ds[4], sizeof(config.ds[4])); 778 | strlcpy(config.ds[5], conf["ds5"] | config.ds[5], sizeof(config.ds[5])); 779 | config.d2p[0] = conf["d2p0"] | config.d2p[0]; 780 | config.d2p[1] = conf["d2p1"] | config.d2p[1]; 781 | config.d2p[2] = conf["d2p2"] | config.d2p[2]; 782 | config.d2p[3] = conf["d2p3"] | config.d2p[3]; 783 | config.d2p[4] = conf["d2p4"] | config.d2p[4]; 784 | config.d2p[5] = conf["d2p5"] | config.d2p[5]; 785 | config.d2t[0] = conf["d2t0"] | config.d2t[0]; 786 | config.d2t[1] = conf["d2t1"] | config.d2t[1]; 787 | config.d2t[2] = conf["d2t2"] | config.d2t[2]; 788 | config.d2t[3] = conf["d2t3"] | config.d2t[3]; 789 | config.d2t[4] = conf["d2t4"] | config.d2t[4]; 790 | config.d2t[5] = conf["d2t5"] | config.d2t[5]; 791 | strlcpy(config.d2c[0], conf["d2c0"] | config.d2c[0], sizeof(config.d2c[0])); 792 | strlcpy(config.d2c[1], conf["d2c1"] | config.d2c[1], sizeof(config.d2c[1])); 793 | strlcpy(config.d2c[2], conf["d2c2"] | config.d2c[2], sizeof(config.d2c[2])); 794 | strlcpy(config.d2c[3], conf["d2c3"] | config.d2c[3], sizeof(config.d2c[3])); 795 | strlcpy(config.d2c[4], conf["d2c4"] | config.d2c[4], sizeof(config.d2c[4])); 796 | strlcpy(config.d2c[5], conf["d2c5"] | config.d2c[5], sizeof(config.d2c[5])); 797 | strlcpy(config.d2s[0], conf["d2s0"] | config.d2s[0], sizeof(config.d2s[0])); 798 | strlcpy(config.d2s[1], conf["d2s1"] | config.d2s[1], sizeof(config.d2s[1])); 799 | strlcpy(config.d2s[2], conf["d2s2"] | config.d2s[2], sizeof(config.d2s[2])); 800 | strlcpy(config.d2s[3], conf["d2s3"] | config.d2s[3], sizeof(config.d2s[3])); 801 | strlcpy(config.d2s[4], conf["d2s4"] | config.d2s[4], sizeof(config.d2s[4])); 802 | strlcpy(config.d2s[5], conf["d2s5"] | config.d2s[5], sizeof(config.d2s[5])); 803 | 804 | config.provider = conf["provider"] | config.provider; 805 | config.citysearch = conf["citysearch"] | config.citysearch; 806 | strlcpy(config.city, conf["city"] | config.city, sizeof(config.city)); 807 | strlcpy(config.lat, conf["lat"] | config.lat, sizeof(config.lat)); 808 | strlcpy(config.lon, conf["lon"] | config.lon, sizeof(config.lon)); 809 | strlcpy(config.cityid, conf["cityid"] | config.cityid, sizeof(config.cityid)); 810 | strlcpy(config.appid, conf["appid"] | config.appid, sizeof(config.appid)); 811 | strlcpy(config.appkey, conf["appkey"] | config.appkey, sizeof(config.appkey)); 812 | 813 | config.bme_plc = conf["bme_plc"] | config.bme_plc; 814 | config.bmp_plc = conf["bmp_plc"] | config.bmp_plc; 815 | config.sht_plc = conf["sht_plc"] | config.sht_plc; 816 | config.dht_plc = conf["dht_plc"] | config.dht_plc; 817 | config.ds18_plc = conf["ds18_plc"] | config.ds18_plc; 818 | config.ds32_plc = conf["ds32_plc"] | config.ds32_plc; 819 | config.ths_plc = conf["ths_plc"] | config.ths_plc; 820 | config.wet_plc = conf["wet_plc"] | config.wet_plc; 821 | config.bme_plc2 = conf["bme_plc2"] | config.bme_plc2; 822 | config.bmp_plc2 = conf["bmp_plc2"] | config.bmp_plc2; 823 | config.sht_plc2 = conf["sht_plc2"] | config.sht_plc2; 824 | config.dht_plc2 = conf["dht_plc2"] | config.dht_plc2; 825 | config.ds18_plc2 = conf["ds18_plc2"] | config.ds18_plc2; 826 | config.ds32_plc2 = conf["ds32_plc2"] | config.ds32_plc2; 827 | config.ths_plc2 = conf["ths_plc2"] | config.ths_plc2; 828 | config.wet_plc2 = conf["wet_plc2"] | config.wet_plc2; 829 | } 830 | } 831 | 832 | file = SPIFFS.open("/user.us", "r"); 833 | while(file.available()){ 834 | String json = file.readString(); 835 | DynamicJsonDocument conf(128); 836 | DeserializationError error = deserializeJson(conf, json); 837 | if(!error){ 838 | strlcpy(config.username, conf["user"] | config.username, sizeof(config.username)); 839 | strlcpy(config.password, conf["pass"] | config.password, sizeof(config.password)); 840 | } 841 | } 842 | } 843 | 844 | void apMode(){ 845 | WiFi.disconnect(); 846 | Serial.printf("AP Mode SSID: \"%s\" password: \"%s\"", config.apssid, config.appass); 847 | IPAddress ip; 848 | IPAddress subnet; 849 | IPAddress gateway; 850 | if(ip.fromString(config.apip) and gateway.fromString(config.apip) and subnet.fromString(config.apmask)){ 851 | WiFi.softAPConfig(ip, gateway, subnet); 852 | } 853 | WiFi.mode(WIFI_AP_STA); 854 | WiFi.softAP(config.apssid, config.appass, config.chnl); 855 | 856 | datas.clock_dig[0][0] = datas.clock_dig[0][2] = datas.clock_dig[0][4] = datas.clock_dig[0][6] = 0x0C; 857 | datas.clock_dig[0][1] = datas.clock_dig[0][3] = datas.clock_dig[0][5] = datas.clock_dig[0][7] = 0x0C; 858 | datas.clock_dig[1][0] = datas.clock_dig[1][2] = datas.clock_dig[1][4] = datas.clock_dig[1][6] = 0x0C; 859 | datas.clock_dig[1][1] = datas.clock_dig[1][3] = datas.clock_dig[1][5] = datas.clock_dig[1][7] = 0x0C; 860 | tm1637_6D.display(datas.clock_dig[0], datas.clock_points[0]); 861 | lc.setChar(0, 7, 'P', false); 862 | lc.setChar(0, 6, 'P', false); 863 | lc.setChar(0, 5, 'P', false); 864 | lc.setChar(0, 4, 'P', false); 865 | lc.setChar(0, 3, 'P', false); 866 | lc.setChar(0, 2, 'P', false); 867 | lc.setChar(0, 1, 'P', false); 868 | lc.setChar(0, 0, 'P', false); 869 | lc.setChar(1, 7, 'P', false); 870 | lc.setChar(1, 6, 'P', false); 871 | lc.setChar(1, 5, 'P', false); 872 | lc.setChar(1, 4, 'P', false); 873 | lc.setChar(1, 3, 'P', false); 874 | lc.setChar(1, 2, 'P', false); 875 | lc.setChar(1, 1, 'P', false); 876 | lc.setChar(1, 0, 'P', false); 877 | while(1){ 878 | webServer.handleClient(); 879 | yield(); 880 | delay(100); 881 | } 882 | } 883 | 884 | void connectToWiFi(void){ 885 | WiFi.disconnect(); 886 | Serial.print("Connect to WiFi "); 887 | if(String(config.ssid) != ""){ 888 | uint8_t i = 0; 889 | WiFi.begin(config.ssid, config.pass); 890 | while(WiFi.status() != WL_CONNECTED){ 891 | Serial.print("."); 892 | delay(500); 893 | if(i++ > 30) break; 894 | } 895 | if(WiFi.status() == WL_CONNECTED){ 896 | //datas.ap_mode = false; 897 | WiFi.setAutoConnect(true); 898 | WiFi.setAutoReconnect(true); 899 | if(config.type){ 900 | IPAddress ip; 901 | IPAddress subnet; 902 | IPAddress gateway; 903 | IPAddress dns1; 904 | IPAddress dns2; 905 | if(ip.fromString(config.ip) and 906 | gateway.fromString(config.gw) and 907 | subnet.fromString(config.mask) and 908 | dns1.fromString(config.dns1) and 909 | dns2.fromString(config.dns2) 910 | ) WiFi.config(ip, gateway, subnet, dns1, dns2); 911 | } 912 | Serial.print("\r\nConnected to: "); Serial.println(WiFi.SSID()); 913 | Serial.print("IP address: "); Serial.println(WiFi.localIP()); 914 | } 915 | else Serial.println(" Failed"); 916 | } 917 | //else apMode(WIFI_AP); 918 | } 919 | 920 | void sensors_init(void){ 921 | //BME280 922 | sensors.bme280_det = bme.begin(0x76, &Wire); 923 | if(!sensors.bme280_det) sensors.bme280_det = bme.begin(0x77, &Wire); 924 | //BMP180 925 | if(bmp.begin()) sensors.bmp180_det = true; 926 | //SHT21; 927 | SHT21.begin(); 928 | Wire.beginTransmission(SHT21_ADDRESS); 929 | Wire.write(0xE7); 930 | Wire.endTransmission(); 931 | delay(100); 932 | Wire.requestFrom(SHT21_ADDRESS, 1); 933 | if(Wire.available() == 1){ 934 | Wire.read(); 935 | sensors.sht21_det = true; 936 | } 937 | //DHT22 938 | dht.setup(dhtPin, DHTesp::DHT22); 939 | dht.getTempAndHumidity(); 940 | dht.getStatus(); 941 | if(dht.getStatus() == 0) sensors.dht22_det = true; 942 | //DS18B20 943 | term.begin(); 944 | sensors.ds18_det = term.getDeviceCount(); 945 | if(sensors.ds18_det > 0){ 946 | term.getAddress(thermometer, 0); 947 | term.setResolution(thermometer, 10); 948 | term.requestTemperatures(); 949 | } 950 | //DS3231 951 | bool a, b, c; 952 | byte hr = Clock.getHour(a, b); 953 | byte mn = Clock.getMinute(); 954 | byte sc = Clock.getSecond(); 955 | byte dt = Clock.getDate(); 956 | byte mt = Clock.getMonth(c); 957 | uint16_t yr = Clock.getYear() + 2000; 958 | 959 | if(hr >= 0 and hr <= 23){ 960 | sensors.ds32_det = true; 961 | Serial.printf("DS3231 time: %02d:%02d:%02d %02d-%02d-%d\r\n", hr, mn, sc, dt, mt, yr); 962 | setTime(hr, mn, sc, dt, mt, yr); 963 | } 964 | // 965 | Serial.printf("%s %s%s\r\n", "DS3231", sensors.ds32_det ? "" : "not ", "detected"); 966 | Serial.printf("%s %s%s\r\n", "BME280", sensors.bme280_det ? "" : "not ", "detected"); 967 | Serial.printf("%s %s%s\r\n", "BMP180", sensors.bmp180_det ? "" : "not ", "detected"); 968 | Serial.printf("%s %s%s\r\n", "DS18B20", sensors.ds18_det ? "" : "not ", "detected"); 969 | Serial.printf("%s %s%s\r\n", "SHT21", sensors.sht21_det ? "" : "not ", "detected"); 970 | Serial.printf("%s %s%s\r\n", "DHT22", sensors.dht22_det ? "" : "not ", "detected"); 971 | } 972 | 973 | void sensors_read(void){ 974 | /////////// Temperature ////////////////////////////////// 975 | if(sensors.bme280_det){ 976 | sensors_event_t temp_event; 977 | bme_temp -> getEvent(&temp_event); 978 | sensors.bme280_temp = temp_event.temperature + sensors.bme280_temp_corr; 979 | } 980 | if(sensors.bmp180_det) sensors.bmp180_temp = bmp.readTemperature() + sensors.bmp180_temp_corr; 981 | if(sensors.sht21_det) sensors.sht21_temp = SHT21.getTemperature() + sensors.sht21_temp_corr; 982 | if(sensors.dht22_det) sensors.dht22_temp = dht.getTemperature() + sensors.dht22_temp_corr; 983 | if(sensors.ds18_det){ sensors.ds18_temp = term.getTempC(thermometer) + sensors.ds18_temp_corr; term.requestTemperatures();} 984 | if(sensors.ds32_det) sensors.ds32_temp = Clock.getTemperature() + sensors.ds32_temp_corr; 985 | /////////// Humidity ////////////////////////////////// 986 | if(sensors.bme280_det){ 987 | sensors_event_t humidity_event; 988 | bme_humidity -> getEvent(&humidity_event); 989 | sensors.bme280_hum = humidity_event.relative_humidity + sensors.bme280_hum_corr; 990 | } 991 | if(sensors.sht21_det) sensors.sht21_hum = SHT21.getHumidity() + sensors.sht21_hum_corr; 992 | if(sensors.dht22_det) sensors.dht22_hum = dht.getHumidity() + sensors.dht22_hum_corr; 993 | ////////// Pressure ///////////////////////////////////// 994 | if(sensors.bme280_det){ 995 | sensors_event_t pressure_event; 996 | bme_pressure -> getEvent(&pressure_event); 997 | sensors.bme280_pres = pressure_event.pressure + sensors.bme280_pres_corr; 998 | sensors.bme280_pres *= 0.75; 999 | } 1000 | if(sensors.bmp180_det){ 1001 | sensors.bmp180_pres = bmp.readPressure() / 100 + sensors.bmp180_pres_corr; 1002 | sensors.bmp180_pres *= 0.75; 1003 | } 1004 | } 1005 | -------------------------------------------------------------------------------- /cloud.ino: -------------------------------------------------------------------------------- 1 | void getWeatherNow(void){ 2 | String url; 3 | if(config.provider == 0){ 4 | url = "http://api.openweathermap.org/data/2.5/weather"; 5 | if(config.citysearch == 0) url += "?q=" + String(config.city); 6 | if(config.citysearch == 1) url += "?id=" + String(config.cityid); 7 | if(config.citysearch == 2) url += "?lat=" + String(config.lat) + "&lon=" + String(config.lon); 8 | url += "&units=metric&appid=" + String(config.appid); 9 | } 10 | if(config.provider == 1){ 11 | url = "http://api.weatherbit.io/v2.0/current?key="; 12 | url += String(config.appkey); 13 | if(config.citysearch == 0) url += "&city=" + String(config.city); 14 | if(config.citysearch == 1) url += "&city_id=" + String(config.cityid); 15 | if(config.citysearch == 2) url += "&lat=" + String(config.lat) + "&lon=" + String(config.lon); 16 | } 17 | parseWeatherNow(weatherRequest(url)); 18 | } 19 | 20 | String weatherRequest(String url){ 21 | String httpData = ""; 22 | HTTPClient client; 23 | client.begin(url); 24 | int httpCode = client.GET(); 25 | if(httpCode > 0){ 26 | if(httpCode == HTTP_CODE_OK){ 27 | httpData = client.getString(); 28 | } 29 | } 30 | client.end(); 31 | return httpData; 32 | } 33 | 34 | void parseWeatherNow(String httpData){ 35 | StaticJsonDocument<2048> root; 36 | DeserializationError error = deserializeJson(root, httpData); 37 | if(error) return; 38 | if(config.provider == 0){ 39 | datas.temp_web = root["main"]["temp"]; 40 | datas.hum_web = root["main"]["humidity"]; 41 | datas.pres_web = root["main"]["pressure"]; 42 | datas.pres_web *= 0.75; 43 | } 44 | if(config.provider == 1){ 45 | datas.temp_web = root["data"][0]["temp"]; 46 | datas.hum_web = root["data"][0]["rh"]; 47 | datas.pres_web = root["data"][0]["pres"]; 48 | datas.pres_web *= 0.75; 49 | } 50 | httpData = ""; 51 | datas.wet_tm = now(); 52 | Serial.printf("weather updated at %02d:%02d:%02d\r\n", hour(), minute(), second()); 53 | } 54 | 55 | void thingspk_recv(void){ 56 | String url; 57 | url = "http://api.thingspeak.com/channels/"; 58 | url += String(config.chid); 59 | url += "/feeds.json?api_key="; 60 | url += String(config.rdkey); 61 | url += "&results=1"; 62 | parseThing(thingRequest(url)); 63 | } 64 | 65 | String thingRequest(String url){ 66 | String httpData = ""; 67 | HTTPClient client; 68 | client.begin(url); 69 | int httpCode = client.GET(); 70 | if(httpCode > 0){ 71 | if(httpCode == HTTP_CODE_OK){ 72 | httpData = client.getString(); 73 | } 74 | } 75 | client.end(); 76 | return httpData; 77 | } 78 | 79 | void parseThing(String httpData){ 80 | StaticJsonDocument<2048> root; 81 | DeserializationError error = deserializeJson(root, httpData); 82 | if(error) return; 83 | String thing_tm = root["feeds"][0]["created_at"]; 84 | datas.thing[1] = root["feeds"][0]["field1"]; 85 | datas.thing[2] = root["feeds"][0]["field2"]; 86 | datas.thing[3] = root["feeds"][0]["field3"]; 87 | datas.thing[4] = root["feeds"][0]["field4"]; 88 | datas.thing[5] = root["feeds"][0]["field5"]; 89 | datas.thing[6] = root["feeds"][0]["field6"]; 90 | datas.thing[7] = root["feeds"][0]["field7"]; 91 | datas.thing[8] = root["feeds"][0]["field8"]; 92 | httpData = ""; 93 | TimeElements tm; 94 | char buf[22]; 95 | thing_tm.toCharArray(buf, 22); 96 | tm.Year = atoi(strtok(buf, "-")) - 1970; 97 | tm.Month = atoi(strtok(NULL, "-")); 98 | tm.Day = atoi(strtok(NULL, "T")); 99 | tm.Hour = atoi(strtok(NULL, ":")); 100 | tm.Minute = atoi(strtok(NULL, ":")); 101 | tm.Second = atoi(strtok(NULL, ":")); 102 | datas.thing_tm = makeTime(tm); 103 | datas.thing_tm += config.utc * 3600; 104 | datas.thing_tm += config.daylight ? is_summertime() ? 3600 : 0 : 0; 105 | Serial.printf("thingspeak updated at %02d:%02d:%02d\r\n", hour(), minute(), second()); 106 | } 107 | 108 | void thingspk_send(void){ 109 | String url; 110 | url = "http://api.thingspeak.com/update?api_key="; 111 | url += String(config.wrkey); 112 | if(config.tf1 > 0){ 113 | url += "&field1="; 114 | switch(config.tf1){ 115 | case 1: url += String(sensors.bme280_temp); break; 116 | case 2: url += String(sensors.bme280_hum); break; 117 | case 3: url += String(sensors.bme280_pres); break; 118 | case 4: url += String(sensors.bmp180_temp); break; 119 | case 5: url += String(sensors.bmp180_pres); break; 120 | case 6: url += String(sensors.sht21_temp); break; 121 | case 7: url += String(sensors.sht21_hum); break; 122 | case 8: url += String(sensors.dht22_temp); break; 123 | case 9: url += String(sensors.dht22_hum); break; 124 | case 10: url += String(sensors.ds18_temp); break; 125 | case 11: url += String(sensors.ds32_temp); break; 126 | default: url += "0"; break; 127 | } 128 | } 129 | if(config.tf2 > 0){ 130 | url += "&field2="; 131 | switch(config.tf2){ 132 | case 1: url += String(sensors.bme280_temp); break; 133 | case 2: url += String(sensors.bme280_hum); break; 134 | case 3: url += String(sensors.bme280_pres); break; 135 | case 4: url += String(sensors.bmp180_temp); break; 136 | case 5: url += String(sensors.bmp180_pres); break; 137 | case 6: url += String(sensors.sht21_temp); break; 138 | case 7: url += String(sensors.sht21_hum); break; 139 | case 8: url += String(sensors.dht22_temp); break; 140 | case 9: url += String(sensors.dht22_hum); break; 141 | case 10: url += String(sensors.ds18_temp); break; 142 | case 11: url += String(sensors.ds32_temp); break; 143 | default: url += "0"; break; 144 | } 145 | } 146 | if(config.tf3 > 0){ 147 | url += "&field3="; 148 | switch(config.tf3){ 149 | case 1: url += String(sensors.bme280_temp); break; 150 | case 2: url += String(sensors.bme280_hum); break; 151 | case 3: url += String(sensors.bme280_pres); break; 152 | case 4: url += String(sensors.bmp180_temp); break; 153 | case 5: url += String(sensors.bmp180_pres); break; 154 | case 6: url += String(sensors.sht21_temp); break; 155 | case 7: url += String(sensors.sht21_hum); break; 156 | case 8: url += String(sensors.dht22_temp); break; 157 | case 9: url += String(sensors.dht22_hum); break; 158 | case 10: url += String(sensors.ds18_temp); break; 159 | case 11: url += String(sensors.ds32_temp); break; 160 | default: url += "0"; break; 161 | } 162 | } 163 | if(config.tf4 > 0){ 164 | url += "&field4="; 165 | switch(config.tf4){ 166 | case 1: url += String(sensors.bme280_temp); break; 167 | case 2: url += String(sensors.bme280_hum); break; 168 | case 3: url += String(sensors.bme280_pres); break; 169 | case 4: url += String(sensors.bmp180_temp); break; 170 | case 5: url += String(sensors.bmp180_pres); break; 171 | case 6: url += String(sensors.sht21_temp); break; 172 | case 7: url += String(sensors.sht21_hum); break; 173 | case 8: url += String(sensors.dht22_temp); break; 174 | case 9: url += String(sensors.dht22_hum); break; 175 | case 10: url += String(sensors.ds18_temp); break; 176 | case 11: url += String(sensors.ds32_temp); break; 177 | default: url += "0"; break; 178 | } 179 | } 180 | if(config.tf5 > 0){ 181 | url += "&field5="; 182 | switch(config.tf5){ 183 | case 1: url += String(sensors.bme280_temp); break; 184 | case 2: url += String(sensors.bme280_hum); break; 185 | case 3: url += String(sensors.bme280_pres); break; 186 | case 4: url += String(sensors.bmp180_temp); break; 187 | case 5: url += String(sensors.bmp180_pres); break; 188 | case 6: url += String(sensors.sht21_temp); break; 189 | case 7: url += String(sensors.sht21_hum); break; 190 | case 8: url += String(sensors.dht22_temp); break; 191 | case 9: url += String(sensors.dht22_hum); break; 192 | case 10: url += String(sensors.ds18_temp); break; 193 | case 11: url += String(sensors.ds32_temp); break; 194 | default: url += "0"; break; 195 | } 196 | } 197 | if(config.tf6 > 0){ 198 | url += "&field6="; 199 | switch(config.tf6){ 200 | case 1: url += String(sensors.bme280_temp); break; 201 | case 2: url += String(sensors.bme280_hum); break; 202 | case 3: url += String(sensors.bme280_pres); break; 203 | case 4: url += String(sensors.bmp180_temp); break; 204 | case 5: url += String(sensors.bmp180_pres); break; 205 | case 6: url += String(sensors.sht21_temp); break; 206 | case 7: url += String(sensors.sht21_hum); break; 207 | case 8: url += String(sensors.dht22_temp); break; 208 | case 9: url += String(sensors.dht22_hum); break; 209 | case 10: url += String(sensors.ds18_temp); break; 210 | case 11: url += String(sensors.ds32_temp); break; 211 | default: url += "0"; break; 212 | } 213 | } 214 | if(config.tf7 > 0){ 215 | url += "&field7="; 216 | switch(config.tf7){ 217 | case 1: url += String(sensors.bme280_temp); break; 218 | case 2: url += String(sensors.bme280_hum); break; 219 | case 3: url += String(sensors.bme280_pres); break; 220 | case 4: url += String(sensors.bmp180_temp); break; 221 | case 5: url += String(sensors.bmp180_pres); break; 222 | case 6: url += String(sensors.sht21_temp); break; 223 | case 7: url += String(sensors.sht21_hum); break; 224 | case 8: url += String(sensors.dht22_temp); break; 225 | case 9: url += String(sensors.dht22_hum); break; 226 | case 10: url += String(sensors.ds18_temp); break; 227 | case 11: url += String(sensors.ds32_temp); break; 228 | default: url += "0"; break; 229 | } 230 | } 231 | if(config.tf8 > 0){ 232 | url += "&field8="; 233 | switch(config.tf8){ 234 | case 1: url += String(sensors.bme280_temp); break; 235 | case 2: url += String(sensors.bme280_hum); break; 236 | case 3: url += String(sensors.bme280_pres); break; 237 | case 4: url += String(sensors.bmp180_temp); break; 238 | case 5: url += String(sensors.bmp180_pres); break; 239 | case 6: url += String(sensors.sht21_temp); break; 240 | case 7: url += String(sensors.sht21_hum); break; 241 | case 8: url += String(sensors.dht22_temp); break; 242 | case 9: url += String(sensors.dht22_hum); break; 243 | case 10: url += String(sensors.ds18_temp); break; 244 | case 11: url += String(sensors.ds32_temp); break; 245 | default: url += "0"; break; 246 | } 247 | } 248 | String httpData = ""; 249 | HTTPClient client; 250 | client.begin(url); 251 | int httpCode = client.GET(); 252 | if(httpCode > 0){ 253 | if(httpCode == HTTP_CODE_OK){ 254 | httpData = client.getString(); 255 | } 256 | } 257 | client.end(); 258 | httpData = ""; 259 | } 260 | 261 | boolean is_summertime(){ 262 | if(month() < 3 || month() > 10) return false; 263 | if(month() > 3 && month() < 10) return true; 264 | if((month() == 3 && (hour() + 24 * day()) >= (1 + 24 * (31 - (5 * year() / 4 + 4) % 7))) || (month() == 10 && (hour() + 24 * day()) < (1 + 24 * (31 - (5 * year() / 4 + 1) % 7)))) return true; 265 | else return false; 266 | } 267 | -------------------------------------------------------------------------------- /data/acpoint.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/acpoint.htm.gz -------------------------------------------------------------------------------- /data/backup.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/backup.htm.gz -------------------------------------------------------------------------------- /data/clock.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/clock.htm.gz -------------------------------------------------------------------------------- /data/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssid": "", 3 | "pass": "", 4 | "ip": "", 5 | "mask": "", 6 | "gw": "", 7 | "dns1": "", 8 | "dns2": "", 9 | "type": false, 10 | "apssid": "clock", 11 | "appass": "1234567890", 12 | "chnl": "1", 13 | "apip": "192.168.4.1", 14 | "apmask": "255.255.255.0", 15 | "bmet": 0, 16 | "bmpt": 0, 17 | "shtt": 0, 18 | "dhtt": 0, 19 | "bmeh": 0, 20 | "shth": 0, 21 | "dhth": 0, 22 | "bmep": 0, 23 | "bmpp": 0, 24 | "dst": 0, 25 | "thngsnd": false, 26 | "thngrcv": false, 27 | "chid": 0, 28 | "wrkey": "", 29 | "rdkey": "", 30 | "tf1": 0, 31 | "tf2": 0, 32 | "tf3": 0, 33 | "tf4": 0, 34 | "tf5": 0, 35 | "tf6": 0, 36 | "tf7": 0, 37 | "tf8": 0, 38 | "ntp": "time.nist.gov", 39 | "utc": 0, 40 | "dlst": false, 41 | "time": 0, 42 | "ntp_period": 15, 43 | "hd": 8, 44 | "md": 0, 45 | "hn": 21, 46 | "mn": 0, 47 | "dp0": 6, 48 | "dp1": 2, 49 | "dp2": 0, 50 | "dp3": 0, 51 | "dp4": 0, 52 | "dp5": 0, 53 | "dt1": 1, 54 | "dt2": 1, 55 | "dt3": 1, 56 | "dt4": 1, 57 | "dt5": 1, 58 | "ds0": "C", 59 | "ds1": "D", 60 | "ds2": "C", 61 | "ds3": "C", 62 | "ds4": "C", 63 | "ds5": "C", 64 | "dc0": "#FFF", 65 | "dc1": "#FFF", 66 | "dc2": "#FFF", 67 | "dc3": "#FFF", 68 | "dc4": "#FFF", 69 | "dc5": "#FFF", 70 | "day_bright": 87, 71 | "night_bright": 13, 72 | "dt0": 1, 73 | "disp": 0, 74 | "ds18t": 0, 75 | "ds32t": 0, 76 | "appid": "", 77 | "appkey": "", 78 | "city": "", 79 | "cityid": "", 80 | "lat": "", 81 | "lon": "", 82 | "provider": 0, 83 | "citysearch": 0, 84 | "disp2": 2, 85 | "d2p0": 6, 86 | "d2p1": 2, 87 | "d2p2": 0, 88 | "d2p3": 0, 89 | "d2p4": 0, 90 | "d2p5": 0, 91 | "d2t0": 1, 92 | "d2t1": 1, 93 | "d2t2": 1, 94 | "d2t3": 1, 95 | "d2t4": 1, 96 | "d2t5": 1, 97 | "d2s0": "C", 98 | "d2s1": "D", 99 | "d2s2": "C", 100 | "d2s3": "C", 101 | "d2s4": "C", 102 | "d2s5": "C", 103 | "d2c0": "#FFF", 104 | "d2c1": "#FFF", 105 | "d2c2": "#FFF", 106 | "d2c3": "#FFF", 107 | "d2c4": "#FFF", 108 | "d2c5": "#FFF", 109 | "hd2": 8, 110 | "md2": 30, 111 | "hn2": 21, 112 | "mn2": 30, 113 | "day_bright2": 66, 114 | "night_bright2": 30 115 | } 116 | -------------------------------------------------------------------------------- /data/default.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/default.htm.gz -------------------------------------------------------------------------------- /data/disp.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/disp.htm.gz -------------------------------------------------------------------------------- /data/disp2.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/disp2.htm.gz -------------------------------------------------------------------------------- /data/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/favicon.ico -------------------------------------------------------------------------------- /data/filesystem.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/filesystem.htm.gz -------------------------------------------------------------------------------- /data/index.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/index.htm.gz -------------------------------------------------------------------------------- /data/jquery.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/jquery.js.gz -------------------------------------------------------------------------------- /data/login.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/login.htm.gz -------------------------------------------------------------------------------- /data/network.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/network.htm.gz -------------------------------------------------------------------------------- /data/restart.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/restart.htm.gz -------------------------------------------------------------------------------- /data/segmend.ttf.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/segmend.ttf.gz -------------------------------------------------------------------------------- /data/segment.ttf.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/segment.ttf.gz -------------------------------------------------------------------------------- /data/sensors.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/sensors.htm.gz -------------------------------------------------------------------------------- /data/update.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/update.htm.gz -------------------------------------------------------------------------------- /data/user.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/user.htm.gz -------------------------------------------------------------------------------- /data/user.us: -------------------------------------------------------------------------------- 1 | {"user":"admin","pass":"1111"} -------------------------------------------------------------------------------- /data/weather.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/data/weather.htm.gz -------------------------------------------------------------------------------- /firmware/Clock_BIM_v3.3.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/firmware/Clock_BIM_v3.3.bin -------------------------------------------------------------------------------- /firmware/old_versions/Clock_BIM_v3.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/firmware/old_versions/Clock_BIM_v3.0.zip -------------------------------------------------------------------------------- /firmware/old_versions/Clock_BIM_v3.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/firmware/old_versions/Clock_BIM_v3.1.zip -------------------------------------------------------------------------------- /firmware/old_versions/Clock_BIM_v3.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/firmware/old_versions/Clock_BIM_v3.2.zip -------------------------------------------------------------------------------- /firmware/old_versions/clock2.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/firmware/old_versions/clock2.1.zip -------------------------------------------------------------------------------- /firmware/old_versions/clock_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/firmware/old_versions/clock_1.0.zip -------------------------------------------------------------------------------- /firmware/old_versions/clock_2.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/firmware/old_versions/clock_2.0.zip -------------------------------------------------------------------------------- /firmware/old_versions/clock_OTA_v1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/firmware/old_versions/clock_OTA_v1.1.zip -------------------------------------------------------------------------------- /firmware/old_versions/clock_v1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/firmware/old_versions/clock_v1.1.zip -------------------------------------------------------------------------------- /img/DS3231.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/DS3231.png -------------------------------------------------------------------------------- /img/clock2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/clock2.jpg -------------------------------------------------------------------------------- /img/clock3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/clock3.jpg -------------------------------------------------------------------------------- /img/clock4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/clock4.jpg -------------------------------------------------------------------------------- /img/clock5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/clock5.jpg -------------------------------------------------------------------------------- /img/clock6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/clock6.jpg -------------------------------------------------------------------------------- /img/clock7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/clock7.jpg -------------------------------------------------------------------------------- /img/clock_pcb_v1.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/clock_pcb_v1.1.png -------------------------------------------------------------------------------- /img/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/login.png -------------------------------------------------------------------------------- /img/sett.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/sett.png -------------------------------------------------------------------------------- /img/tm1637.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/tm1637.png -------------------------------------------------------------------------------- /img/wemos.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/wemos.jpg -------------------------------------------------------------------------------- /img/youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/img/youtube.png -------------------------------------------------------------------------------- /languages.h: -------------------------------------------------------------------------------- 1 | struct saved_text{ 2 | const char* saved; 3 | const char* not_saved; 4 | const char* old_pass; 5 | }; 6 | 7 | struct saved_text saved[10]={ 8 | "Saved", 9 | "Not saved", 10 | "Invalid old password", 11 | 12 | "Сохранено", 13 | "Не сохранено", 14 | "Неверный старый пароль", 15 | 16 | "Salvat", 17 | "Nu este salvat", 18 | "Parola veche nevalidă", 19 | 20 | "Gespeichert", 21 | "Nicht gespeichert", 22 | "Ungültiges altes Passwort", 23 | 24 | "Išsaugota", 25 | "Nepasaugotas", 26 | "Netinkamas senas slaptažodis", 27 | 28 | "Salvestatud", 29 | "Ei salvestatud", 30 | "Kehtetu vana parool", 31 | 32 | "Збережено", 33 | "Не збережено", 34 | "Невірний старий пароль", 35 | 36 | "Yadda saxlanıldı", 37 | "Yadda saxlanılmadı", 38 | "Yanlış köhnə parol", 39 | 40 | "Захавана", 41 | "Не захавана", 42 | "Няправільны стары пароль", 43 | 44 | "Запазено", 45 | "Незапазено", 46 | "Невалидна стара парола" 47 | }; 48 | -------------------------------------------------------------------------------- /libraries.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/libraries.zip -------------------------------------------------------------------------------- /pcb/Diptrace V3.0 TM1637-4.dip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/pcb/Diptrace V3.0 TM1637-4.dip -------------------------------------------------------------------------------- /pcb/Gerber V3.0 TM1637-4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/pcb/Gerber V3.0 TM1637-4.zip -------------------------------------------------------------------------------- /pcb/Sprint_layout v3.0 TM1637-4.lay6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/pcb/Sprint_layout v3.0 TM1637-4.lay6 -------------------------------------------------------------------------------- /schematic/ClockSchematicV1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/schematic/ClockSchematicV1.0.zip -------------------------------------------------------------------------------- /schematic/ClockSchematicV1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/schematic/ClockSchematicV1.1.zip -------------------------------------------------------------------------------- /schematic/clock_v1.0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/schematic/clock_v1.0.gif -------------------------------------------------------------------------------- /schematic/clock_v1.1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/schematic/clock_v1.1.gif -------------------------------------------------------------------------------- /schematic/clock_v2.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/schematic/clock_v2.0.png -------------------------------------------------------------------------------- /schematic/clock_v3.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/himikat123/Clock/7fe054bff66cb806a7cced04552d79a6ea3dffe5/schematic/clock_v3.0.png -------------------------------------------------------------------------------- /web.ino: -------------------------------------------------------------------------------- 1 | String getContentType(String filename){ 2 | if(webServer.hasArg("download")) return "application/octet-stream"; 3 | else if(filename.endsWith(".htm")) return "text/html"; 4 | else if(filename.endsWith(".html")) return "text/html"; 5 | else if(filename.endsWith(".css")) return "text/css"; 6 | else if(filename.endsWith(".js")) return "application/javascript"; 7 | else if(filename.endsWith(".json")) return "text/json"; 8 | else if(filename.endsWith(".png")) return "image/png"; 9 | else if(filename.endsWith(".gif")) return "image/gif"; 10 | else if(filename.endsWith(".jpg")) return "image/jpeg"; 11 | else if(filename.endsWith(".ico")) return "image/x-icon"; 12 | else if(filename.endsWith(".xml")) return "text/xml"; 13 | else if(filename.endsWith(".pdf")) return "application/x-pdf"; 14 | else if(filename.endsWith(".zip")) return "application/x-zip"; 15 | else if(filename.endsWith(".gz")) return "application/x-gzip"; 16 | return "text/plain"; 17 | } 18 | 19 | bool handleFileRead(String path){ 20 | //Serial.println(path); 21 | if(webServer.hasHeader("Cookie")){ 22 | String cookie = webServer.header("Cookie"); 23 | int8_t au = cookie.indexOf("auth"); 24 | uint8_t cook[10]; 25 | uint8_t coincid = 0; 26 | uint8_t code_auth[10]; 27 | ESP.rtcUserMemoryRead(0, (uint32_t*)&code_auth, 10); 28 | for(uint8_t i=0; i<10; i++){ 29 | cook[i] = (uint8_t)cookie[au + 5 + i] - 48; 30 | } 31 | for(uint8_t i=0; i<10; i++) if(code_auth[i] == cook[i]) coincid++; 32 | if(au != -1 and coincid == 10) return FileRead(path); 33 | else return FileRead("/login.htm"); 34 | } 35 | else return FileRead("/login.htm"); 36 | } 37 | 38 | bool FileRead(String path){ 39 | //Serial.println(path); 40 | if(path.endsWith("/")) path += "index.htm"; 41 | String contentType = getContentType(path); 42 | String pathWithGz = path + ".gz"; 43 | if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)){ 44 | if(SPIFFS.exists(pathWithGz)) path += ".gz"; 45 | //Serial.println(path); 46 | File file = SPIFFS.open(path, "r"); 47 | size_t sent = webServer.streamFile(file, contentType); 48 | file.close(); 49 | return true; 50 | } 51 | //Serial.println("No file found"); 52 | return false; 53 | } 54 | 55 | void handleFileUpload(void){ 56 | if(webServer.uri() != "/edit") return; 57 | HTTPUpload& upload = webServer.upload(); 58 | if(upload.status == UPLOAD_FILE_START){ 59 | String filename = upload.filename; 60 | if(!filename.startsWith("/")) filename = "/" + filename; 61 | fsUploadFile = SPIFFS.open(filename, "w"); 62 | filename = String(); 63 | } 64 | else if(upload.status == UPLOAD_FILE_WRITE){ 65 | if(fsUploadFile) fsUploadFile.write(upload.buf, upload.currentSize); 66 | } 67 | else if(upload.status == UPLOAD_FILE_END){ 68 | if(fsUploadFile) fsUploadFile.close(); 69 | } 70 | } 71 | 72 | String notFound = "HTTP 404 - File Not Found"; 73 | 74 | void web_settings(void){ 75 | webServer.on("/esp/save.php", HTTP_POST, [](){ 76 | String daten = webServer.arg("CONFIG"); 77 | File file = SPIFFS.open("/config.json", "w"); 78 | if(file){ 79 | file.print(daten); 80 | file.close(); 81 | webServer.send(200, "text/plain", "OK"); 82 | } 83 | else webServer.send(200, "text/plain", "ERROR"); 84 | }); 85 | //////////////////////////////////////////////////////////////////////// 86 | webServer.on("/esp/ssids.php", HTTP_GET, [](){ 87 | String json = "{"; 88 | uint8_t n = WiFi.scanNetworks(); 89 | for(uint8_t i=0; i