├── DSEG7Classic-BoldFont.h ├── README.md ├── WeatherStationFonts.h ├── WeatherStationImages.h ├── esp8266-weather-station-oled-DST.ino └── resources ├── 1-3_day_forecast.jpg ├── 4-6_day_forecast.jpg ├── Boston_EDT.jpg ├── DHT22_sensor.jpg ├── DHT22_update.jpg ├── Thumbs.db ├── Zurich_CET.jpg ├── conditions.jpg ├── cover.jpg ├── splash.jpg └── thingspeak.jpg /DSEG7Classic-BoldFont.h: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | [Name] 7-segment Font DSEG7 Family 3 | [Version] 0.30(2015.07.20) 4 | [File Type] Derived from TTF(True Type Font) 5 | [License] Free(See link for details) 6 | [Copyrights] Keshikan(http://www.keshikan.net/fonts-e.html) 7 | ******************************************************/ 8 | 9 | // Converted by FontConverterV3.java written by Squix78 http://oleddisplay.squix.ch/ Consider a donation 10 | // In case of problems make sure that you are using the font file with the correct version! 11 | const char DSEG7_Classic_Bold_21[] PROGMEM = { 12 | 0x11, // Width: 17 13 | 0x17, // Height: 23 14 | 0x20, // First Char: 32 15 | 0x1B, // Numbers of Chars: 27 16 | 17 | // Jump Table: 18 | 0xFF, 0xFF, 0x00, 0x04, // 32:65535 19 | 0x00, 0x00, 0x15, 0x08, // 33:0 20 | 0x00, 0x15, 0x15, 0x08, // 34:21 21 | 0x00, 0x2A, 0x15, 0x08, // 35:42 22 | 0x00, 0x3F, 0x15, 0x08, // 36:63 23 | 0x00, 0x54, 0x15, 0x08, // 37:84 24 | 0x00, 0x69, 0x15, 0x08, // 38:105 25 | 0x00, 0x7E, 0x15, 0x08, // 39:126 26 | 0x00, 0x93, 0x15, 0x08, // 40:147 27 | 0x00, 0xA8, 0x15, 0x08, // 41:168 28 | 0x00, 0xBD, 0x15, 0x08, // 42:189 29 | 0x00, 0xD2, 0x15, 0x08, // 43:210 30 | 0x00, 0xE7, 0x15, 0x08, // 44:231 31 | 0x00, 0xFC, 0x26, 0x11, // 45:252 32 | 0xFF, 0xFF, 0x00, 0x00, // 46:65535 33 | 0x01, 0x22, 0x15, 0x08, // 47:290 34 | 0x01, 0x37, 0x2D, 0x11, // 48:311 35 | 0x01, 0x64, 0x2D, 0x11, // 49:356 36 | 0x01, 0x91, 0x2C, 0x11, // 50:401 37 | 0x01, 0xBD, 0x2D, 0x11, // 51:445 38 | 0x01, 0xEA, 0x2D, 0x11, // 52:490 39 | 0x02, 0x17, 0x2D, 0x11, // 53:535 40 | 0x02, 0x44, 0x2D, 0x11, // 54:580 41 | 0x02, 0x71, 0x2D, 0x11, // 55:625 42 | 0x02, 0x9E, 0x2D, 0x11, // 56:670 43 | 0x02, 0xCB, 0x2D, 0x11, // 57:715 44 | 0x02, 0xF8, 0x09, 0x04, // 58:760 45 | 46 | // Font Data: 47 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 33 48 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 34 49 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 35 50 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 36 51 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 37 52 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 38 53 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 39 54 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 40 55 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 41 56 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 42 57 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 43 58 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 44 59 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x10, // 45 60 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 47 61 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xEF,0x5F,0xEC,0xC7,0x6F,0x1C,0x00,0x70,0x1C,0x00,0x70,0x1C,0x00,0x70,0x1C,0x00,0x70,0x1C,0x00,0x70,0x1C,0x00,0x70,0x1C,0x00,0x70,0xEC,0xC7,0x6F,0xF4,0xEF,0x5F,0xF8,0xEF,0x3F, // 48 62 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xC7,0x0F,0xF0,0xEF,0x1F,0xF8,0xEF,0x3F, // 49 63 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x3F,0x04,0xE0,0x5F,0x0C,0xD0,0x6F,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0xEC,0x17,0x60,0xF4,0x0F,0x40,0xF8,0x0F, // 50 64 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x40,0x0C,0x10,0x60,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0xEC,0xD7,0x6F,0xF4,0xEF,0x5F,0xF8,0xEF,0x3F, // 51 65 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF0,0x0F,0x00,0xE0,0x17,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0xE0,0xD7,0x0F,0xF0,0xEF,0x1F,0xF8,0xEF,0x3F, // 52 66 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x0F,0x40,0xEC,0x17,0x60,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x0C,0xD0,0x6F,0x04,0xE0,0x5F,0x00,0xE0,0x3F, // 53 67 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xEF,0x5F,0xEC,0xD7,0x6F,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x0C,0xD0,0x6F,0x04,0xE0,0x5F,0x00,0xE0,0x3F, // 54 68 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x0F,0x00,0xEC,0x07,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0xEC,0xC7,0x0F,0xF4,0xEF,0x1F,0xF8,0xEF,0x3F, // 55 69 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xEF,0x5F,0xEC,0xD7,0x6F,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0xEC,0xD7,0x6F,0xF4,0xEF,0x5F,0xF8,0xEF,0x3F, // 56 70 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x0F,0x40,0xEC,0x17,0x60,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0xEC,0xD7,0x6F,0xF4,0xEF,0x5F,0xF8,0xEF,0x3F, // 57 71 | 0x00,0x00,0x00,0x80,0x03,0x03,0x80,0x03,0x03 // 58 72 | }; 73 | 74 | // Created by http://oleddisplay.squix.ch/ Consider a donation 75 | // In case of problems make sure that you are using the font file with the correct version! 76 | const char DSEG7_Classic_Regular_21[] PROGMEM = { 77 | 0x11, // Width: 17 78 | 0x17, // Height: 23 79 | 0x20, // First Char: 32 80 | 0x1B, // Numbers of Chars: 27 81 | 82 | // Jump Table: 83 | 0xFF, 0xFF, 0x00, 0x04, // 32:65535 84 | 0x00, 0x00, 0x15, 0x08, // 33:0 85 | 0x00, 0x15, 0x15, 0x08, // 34:21 86 | 0x00, 0x2A, 0x15, 0x08, // 35:42 87 | 0x00, 0x3F, 0x15, 0x08, // 36:63 88 | 0x00, 0x54, 0x15, 0x08, // 37:84 89 | 0x00, 0x69, 0x15, 0x08, // 38:105 90 | 0x00, 0x7E, 0x15, 0x08, // 39:126 91 | 0x00, 0x93, 0x15, 0x08, // 40:147 92 | 0x00, 0xA8, 0x15, 0x08, // 41:168 93 | 0x00, 0xBD, 0x15, 0x08, // 42:189 94 | 0x00, 0xD2, 0x15, 0x08, // 43:210 95 | 0x00, 0xE7, 0x15, 0x08, // 44:231 96 | 0x00, 0xFC, 0x29, 0x11, // 45:252 97 | 0xFF, 0xFF, 0x00, 0x00, // 46:65535 98 | 0x01, 0x25, 0x15, 0x08, // 47:293 99 | 0x01, 0x3A, 0x2D, 0x11, // 48:314 100 | 0x01, 0x67, 0x2D, 0x11, // 49:359 101 | 0x01, 0x94, 0x2C, 0x11, // 50:404 102 | 0x01, 0xC0, 0x2D, 0x11, // 51:448 103 | 0x01, 0xED, 0x2D, 0x11, // 52:493 104 | 0x02, 0x1A, 0x2D, 0x11, // 53:538 105 | 0x02, 0x47, 0x2D, 0x11, // 54:583 106 | 0x02, 0x74, 0x2D, 0x11, // 55:628 107 | 0x02, 0xA1, 0x2D, 0x11, // 56:673 108 | 0x02, 0xCE, 0x2D, 0x11, // 57:718 109 | 0x02, 0xFB, 0x09, 0x04, // 58:763 110 | 111 | // Font Data: 112 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 33 113 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 34 114 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 35 115 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 36 116 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 37 117 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 38 118 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 39 119 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 40 120 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 41 121 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 42 122 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 43 123 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 44 124 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10, // 45 125 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 47 126 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xC7,0x5F,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0xF4,0xC7,0x5F,0xF8,0xEF,0x3F, // 48 127 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xC7,0x1F,0xF8,0xEF,0x3F, // 49 128 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x3F,0x04,0xD0,0x5F,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0xF4,0x17,0x40,0xF8,0x0F, // 50 129 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x40,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0xF4,0xD7,0x5F,0xF8,0xEF,0x3F, // 51 130 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF0,0x17,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0xF0,0xD7,0x1F,0xF8,0xEF,0x3F, // 52 131 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x17,0x40,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x04,0xD0,0x5F,0x00,0xE0,0x3F, // 53 132 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xD7,0x5F,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x04,0xD0,0x5F,0x00,0xE0,0x3F, // 54 133 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x07,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0xF4,0xC7,0x1F,0xF8,0xEF,0x3F, // 55 134 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xD7,0x5F,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0xF4,0xD7,0x5F,0xF8,0xEF,0x3F, // 56 135 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x17,0x40,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0xF4,0xD7,0x5F,0xF8,0xEF,0x3F, // 57 136 | 0x00,0x00,0x00,0x80,0x03,0x03,0x80,0x03,0x03 // 58 137 | }; 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # esp8266-weather-station-OLED-DST 2 | 3 | Daylight Saving Time and other customizations of Squix78 ESP8266 OLED Weather Station. 4 | Uses SSD1306 128x64 OLED display with with either SPI or I2C interface 5 | 6 | | New Splash Screen | DHT22 Update | 7 | |:-----------------:|:------------:| 8 | | ![cover](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/splash.jpg) | ![DHT22 Update](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/DHT22_update.jpg) | 9 | 10 | | Zurich Standard Time | Boston Daylight Saving Time | Conditions Screen | 11 | |:--------------------:|:---------------------------:|:-----------------:| 12 | | ![Zurich CET](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/Zurich_CET.jpg) | ![Boston EDT](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/Boston_EDT.jpg) | ![Conditions](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/conditions.jpg) | 13 | 14 | | DHT Sensor | Thingspeak Sensor | 1 to 3 Day Forecast | 4 to 6 Day Forecast | 15 | |:----------:|:-----------------:|:-------------------:|:-------------------:| 16 | | ![DHT Sensor](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/DHT22_sensor.jpg) | ![ThingSpeak Sensor](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/thingspeak.jpg) | ![DHT Sensor](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/1-3_day_forecast.jpg) | ![ThingSpeak Sensor](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/4-6_day_forecast.jpg) | 17 | 18 | ## Specific customizations include: 19 | 20 | * Added Wifi Splash screen and credit to Squix78 21 | * Modified progress bar to a thicker and symmetrical shape 22 | * Replaced TimeClient with built-in lwip sntp client (no need for external ntp client library) 23 | * Added Daylight Saving Time Auto adjuster with DST rules using simpleDSTadjust library 24 | * https://github.com/neptune2/simpleDSTadjust 25 | * Added Locale Setting examples for Boston, Zurich and Sydney 26 | * Selectable NTP servers for each locale 27 | * DST rules and timezone settings customizable for each locale 28 | * See https://www.timeanddate.com/time/change/ for DST rules 29 | * Added AM/PM or 24-hour option for each locale 30 | * Changed Clock screen to 7-segment font from http://www.keshikan.net/fonts-e.html 31 | * Added Forecast screen for days 4-6 32 | * **>>> Need to change WundergroundClient.h in ESP8266_Weather_Station library** 33 | * `#define MAX_FORECAST_PERIODS 12 // Was 7` 34 | * Added support for DHT22 Indoor Temperature and Humidity 35 | * Fixed bug preventing display.flipScreenVertically() from working 36 | * Slight adjustment to overlay 37 | 38 | ## Bug Fixes include: 39 | 40 | * Fixed ticker overwrite bug: Split DHT and Wunderground timed updates out to 2 tickers. Thanks @charonofssi 41 | 42 | ## Hardware Requirements 43 | 44 | This code is made for an 128x64 SSD1603 OLED display with code running on an ESP8266. 45 | Either the SPI or I2C version can be used. 46 | You can buy the original Squix78 Weather Station Kit here: 47 | [Squix Shop](https://shop.squix.ch/index.php/esp8266.html) or here: [US Amazon store](https://www.amazon.com/gp/product/B01KE7BA3O) 48 | 49 | ## Software Requirements/ Libraries 50 | 51 | * [Arduino IDE with ESP8266 platform installed](https://github.com/esp8266/Arduino) 52 | * [Weather Station Library](https://github.com/squix78/esp8266-weather-station) or through Library Manager 53 | * [ESP8266 OLED SSD1306 Library](https://github.com/squix78/esp8266-oled-ssd1306) 54 | * [WifiManager Library](https://github.com/tzapu/WiFiManager) 55 | * [DHT Sensor Library](https://github.com/adafruit/DHT-sensor-library) 56 | 57 | ### Additional required library for automatic Daylight Saving Time adjust 58 | * [simpleDSTadjust Library](https://github.com/neptune2/simpleDSTadjust) 59 | 60 | You also need to get an API key for the Wunderground data: https://www.wunderground.com/ 61 | 62 | ## Wemos D1R2 Wiring 63 | ![Wemos D1R2 and DHT22 sensor](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/cover.jpg) 64 | 65 | See code for pin configurations 66 | 67 | | SSD1306 SPI | Wemos D1R2 | 68 | | ----------- |:----------:| 69 | | CS | D8 | 70 | | DC | D2 | 71 | | RST | D0 | 72 | | D1 | D7 | 73 | | D0 | D5 | 74 | | GND | GND | 75 | | VCC | 3V3 | 76 | 77 | | DHT22 | Wemos D1R2 | 78 | | ----- |:----------:| 79 | | DATA | D4 | 80 | | GND | GND | 81 | | VCC | 3V3 | 82 | -------------------------------------------------------------------------------- /WeatherStationImages.h: -------------------------------------------------------------------------------- 1 | #define WiFi_Logo_width 60 2 | #define WiFi_Logo_height 36 3 | const char WiFi_Logo_bits[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 7 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 9 | 0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 10 | 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 11 | 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 12 | 0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C, 13 | 0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00, 14 | 0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C, 15 | 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00, 16 | 0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 17 | 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 18 | 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C, 19 | 0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00, 20 | 0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F, 21 | 0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00, 22 | 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 23 | 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 24 | 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 25 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | }; 29 | 30 | const char emptySymbol[] PROGMEM = { 31 | B00000000, 32 | B00000000, 33 | B00000000, 34 | B00000000, 35 | B00000000, 36 | B00000000, 37 | B00000000, 38 | B00000000 39 | }; 40 | 41 | const char activeSymbol[] PROGMEM = { 42 | B00000000, 43 | B00000000, 44 | B00011000, 45 | B00100100, 46 | B01000010, 47 | B01000010, 48 | B00100100, 49 | B00011000 50 | }; 51 | 52 | const char inactiveSymbol[] PROGMEM = { 53 | B00000000, 54 | B00000000, 55 | B00000000, 56 | B00000000, 57 | B00011000, 58 | B00011000, 59 | B00000000, 60 | B00000000 61 | }; 62 | -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST.ino: -------------------------------------------------------------------------------- 1 | /**The MIT License (MIT) 2 | 3 | Copyright (c) 2016 by Daniel Eichhorn 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. 22 | 23 | See more at http://blog.squix.ch 24 | */ 25 | 26 | /* Customizations by Neptune (NeptuneEng on Twitter, Neptune2 on Github) 27 | * 28 | * Version 1.0.1 - Bugfix 29 | * - Added Missing I2C variables 30 | * 31 | * Version 1.0.0 - Bugfix 32 | * - Fixed ticker overwrite bug: Split DHT and Wunderground timed updates out to 2 tickers. Thanks @charonofssi 33 | * 34 | * Version 0.1.0 - Initial Released Version 35 | * Added Wifi Splash screen and credit to Squix78 36 | * Modified progress bar to a thicker and symmetrical shape 37 | * Replaced TimeClient with built-in lwip sntp client (no need for external ntp client library) 38 | * Added Daylight Saving Time Auto adjuster with DST rules using simpleDSTadjust library 39 | * https://github.com/neptune2/simpleDSTadjust 40 | * Added Setting examples for Boston, Zurich and Sydney 41 | * Selectable NTP servers for each locale 42 | * DST rules and timezone settings customizable for each locale 43 | * See https://www.timeanddate.com/time/change/ for DST rules 44 | * Added AM/PM or 24-hour option for each locale 45 | * Changed to 7-segment Clock font from http://www.keshikan.net/fonts-e.html 46 | * Added Forecast screen for days 4-6 47 | * >>> Need to change WundergroundClient.h in ESP8266_Weather_Station library 48 | * #define MAX_FORECAST_PERIODS 12 // Was 7 49 | * Added support for DHT22 Indoor Temperature and Humidity 50 | * Fixed bug preventing display.flipScreenVertically() from working 51 | * Slight adjustment to overlay 52 | */ 53 | 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | 60 | #include 61 | #include 62 | #include 63 | 64 | // #include "SSD1306Wire.h" 65 | // #include // Only needed for Arduino 1.6.5 and earlier 66 | #include "SSD1306Spi.h" 67 | #include "OLEDDisplayUi.h" 68 | // #include "Wire.h" 69 | #include "WundergroundClient.h" 70 | #include "WeatherStationFonts.h" 71 | #include "WeatherStationImages.h" 72 | #include "DSEG7Classic-BoldFont.h" 73 | #include 74 | #include "DHT.h" 75 | #include "ThingspeakClient.h" 76 | #include 77 | 78 | 79 | /*************************** 80 | * Begin Settings 81 | **************************/ 82 | // Please read http://blog.squix.org/weatherstation-getting-code-adapting-it 83 | // for setup instructions 84 | 85 | #define HOSTNAME "ESP8266-OTA-" 86 | 87 | // Setup 88 | const int UPDATE_INTERVAL_SECS = 30 + (10 * 60); // Update every 10.5 minutes 89 | 90 | // Display Settings 91 | // Pin definitions for I2C OLED 92 | const int I2C_DISPLAY_ADDRESS = 0x3c; 93 | // const int SDA_PIN = 0; 94 | // const int SDC_PIN = 2; 95 | const int SDA_PIN = D2; 96 | const int SDC_PIN = D4; 97 | 98 | // Pin definitions for SPI OLED 99 | #define OLED_CS D8 // Chip select 100 | #define OLED_DC D2 // Data/Command 101 | #define OLED_RESET D0 // RESET 102 | 103 | // DHT Settings 104 | // #define DHTPIN D2 // NodeMCU 105 | #define DHTPIN D4 // Wemos D1R2 Mini 106 | #define DHTTYPE DHT22 // DHT22 (AM2302), AM2321 107 | char FormattedTemperature[10]; 108 | char FormattedHumidity[10]; 109 | 110 | // ----------------------------------- 111 | // Locales (uncomment only 1) 112 | #define Zurich 113 | //#define Boston 114 | // #define Sydney 115 | //------------------------------------ 116 | 117 | #ifdef Zurich 118 | //DST rules for Central European Time Zone 119 | #define UTC_OFFSET +1 120 | struct dstRule StartRule = {"CEST", Last, Sun, Mar, 2, 3600}; // Central European Summer Time = UTC/GMT +2 hours 121 | struct dstRule EndRule = {"CET", Last, Sun, Oct, 2, 0}; // Central European Time = UTC/GMT +1 hour 122 | 123 | // Uncomment for 24 Hour style clock 124 | #define STYLE_24HR 125 | 126 | #define NTP_SERVERS "0.ch.pool.ntp.org", "1.ch.pool.ntp.org", "2.ch.pool.ntp.org" 127 | 128 | // Wunderground Settings 129 | const boolean IS_METRIC = true; 130 | const String WUNDERGRROUND_API_KEY = ""; 131 | const String WUNDERGRROUND_LANGUAGE = "EN"; 132 | const String WUNDERGROUND_COUNTRY = "CH"; 133 | const String WUNDERGROUND_CITY = "Zurich"; 134 | #endif 135 | 136 | #ifdef Boston 137 | //DST rules for US Eastern Time Zone (New York, Boston) 138 | #define UTC_OFFSET -5 139 | struct dstRule StartRule = {"EDT", Second, Sun, Mar, 2, 3600}; // Eastern Daylight time = UTC/GMT -4 hours 140 | struct dstRule EndRule = {"EST", First, Sun, Nov, 1, 0}; // Eastern Standard time = UTC/GMT -5 hour 141 | 142 | // Uncomment for 24 Hour style clock 143 | //#define STYLE_24HR 144 | 145 | #define NTP_SERVERS "us.pool.ntp.org", "time.nist.gov", "pool.ntp.org" 146 | 147 | // Wunderground Settings 148 | const boolean IS_METRIC = false; 149 | const String WUNDERGRROUND_API_KEY = ""; 150 | const String WUNDERGRROUND_LANGUAGE = "EN"; 151 | const String WUNDERGROUND_COUNTRY = "MA"; 152 | const String WUNDERGROUND_CITY = "Boston"; 153 | #endif 154 | 155 | #ifdef Sydney 156 | //DST Rules for Australia Eastern Time Zone (Sydney) 157 | #define UTC_OFFSET +10 158 | struct dstRule StartRule = {"AEDT", First, Sun, Oct, 2, 3600}; // Australia Eastern Daylight time = UTC/GMT +11 hours 159 | struct dstRule EndRule = {"AEST", First, Sun, Apr, 2, 0}; // Australia Eastern Standard time = UTC/GMT +10 hour 160 | 161 | // Uncomment for 24 Hour style clock 162 | //#define STYLE_24HR 163 | 164 | #define NTP_SERVERS "0.au.pool.ntp.org", "1.au.pool.ntp.org", "2.au.pool.ntp.org" 165 | 166 | // Wunderground Settings 167 | const boolean IS_METRIC = true; 168 | const String WUNDERGRROUND_API_KEY = ""; 169 | const String WUNDERGRROUND_LANGUAGE = "EN"; 170 | const String WUNDERGROUND_COUNTRY = "AU"; 171 | const String WUNDERGROUND_CITY = "Sydney"; 172 | #endif 173 | 174 | //Thingspeak Settings 175 | const String THINGSPEAK_CHANNEL_ID = "67284"; 176 | const String THINGSPEAK_API_READ_KEY = "L2VIW20QVNZJBLAK"; 177 | 178 | // Initialize the I2 oled display for address 0x3c 179 | // sda-pin=14 and sdc-pin=12 180 | // SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN); 181 | 182 | // SPI OLED 183 | SSD1306Spi display(OLED_RESET, OLED_DC, OLED_CS); 184 | 185 | OLEDDisplayUi ui( &display ); 186 | 187 | // Setup simpleDSTadjust Library rules 188 | simpleDSTadjust dstAdjusted(StartRule, EndRule); 189 | 190 | /*************************** 191 | * End Settings 192 | **************************/ 193 | 194 | // TimeClient timeClient(UTC_OFFSET); 195 | 196 | // Set to false, if you prefere imperial/inches, Fahrenheit 197 | WundergroundClient wunderground(IS_METRIC); 198 | 199 | // Initialize the temperature/ humidity sensor 200 | DHT dht(DHTPIN, DHTTYPE); 201 | float humidity = 0.0; 202 | float temperature = 0.0; 203 | 204 | ThingspeakClient thingspeak; 205 | 206 | // flag changed in the ticker function every 10 minutes 207 | bool readyForWeatherUpdate = false; 208 | // flag changed in the ticker function every 1 minute 209 | bool readyForDHTUpdate = false; 210 | 211 | String lastUpdate = "--"; 212 | 213 | Ticker ticker1, ticker2; 214 | 215 | //declaring prototypes 216 | void configModeCallback (WiFiManager *myWiFiManager); 217 | void drawProgress(OLEDDisplay *display, int percentage, String label); 218 | void drawOtaProgress(unsigned int, unsigned int); 219 | void updateData(OLEDDisplay *display); 220 | void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 221 | void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 222 | void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 223 | void drawForecast2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 224 | void drawIndoor(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 225 | void drawThingspeak(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 226 | void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex); 227 | void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state); 228 | void setReadyForWeatherUpdate(); 229 | int8_t getWifiQuality(); 230 | 231 | 232 | // Add frames 233 | // this array keeps function pointers to all frames 234 | // frames are the single views that slide from right to left 235 | FrameCallback frames[] = { drawDateTime, drawCurrentWeather, drawIndoor, drawThingspeak, drawForecast, drawForecast2 }; 236 | int numberOfFrames = 6; 237 | 238 | OverlayCallback overlays[] = { drawHeaderOverlay }; 239 | int numberOfOverlays = 1; 240 | 241 | void setup() { 242 | // Turn On VCC 243 | // pinMode(D4, OUTPUT); 244 | // digitalWrite(D4, HIGH); 245 | Serial.begin(115200); 246 | 247 | // initialize dispaly 248 | display.init(); 249 | display.clear(); 250 | display.display(); 251 | 252 | display.flipScreenVertically(); // Comment out to flip display 180deg 253 | display.setFont(ArialMT_Plain_10); 254 | display.setTextAlignment(TEXT_ALIGN_CENTER); 255 | display.setContrast(255); 256 | 257 | // Credit where credit is due 258 | display.drawXbm(-6, 5, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits); 259 | display.drawString(88, 18, "Weather Station\nBy Squix78\nmods by Neptune"); 260 | display.display(); 261 | 262 | //WiFiManager 263 | //Local intialization. Once its business is done, there is no need to keep it around 264 | WiFiManager wifiManager; 265 | // Uncomment for testing wifi manager 266 | // wifiManager.resetSettings(); 267 | wifiManager.setAPCallback(configModeCallback); 268 | 269 | //or use this for auto generated name ESP + ChipID 270 | wifiManager.autoConnect(); 271 | 272 | //Manual Wifi 273 | // WiFi.begin(SSID, PASSWORD); 274 | String hostname(HOSTNAME); 275 | hostname += String(ESP.getChipId(), HEX); 276 | WiFi.hostname(hostname); 277 | 278 | 279 | int counter = 0; 280 | while (WiFi.status() != WL_CONNECTED) { 281 | delay(500); 282 | Serial.print("."); 283 | display.clear(); 284 | display.drawString(64, 10, "Connecting to WiFi"); 285 | display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbol : inactiveSymbol); 286 | display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbol : inactiveSymbol); 287 | display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbol : inactiveSymbol); 288 | display.display(); 289 | 290 | counter++; 291 | } 292 | 293 | ui.setTargetFPS(30); 294 | ui.setTimePerFrame(10*1000); // Setup frame display time to 10 sec 295 | 296 | //Hack until disableIndicator works: 297 | //Set an empty symbol 298 | ui.setActiveSymbol(emptySymbol); 299 | ui.setInactiveSymbol(emptySymbol); 300 | 301 | ui.disableIndicator(); 302 | 303 | // You can change the transition that is used 304 | // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN 305 | ui.setFrameAnimation(SLIDE_LEFT); 306 | 307 | ui.setFrames(frames, numberOfFrames); 308 | 309 | ui.setOverlays(overlays, numberOfOverlays); 310 | 311 | // Inital UI takes care of initalising the display too. 312 | // ui.init(); // not necessary - already done above, breaks flipScreenVertically() 313 | 314 | // Setup OTA 315 | Serial.println("Hostname: " + hostname); 316 | ArduinoOTA.setHostname((const char *)hostname.c_str()); 317 | ArduinoOTA.onProgress(drawOtaProgress); 318 | ArduinoOTA.begin(); 319 | 320 | updateData(&display); 321 | 322 | ticker1.attach(UPDATE_INTERVAL_SECS, setReadyForWeatherUpdate); 323 | ticker2.attach(60, setReadyForDHTUpdate); 324 | } 325 | 326 | void loop() { 327 | 328 | if (readyForWeatherUpdate && ui.getUiState()->frameState == FIXED) { 329 | updateData(&display); 330 | } 331 | 332 | if (readyForDHTUpdate && ui.getUiState()->frameState == FIXED) 333 | updateDHT(); 334 | 335 | int remainingTimeBudget = ui.update(); 336 | 337 | if (remainingTimeBudget > 0) { 338 | // You can do some work here 339 | // Don't do stuff if you are below your 340 | // time budget. 341 | ArduinoOTA.handle(); 342 | delay(remainingTimeBudget); 343 | } 344 | 345 | } 346 | 347 | void configModeCallback (WiFiManager *myWiFiManager) { 348 | Serial.println("Entered config mode"); 349 | Serial.println(WiFi.softAPIP()); 350 | //if you used auto generated SSID, print it 351 | Serial.println(myWiFiManager->getConfigPortalSSID()); 352 | display.clear(); 353 | display.setTextAlignment(TEXT_ALIGN_CENTER); 354 | display.setFont(ArialMT_Plain_10); 355 | display.drawString(64, 10, "Wifi Manager"); 356 | display.drawString(64, 20, "Please connect to AP"); 357 | display.drawString(64, 30, myWiFiManager->getConfigPortalSSID()); 358 | display.drawString(64, 40, "To setup Wifi Configuration"); 359 | display.display(); 360 | } 361 | 362 | void drawProgress(OLEDDisplay *display, int percentage, String label) { 363 | display->clear(); 364 | display->setTextAlignment(TEXT_ALIGN_CENTER); 365 | display->setFont(ArialMT_Plain_10); 366 | display->drawString(64, 10, label); 367 | display->drawProgressBar(2, 28, 124, 12, percentage); 368 | display->display(); 369 | } 370 | 371 | void drawOtaProgress(unsigned int progress, unsigned int total) { 372 | display.clear(); 373 | display.setTextAlignment(TEXT_ALIGN_CENTER); 374 | display.setFont(ArialMT_Plain_10); 375 | display.drawString(64, 10, "OTA Update"); 376 | display.drawProgressBar(2, 28, 124, 12, progress / (total / 100)); 377 | display.display(); 378 | } 379 | 380 | void updateData(OLEDDisplay *display) { 381 | drawProgress(display, 10, "Updating time..."); 382 | configTime(UTC_OFFSET * 3600, 0, NTP_SERVERS); 383 | drawProgress(display, 30, "Updating conditions..."); 384 | wunderground.updateConditions(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY); 385 | drawProgress(display, 50, "Updating forecasts..."); 386 | wunderground.updateForecast(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY); 387 | 388 | drawProgress(display, 70, "Updating DHT Sensor"); 389 | humidity = dht.readHumidity(); 390 | drawProgress(display, 80, "Updating DHT Sensor"); 391 | temperature = dht.readTemperature(!IS_METRIC); 392 | delay(500); 393 | 394 | drawProgress(display, 90, "Updating thingspeak..."); 395 | thingspeak.getLastChannelItem(THINGSPEAK_CHANNEL_ID, THINGSPEAK_API_READ_KEY); 396 | readyForWeatherUpdate = false; 397 | drawProgress(display, 100, "Done..."); 398 | delay(1000); 399 | } 400 | 401 | // Called every 1 minute 402 | void updateDHT() { 403 | humidity = dht.readHumidity(); 404 | temperature = dht.readTemperature(!IS_METRIC); 405 | readyForDHTUpdate = false; 406 | } 407 | 408 | 409 | void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 410 | char *dstAbbrev; 411 | char time_str[11]; 412 | time_t now = dstAdjusted.time(&dstAbbrev); 413 | struct tm * timeinfo = localtime (&now); 414 | 415 | display->setTextAlignment(TEXT_ALIGN_CENTER); 416 | display->setFont(ArialMT_Plain_10); 417 | String date = ctime(&now); 418 | date = date.substring(0,11) + String(1900+timeinfo->tm_year); 419 | int textWidth = display->getStringWidth(date); 420 | display->drawString(64 + x, 5 + y, date); 421 | display->setFont(DSEG7_Classic_Bold_21); 422 | display->setTextAlignment(TEXT_ALIGN_RIGHT); 423 | 424 | #ifdef STYLE_24HR 425 | sprintf(time_str, "%02d:%02d:%02d\n",timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); 426 | display->drawString(108 + x, 19 + y, time_str); 427 | #else 428 | int hour = (timeinfo->tm_hour+11)%12+1; // take care of noon and midnight 429 | sprintf(time_str, "%2d:%02d:%02d\n",hour, timeinfo->tm_min, timeinfo->tm_sec); 430 | display->drawString(101 + x, 19 + y, time_str); 431 | #endif 432 | 433 | display->setTextAlignment(TEXT_ALIGN_LEFT); 434 | display->setFont(ArialMT_Plain_10); 435 | #ifdef STYLE_24HR 436 | sprintf(time_str, "%s", dstAbbrev); 437 | display->drawString(108 + x, 27 + y, time_str); // Known bug: Cuts off 4th character of timezone abbreviation 438 | #else 439 | sprintf(time_str, "%s\n%s", dstAbbrev, timeinfo->tm_hour>=12?"pm":"am"); 440 | display->drawString(102 + x, 18 + y, time_str); 441 | #endif 442 | 443 | } 444 | 445 | void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 446 | display->setFont(ArialMT_Plain_10); 447 | display->setTextAlignment(TEXT_ALIGN_LEFT); 448 | display->drawString(60 + x, 5 + y, wunderground.getWeatherText()); 449 | 450 | display->setFont(ArialMT_Plain_24); 451 | String temp = wunderground.getCurrentTemp() + (IS_METRIC ? "°C": "°F"); 452 | 453 | display->drawString(60 + x, 15 + y, temp); 454 | int tempWidth = display->getStringWidth(temp); 455 | 456 | display->setFont(Meteocons_Plain_42); 457 | String weatherIcon = wunderground.getTodayIcon(); 458 | int weatherIconWidth = display->getStringWidth(weatherIcon); 459 | display->drawString(32 + x - weatherIconWidth / 2, 05 + y, weatherIcon); 460 | } 461 | 462 | 463 | void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 464 | drawForecastDetails(display, x, y, 0); 465 | drawForecastDetails(display, x + 44, y, 2); 466 | drawForecastDetails(display, x + 88, y, 4); 467 | } 468 | 469 | void drawForecast2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 470 | drawForecastDetails(display, x, y, 6); 471 | drawForecastDetails(display, x + 44, y, 8); 472 | drawForecastDetails(display, x + 88, y, 10); 473 | } 474 | 475 | void drawIndoor(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 476 | display->setTextAlignment(TEXT_ALIGN_CENTER); 477 | display->setFont(ArialMT_Plain_10); 478 | display->drawString(64 + x, 0, "DHT22 Indoor Sensor"); 479 | display->setFont(ArialMT_Plain_16); 480 | dtostrf(temperature,4, 1, FormattedTemperature); 481 | display->drawString(64+x, 12, "Temp: " + String(FormattedTemperature) + (IS_METRIC ? "°C": "°F")); 482 | dtostrf(humidity,4, 1, FormattedHumidity); 483 | display->drawString(64+x, 30, "Humidity: " + String(FormattedHumidity) + "%"); 484 | 485 | } 486 | 487 | void drawThingspeak(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 488 | display->setTextAlignment(TEXT_ALIGN_CENTER); 489 | display->setFont(ArialMT_Plain_10); 490 | display->drawString(64 + x, 0 + y, "Thingspeak Sensor"); 491 | display->setFont(ArialMT_Plain_16); 492 | display->drawString(64 + x, 12 + y, thingspeak.getFieldValue(0) + "°C"); 493 | // display->drawString(64 + x, 12 + y, thingspeak.getFieldValue(0) + (IS_METRIC ? "°C": "°F")); // Needs code to convert Thingspeak temperature string 494 | display->drawString(64 + x, 30 + y, thingspeak.getFieldValue(1) + "%"); 495 | } 496 | 497 | void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex) { 498 | display->setTextAlignment(TEXT_ALIGN_CENTER); 499 | display->setFont(ArialMT_Plain_10); 500 | String day = wunderground.getForecastTitle(dayIndex).substring(0, 3); 501 | day.toUpperCase(); 502 | display->drawString(x + 20, y, day); 503 | 504 | display->setFont(Meteocons_Plain_21); 505 | display->drawString(x + 20, y + 12, wunderground.getForecastIcon(dayIndex)); 506 | 507 | display->setFont(ArialMT_Plain_10); 508 | display->drawString(x + 20, y + 34, wunderground.getForecastLowTemp(dayIndex) + "|" + wunderground.getForecastHighTemp(dayIndex)); 509 | display->setTextAlignment(TEXT_ALIGN_LEFT); 510 | } 511 | 512 | void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) { 513 | char time_str[11]; 514 | time_t now = dstAdjusted.time(nullptr); 515 | struct tm * timeinfo = localtime (&now); 516 | 517 | display->setFont(ArialMT_Plain_10); 518 | 519 | #ifdef STYLE_24HR 520 | sprintf(time_str, "%02d:%02d:%02d\n",timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); 521 | #else 522 | int hour = (timeinfo->tm_hour+11)%12+1; // take care of noon and midnight 523 | sprintf(time_str, "%2d:%02d:%02d%s\n",hour, timeinfo->tm_min, timeinfo->tm_sec, timeinfo->tm_hour>=12?"pm":"am"); 524 | #endif 525 | 526 | display->setTextAlignment(TEXT_ALIGN_LEFT); 527 | display->drawString(5, 52, time_str); 528 | 529 | display->setTextAlignment(TEXT_ALIGN_CENTER); 530 | String temp = wunderground.getCurrentTemp() + (IS_METRIC ? "°C": "°F"); 531 | display->drawString(101, 52, temp); 532 | 533 | int8_t quality = getWifiQuality(); 534 | for (int8_t i = 0; i < 4; i++) { 535 | for (int8_t j = 0; j < 2 * (i + 1); j++) { 536 | if (quality > i * 25 || j == 0) { 537 | display->setPixel(120 + 2 * i, 61 - j); 538 | } 539 | } 540 | } 541 | 542 | 543 | display->setTextAlignment(TEXT_ALIGN_CENTER); 544 | display->setFont(Meteocons_Plain_10); 545 | String weatherIcon = wunderground.getTodayIcon(); 546 | int weatherIconWidth = display->getStringWidth(weatherIcon); 547 | // display->drawString(64, 55, weatherIcon); 548 | display->drawString(77, 53, weatherIcon); 549 | 550 | display->drawHorizontalLine(0, 51, 128); 551 | 552 | } 553 | 554 | // converts the dBm to a range between 0 and 100% 555 | int8_t getWifiQuality() { 556 | int32_t dbm = WiFi.RSSI(); 557 | if(dbm <= -100) { 558 | return 0; 559 | } else if(dbm >= -50) { 560 | return 100; 561 | } else { 562 | return 2 * (dbm + 100); 563 | } 564 | } 565 | 566 | void setReadyForWeatherUpdate() { 567 | Serial.println("Setting readyForUpdate to true"); 568 | readyForWeatherUpdate = true; 569 | } 570 | 571 | void setReadyForDHTUpdate() { 572 | Serial.println("Setting readyForDHTUpdate to true"); 573 | readyForDHTUpdate = true; 574 | } 575 | 576 | -------------------------------------------------------------------------------- /resources/1-3_day_forecast.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/1-3_day_forecast.jpg -------------------------------------------------------------------------------- /resources/4-6_day_forecast.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/4-6_day_forecast.jpg -------------------------------------------------------------------------------- /resources/Boston_EDT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/Boston_EDT.jpg -------------------------------------------------------------------------------- /resources/DHT22_sensor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/DHT22_sensor.jpg -------------------------------------------------------------------------------- /resources/DHT22_update.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/DHT22_update.jpg -------------------------------------------------------------------------------- /resources/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/Thumbs.db -------------------------------------------------------------------------------- /resources/Zurich_CET.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/Zurich_CET.jpg -------------------------------------------------------------------------------- /resources/conditions.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/conditions.jpg -------------------------------------------------------------------------------- /resources/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/cover.jpg -------------------------------------------------------------------------------- /resources/splash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/splash.jpg -------------------------------------------------------------------------------- /resources/thingspeak.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neptune2/esp8266-weather-station-oled-DST/120ffecf4b60b5e778777dba77f03ef2b7a887a6/resources/thingspeak.jpg --------------------------------------------------------------------------------