Showing 10 changed files with 821 additions and 0 deletions
+123
DHT.ino
... ...
@@ -0,0 +1,123 @@
1
+
2
+#ifndef ARDUINO_ESP8266_WEMOS_D1MINI
3
+  #ifndef ARDUINO_ESP8266_WEMOS_D1R1
4
+    error "Board Must be /LOLIN(WEMOS) D1 R2 & Mini/ OR /Wemos D1 R1/"
5
+  #endif //ARDUINO_ESP8266_WEMOS_D1R1
6
+#endif //ARDUINO_ESP8266_WEMOS_D1MINI
7
+
8
+//---------------------------------------------------------------------
9
+//Note:
10
+//---------------------------------------------------------------------
11
+// ARDUINO_ESP8266_WEMOS_D1MINI :
12
+// - ESP DevBoard with onboard direct connector for DHT & OLED
13
+// - ESP Devboard with no screen
14
+// ARDUINO_ESP8266_WEMOS_D1R1
15
+// - ESP DevBoard with Battery holder
16
+//---------------------------------------------------------------------
17
+
18
+// My Includes
19
+#include <dummy.h>
20
+#include <ESP8266WiFi.h>
21
+//#include <ESP8266WebServer.h>
22
+#include <DHT.h>
23
+#include <ArduinoOTA.h>
24
+
25
+#include "my_constants.h"
26
+#include "my_draw.h"
27
+#include "my_wifi.h"
28
+#include "my_dht.h"
29
+#include "my_ntp.h"
30
+#include "my_isr.h"
31
+
32
+
33
+#ifdef USE_OTA
34
+#include "my_ota.h"
35
+#endif //USE_OTA
36
+
37
+#ifdef USE_MQTT
38
+#include "my_mqtt.h"
39
+#endif //USE_MQTT
40
+
41
+#include "my_http.h"
42
+
43
+
44
+void setup() {
45
+  Serial.begin(115200);
46
+  Serial.setDebugOutput(true);
47
+  Serial.println();
48
+
49
+  Serial.println("Initialization Screen");
50
+  drawInit();
51
+  draw(compile_time, NOLOGO, 0, 0);
52
+  
53
+  Serial.println("Initialization DHT");
54
+  dht.begin();
55
+  Serial.println("Initialization WIFI");
56
+  WiFiConnect();
57
+
58
+  // Sync clock
59
+  if( WiFi.status() == WL_CONNECTED ) {
60
+    setClock();
61
+    sprintf(clientID,clientIDFmt,WiFi.macAddress().c_str());
62
+#ifdef USE_MQTT
63
+    mqtt_connect();
64
+#endif //USE_MQTT
65
+  }
66
+  Serial.println("BuildDate:["+String(compile_date)+"]");
67
+  ota_set();
68
+  
69
+#ifdef ARDUINO_ESP8266_WEMOS_D1MINI
70
+  digitalWrite(LED_BUILTIN, LOW);
71
+#endif //ARDUINO_ESP8266_WEMOS_D1MINI
72
+
73
+  Serial.println("Initialization HTTP server on port "+String(PORT));
74
+  http_set();
75
+
76
+  isr_set();
77
+
78
+  delay(1000);
79
+  displaySetStatus(0);
80
+}
81
+
82
+// the loop function runs over and over again forever
83
+void loop() {
84
+  ArduinoOTA.handle();
85
+  unsigned long time;
86
+  time = millis();
87
+  if (time - timeSinceLastModeSwitch > UPDATE_PERIOD) {
88
+  #ifdef HAS_DHT
89
+    float mT = readDHTTemperature();
90
+    float mH = readDHTHumidity();
91
+    String dispMsg = String(mT)+" | "+String(mH)+"%";
92
+    countMeasures++;
93
+    getTimeString();
94
+    #ifdef USE_MQTT
95
+    mqtt_reconnect();
96
+    String MQTTMsg = "{\"time\": \""+String(acTimeStringTZ)+"\", \"MAC\": \""+WiFi.macAddress()+"\", \"temp\":"+String(mT)+", \"humidity\": "+String(mH)+"}";
97
+    if (!client.publish(mqtt_topic, MQTTMsg.c_str())) {
98
+      Serial.println("ERROR: MQTT not sent!");
99
+    } 
100
+    #endif //USE_MQTT
101
+    draw(acTimeString, NOLOGO, mT, mH);
102
+  #endif //HAS_DHT
103
+  
104
+    timeSinceLastModeSwitch = millis();
105
+  } else if( time > MAX_RUNNING_TIME ) {
106
+      //Restart the board if running time is > MAX_RUNNING_TIME
107
+      #ifdef USE_MQTT
108
+      mqtt_reconnect();
109
+      String MQTTMsg = "{\"time\": \""+String(acTimeStringTZ)+"\", \"MAC\": \""+WiFi.macAddress()+"\", \"status\": \"Triggered reboot\"}";
110
+      if (!client.publish(mqtt_topic, MQTTMsg.c_str())) {
111
+        Serial.println("ERROR: MQTT not sent!");
112
+      }
113
+      #endif //USE_MQTT  
114
+      Serial.println("Triggered reboot");
115
+      ESP.restart();
116
+    } else if(WiFi.status() != WL_CONNECTED) {
117
+      //Reconnect WiFi if not connected
118
+      WiFiConnect();
119
+      mqtt_connect();
120
+    }
121
+  server.handleClient();  
122
+  delay(LOOP_DELAY);
123
+}
+43
my_constants.h
... ...
@@ -0,0 +1,43 @@
1
+#ifndef _MY_CONSTANTS
2
+#define _MY_CONSTANTS
3
+
4
+#define APPVER  "1.0.3"
5
+#define APPNAME "DHT"
6
+const char compile_date[] = APPNAME " v" APPVER " " __DATE__ " " __TIME__; 
7
+const char compile_time[] = __DATE__ " " __TIME__; 
8
+
9
+//Global Switches
10
+#define HAS_DHT
11
+#define USE_MQTT
12
+#define USE_OTA
13
+
14
+#define LED_BUILTIN 2
15
+
16
+/*
17
+#define MAX_RUNNING_TIME 50000 //50s
18
+#define MAX_RUNNING_TIME 100000 //100s
19
+#define MAX_RUNNING_TIME 3600000 //1hour
20
+#define MAX_RUNNING_TIME 7200000 //2hours
21
+#define MAX_RUNNING_TIME 10800000 //3hours
22
+#define MAX_RUNNING_TIME 14400000 //4 hours
23
+#define MAX_RUNNING_TIME 18000000 //5 hours
24
+#define MAX_RUNNING_TIME 21600000 //6 hours
25
+#define MAX_RUNNING_TIME 25200000 //7 hours
26
+#define MAX_RUNNING_TIME 28800000 //8 hours
27
+#define MAX_RUNNING_TIME 32400000 //9 hours
28
+#define MAX_RUNNING_TIME 36000000 //10 hours
29
+#define MAX_RUNNING_TIME 39600000 //11 hours
30
+#define MAX_RUNNING_TIME 43200000 //12 hours
31
+*/
32
+#define MAX_RUNNING_TIME 14400000 //4 hours
33
+#define BLINK_FLASH // Define if you want flash blinking during Wifi connection attempts
34
+//#define UPDATE_PERIOD 30000 // Will cause MQTT reconnect as it is too long
35
+#define UPDATE_PERIOD 20000
36
+long timeSinceLastModeSwitch = 0;
37
+uint32_t countMeasures=0;
38
+
39
+
40
+//#define LOOP_DELAY 10 //Initial Value
41
+#define LOOP_DELAY 100 //Test Value
42
+
43
+#endif //_MY_CONSTANTS
+46
my_dht.h
... ...
@@ -0,0 +1,46 @@
1
+#ifndef _MY_DHT_H
2
+#define _MY_DHT_H
3
+
4
+#ifndef ARDUINO_ESP8266_WEMOS_D1R1
5
+  #define DHTPIN 5             // D1 : Digital pin connected to the DHT sensor
6
+#else
7
+  //LCD + Battery ESP
8
+  //See : https://oneguyoneblog.com/2018/12/28/wemos-d1-esp-wroom-02-arduino-ide/
9
+  //#define DHTPIN 0             // D3 : Digital pin connected to the DHT sensor
10
+  #define DHTPIN 3             // D9 : Digital pin connected to the DHT sensor
11
+#endif //ARDUINO_ESP8266_WEMOS_D1R1
12
+#define DHTTYPE    DHT11     // DHT 11
13
+
14
+DHT dht(DHTPIN, DHTTYPE);
15
+
16
+float readDHTTemperature() {
17
+  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
18
+  // Read temperature as Celsius (the default)
19
+  float t = dht.readTemperature();
20
+  // Read temperature as Fahrenheit (isFahrenheit = true)
21
+  //float t = dht.readTemperature(true);
22
+  // Check if any reads failed and exit early (to try again).
23
+  if (isnan(t)) {    
24
+    Serial.println("Temperature : Failed to read from DHT sensor!");
25
+    return 0;
26
+  }
27
+  else {
28
+    Serial.println("Temperature :"+String(t));
29
+    return t;
30
+  }
31
+}
32
+
33
+float readDHTHumidity() {
34
+  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
35
+  float h = dht.readHumidity();
36
+  if (isnan(h)) {
37
+    Serial.println("Humidity : Failed to read from DHT sensor!");
38
+    return 0;
39
+  }
40
+  else {
41
+    Serial.println("Humidity :"+String(h));
42
+    return h;
43
+  }
44
+}
45
+
46
+#endif //_MY_DHT_H
+216
my_draw.h
... ...
@@ -0,0 +1,216 @@
1
+#ifndef _MY_DRAW_H
2
+#define _MY_DRAW_H
3
+
4
+#define NOLOGO -1
5
+#define SUN 0
6
+#define SUN_CLOUD  1
7
+#define CLOUD 2
8
+#define RAIN 3
9
+#define THUNDER 4
10
+
11
+
12
+#define SCREEN_WIDTH 128 // OLED display width, in pixels
13
+#define SCREEN_HEIGHT 64 // OLED display height, in pixels
14
+
15
+
16
+//--------------------------------------------------------------------------------------------
17
+//--------------------------------------------------------------------------------------------
18
+#ifdef ARDUINO_ESP8266_WEMOS_D1MINI
19
+//--------------------------------------------------------------------------------------------
20
+//--------------------------------------------------------------------------------------------
21
+#include <U8g2lib.h>
22
+#ifdef U8X8_HAVE_HW_SPI
23
+  #include <SPI.h>
24
+#endif
25
+#ifdef U8X8_HAVE_HW_I2C
26
+  #include <Wire.h>
27
+#endif
28
+
29
+#define SCROLL_Y 10
30
+#define T_FONTSZ 18
31
+
32
+U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 14, /* data=*/ 2);
33
+//https://github.com/olikraus/u8g2/wiki/fntlistall
34
+//https://github.com/olikraus/u8g2/wiki/setup_tutorial
35
+
36
+
37
+void drawScreenReset() {
38
+  pinMode(2, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
39
+}
40
+void drawInit() {
41
+  drawScreenReset();
42
+  u8g2.begin();  
43
+  u8g2.enableUTF8Print();
44
+}
45
+  
46
+void drawWeatherSymbol(u8g2_uint_t x, u8g2_uint_t y, uint8_t symbol)
47
+{
48
+  // fonts used:
49
+  // u8g2_font_open_iconic_embedded_6x_t
50
+  // u8g2_font_open_iconic_weather_6x_t
51
+  // encoding values, see: https://github.com/olikraus/u8g2/wiki/fntgrpiconic
52
+  
53
+  switch(symbol)
54
+  {
55
+    case SUN:
56
+      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
57
+      u8g2.drawGlyph(x, y, 69);  
58
+      break;
59
+    case SUN_CLOUD:
60
+      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
61
+      u8g2.drawGlyph(x, y, 65); 
62
+      break;
63
+    case CLOUD:
64
+      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
65
+      u8g2.drawGlyph(x, y, 64); 
66
+      break;
67
+    case RAIN:
68
+      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
69
+      u8g2.drawGlyph(x, y, 67); 
70
+      break;
71
+    case THUNDER:
72
+      u8g2.setFont(u8g2_font_open_iconic_embedded_6x_t);
73
+      u8g2.drawGlyph(x, y, 67);
74
+      break;
75
+    default:
76
+      break;
77
+  }
78
+}
79
+
80
+void drawWeather(uint8_t symbol, float degree, float humidity)
81
+{
82
+  drawWeatherSymbol(0, 48, symbol);
83
+  //u8g2.setFont(u8g2_font_logisoso32_tf);
84
+  u8g2.setFont(u8g2_font_logisoso18_tf );
85
+  //u8g2.setCursor(48+3, 50);
86
+  if(-1 != degree) {
87
+    u8g2.setCursor(60, T_FONTSZ+SCROLL_Y+9);
88
+    u8g2.print((float)((int)(10*degree+0.5))/10);
89
+    u8g2.print("°");    // requires enableUTF8Print()
90
+  }
91
+  if(-1 != humidity) {
92
+    u8g2.setCursor(0, 60);
93
+    u8g2.print((float)((int)(10*humidity+0.5))/10);
94
+    u8g2.print("%");    // requires enableUTF8Print()
95
+  }
96
+}
97
+
98
+/*
99
+  Draw a string with specified pixel offset. 
100
+  The offset can be negative.
101
+  Limitation: The monochrome font with 8 pixel per glyph
102
+*/
103
+void drawScrollString(int16_t offset, const char *s)
104
+{
105
+  static char buf[36];  // should for screen with up to 256 pixel width 
106
+  size_t len;
107
+  size_t char_offset = 0;
108
+  u8g2_uint_t dx = 0;
109
+  size_t visible = 0;
110
+  
111
+
112
+  u8g2.setDrawColor(0);   // clear the scrolling area
113
+  u8g2.drawBox(0, 0, u8g2.getDisplayWidth()-1, SCROLL_Y);
114
+  u8g2.setDrawColor(1);   // set the color for the text
115
+    
116
+  
117
+  len = strlen(s);
118
+  if ( offset < 0 )
119
+  {
120
+    char_offset = (-offset)/8;
121
+    dx = offset + char_offset*8;
122
+    if ( char_offset >= u8g2.getDisplayWidth()/8 )
123
+      return;
124
+    visible = u8g2.getDisplayWidth()/8-char_offset+1;
125
+    strncpy(buf, s, visible);
126
+    buf[visible] = '\0';
127
+    u8g2.setFont(u8g2_font_8x13_mf);
128
+    //u8g2.drawStr(char_offset*8-dx, 62, buf);
129
+    u8g2.drawStr(char_offset*8-dx, SCROLL_Y, buf);
130
+  }
131
+  else
132
+  {
133
+    char_offset = offset / 8;
134
+    if ( char_offset >= len )
135
+      return; // nothing visible
136
+    dx = offset - char_offset*8;
137
+    visible = len - char_offset;
138
+    if ( visible > u8g2.getDisplayWidth()/8+1 )
139
+      visible = u8g2.getDisplayWidth()/8+1;
140
+    strncpy(buf, s+char_offset, visible);
141
+    buf[visible] = '\0';
142
+    u8g2.setFont(u8g2_font_8x13_mf);
143
+    u8g2.drawStr(-dx, SCROLL_Y, buf);
144
+  }
145
+}
146
+
147
+void draw(const char *s, uint8_t symbol, float degree, float humidity)
148
+{
149
+  int16_t offset = -(int16_t)u8g2.getDisplayWidth();
150
+  int16_t len = strlen(s);
151
+  
152
+  u8g2.clearBuffer();         // clear the internal memory
153
+  drawWeather(symbol, degree, humidity);    // draw the icon and degree only once
154
+  drawScrollString(0, s);
155
+  u8g2.sendBuffer();        // transfer internal memory to the display
156
+}
157
+void displaySetStatus(int state) {}
158
+//--------------------------------------------------------------------------------------------
159
+//--------------------------------------------------------------------------------------------
160
+#elif ARDUINO_ESP8266_WEMOS_D1R1
161
+//--------------------------------------------------------------------------------------------
162
+//--------------------------------------------------------------------------------------------
163
+#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier
164
+#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
165
+
166
+SSD1306  display(0x3c, 5, 4);//d1 d2
167
+
168
+#define SCROLL_Y 10
169
+#define T_FONTSZ 18
170
+
171
+void drawScreenReset() {
172
+}
173
+void drawInit() {
174
+  // Initialising the UI will init the display too.
175
+  display.init();
176
+  display.flipScreenVertically();
177
+}
178
+void drawWeatherSymbol(uint8_t x, uint8_t y, uint8_t symbol) {}
179
+void drawWeather(uint8_t symbol, float degree, float humidity) {
180
+  display.setFont(ArialMT_Plain_24);
181
+  if(-1 != degree) {
182
+    char myString[8]="";
183
+    sprintf(myString,"%2.1f°",(float)((int)(10*degree+0.5))/10);
184
+    display.drawString(60, T_FONTSZ-4, myString );
185
+  }
186
+  if(-1 != humidity) {
187
+    char myString[8]="";
188
+    sprintf(myString,"%2.0f%%",(float)((int)(10*humidity+0.5))/10);
189
+    display.drawString(0,2*T_FONTSZ, myString );
190
+  }
191
+}
192
+void drawScrollString(int16_t offset, const char *s) {
193
+  display.setFont(ArialMT_Plain_10);
194
+  display.drawString(0, offset, s );
195
+}
196
+void draw(const char *s, uint8_t symbol, float degree, float humidity) {
197
+  display.setTextAlignment(TEXT_ALIGN_LEFT);
198
+  display.clear();
199
+  drawWeather(NOLOGO, degree, humidity);
200
+  drawScrollString(0, s);
201
+  display.display();
202
+}
203
+void displaySetStatus(int state) {
204
+  if( 0 == state ) {
205
+    display.displayOff();
206
+  } else {
207
+    display.displayOn();
208
+  }
209
+}
210
+#endif //
211
+
212
+
213
+
214
+
215
+
216
+#endif //_MY_DRAW_H
+97
my_http.h
... ...
@@ -0,0 +1,97 @@
1
+#ifndef _MY_HTTP
2
+#define _MY_HTTP
3
+#include <ESP8266WebServer.h>
4
+
5
+#ifdef USE_OTA
6
+#include "my_ota.h"
7
+#endif //USE_OTA
8
+
9
+#define PORT 80
10
+ESP8266WebServer server(PORT);
11
+
12
+
13
+String message="";
14
+
15
+void handleRoot() {
16
+  unsigned long time = millis()/1000;
17
+  byte mac[6];
18
+  char macStr[6];
19
+  WiFi.macAddress(mac);
20
+  sprintf(macStr,"%02x%02x%02x", mac[3], mac[4], mac[5]);
21
+  String macStrString=macStr;
22
+  message = "";
23
+  message += "<!DOCTYPE HTML><html>";
24
+  message += "<head>";
25
+  message += "  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
26
+  message += "  <link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.7.2/css/all.css\" integrity=\"sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr\" crossorigin=\"anonymous\">";
27
+  message += "  <title>esp8266-"+macStrString+"</title>";
28
+  message += "<style>";
29
+  message += "html{font-family:Arial;display:inline-block;margin:0px auto;text-align:center;}";
30
+  message += "h2{font-size:2.0rem;}";
31
+  message += "p{font-size:3.0rem;}";
32
+  message += ".app {font-size:0.8rem;font-style: italic;}";
33
+  message += ".dht-labels{font-size:1.5rem;vertical-align:middle;padding-bottom:15px;}";
34
+  message += "</style>";
35
+  message += "</head>";
36
+  message += "<body>";
37
+  message += "<h2>esp8266-"+macStrString+"</h2>";
38
+  message += "<p><i class=\"fas fa-thermometer-half\" style=\"color:#059e8a;\"></i><span class=\"dht-labels\">Temperature</span> <span id=\"temperature\">"+String(readDHTTemperature())+"</span><sup class=\"units\">&deg;C</sup></p>";
39
+  message += "<p><i class=\"fas fa-tint\" style=\"color:#00add6;\"></i><span class=\"dht-labels\">Humidity</span> <span id=\"temperature\">"+String(readDHTHumidity())+"</span><sup class=\"units\">%</sup></p>";
40
+  message += "<p><i class=\"fas fa-clock\" style=\"color:#00add6;\"></i><span class=\"dht-labels\">Date</span> <span id=\"temperature\">"+String(acTimeString)+"</span></p>";
41
+  message += "<div class=\"app\">"+String(compile_date)+"</div>";
42
+  message += "</body></html>";
43
+  server.send(200, "text/html", message );
44
+}
45
+void handleT() {
46
+  server.send(200, "text/html", String(readDHTTemperature()) );
47
+}
48
+void handleH() {
49
+  server.send(200, "text/html", String(readDHTHumidity()) );
50
+}
51
+void handleS() {
52
+  byte mac[6];
53
+  char macStr[6];
54
+  WiFi.macAddress(mac);
55
+  sprintf(macStr,"%02x%02x%02x", mac[3], mac[4], mac[5]);
56
+  String statusMsg = "{";
57
+  statusMsg += "\"app_name\": \""+String(APPNAME)+"\",";
58
+  statusMsg += "\"app_version\": \""+String(APPVER)+"\",";
59
+  statusMsg += "\"build_date\": \""+String(compile_time)+"\",";
60
+  statusMsg += "\"mac\": \""+WiFi.macAddress()+"\",";
61
+  statusMsg += "\"ip\": \""+WiFiIP+"\",";
62
+  statusMsg += "\"ota_name\": \"esp8266-"+String(macStr)+"\",";
63
+  statusMsg += "\"uptime\": "+String(millis())+",";
64
+  statusMsg += "\"countMeasures\": "+String(countMeasures)+",";
65
+  statusMsg += "\"period\": "+String(UPDATE_PERIOD)+",";
66
+  statusMsg += "\"loop_delay\": "+String(LOOP_DELAY)+",";
67
+  statusMsg += "\"last_update\": \""+String(acTimeStringTZ)+"\"";
68
+  statusMsg += "}";
69
+  server.send(200, "text/html", String(statusMsg) );
70
+}
71
+
72
+void handleNotFound() {
73
+  String message = "File Not Found\n\n";
74
+  message += "URI: ";
75
+  message += server.uri();
76
+  message += "\nMethod: ";
77
+  message += (server.method() == HTTP_GET) ? "GET" : "POST";
78
+  message += "\nArguments: ";
79
+  message += server.args();
80
+  message += "\n";
81
+
82
+  for (uint8_t i = 0; i < server.args(); i++) {
83
+    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
84
+  }
85
+  server.send(404, "text/plain", message);
86
+}
87
+
88
+
89
+void http_set() {
90
+  server.on("/", handleRoot);
91
+  server.on("/temperature", handleT);
92
+  server.on("/humidity", handleH);
93
+  server.on("/status", handleS);
94
+  server.onNotFound(handleNotFound);
95
+  server.begin();
96
+}
97
+#endif //_MY_HTTP
+78
my_isr.h
... ...
@@ -0,0 +1,78 @@
1
+#ifndef _MY_ISR_H
2
+#define _MY_ISR_H
3
+
4
+#include "my_mqtt.h"
5
+
6
+#ifdef ARDUINO_ESP8266_WEMOS_D1R1
7
+uint8_t buttonDown=0;
8
+uint8_t buttonUp=0;
9
+uint8_t buttonRight=0;
10
+uint8_t buttonPush=0;
11
+
12
+void ICACHE_RAM_ATTR interrupt0() // Right
13
+{
14
+  //Way: Opposite screen
15
+  // Disabled as it makes the board reboot
16
+  Serial.println("Right");
17
+  if(0==buttonRight) {
18
+    buttonRight = 1;
19
+    WiFiConnect();
20
+    mqtt_connect();
21
+  } else {
22
+    buttonRight = 0;
23
+  }
24
+}
25
+
26
+void ICACHE_RAM_ATTR interrupt12() // Down
27
+{
28
+  //Way: Toward edge of the board
29
+  Serial.println("Down");
30
+  if(0==buttonDown) {
31
+    buttonDown = 1;
32
+  } else {
33
+    buttonDown = 0;
34
+  }
35
+  displaySetStatus(buttonDown);
36
+}
37
+
38
+void ICACHE_RAM_ATTR interrupt13() // Up
39
+{
40
+  //Way: Toward hole in the board
41
+  Serial.println("Up");
42
+  if(0==buttonUp) {
43
+    buttonUp = 1;
44
+  } else {
45
+    buttonUp = 0;
46
+  }
47
+  displaySetStatus(1);
48
+  //WiFiConnect();
49
+  WiFi.disconnect(true);
50
+  //WiFi.mode(WIFI_STA);
51
+}
52
+
53
+void ICACHE_RAM_ATTR interrupt14() // Push
54
+{
55
+  //Way: Toward hole in the board
56
+  Serial.println("Push");
57
+  if(0==buttonPush) {
58
+    buttonPush = 1;
59
+  } else {
60
+    buttonPush = 0;
61
+  }
62
+}
63
+
64
+void isr_set() {
65
+  //pinMode(0, INPUT_PULLUP);
66
+  //attachInterrupt(digitalPinToInterrupt(0), interrupt0, FALLING);    // Right
67
+  pinMode(12, INPUT_PULLUP);
68
+  attachInterrupt(digitalPinToInterrupt(12), interrupt12, FALLING);  // Down
69
+  pinMode(13, INPUT_PULLUP);
70
+  attachInterrupt(digitalPinToInterrupt(13), interrupt13, FALLING);  // Up
71
+  pinMode(14, INPUT_PULLUP);
72
+  attachInterrupt(digitalPinToInterrupt(14), interrupt14, FALLING); // Push
73
+}
74
+#else
75
+void isr_set() {}
76
+#endif //ARDUINO_ESP8266_WEMOS_D1R1
77
+
78
+#endif //_MY_ISR_H
+56
my_mqtt.h
... ...
@@ -0,0 +1,56 @@
1
+#ifndef _MQTT_H
2
+#define _MQTT_H
3
+
4
+#include <PubSubClient.h> // Allows us to connect to, and publish to the MQTT broker
5
+
6
+
7
+// MQTT
8
+const int MAX_MQTT_CNX_RETRIES = 3;
9
+static char mqtt_server[32] = "";
10
+const char* mqtt_server_int = "192.168.0.1";
11
+const char* mqtt_server_ext = "a.domain.tld";
12
+const char* mqtt_topic = "topicDHT";
13
+const int   mqtt_port = 1883;
14
+// The client id identifies the ESP8266 device. Think of it a bit like a hostname (Or just a name, like Greg).
15
+char clientID[22] = "";
16
+const char* clientIDFmt="esp-%s";
17
+
18
+const char* mqtt_user="esp8266";
19
+const char* mqtt_password="SomeRandomPassword";
20
+
21
+// Initialise the WiFi and MQTT Client objects
22
+WiFiClient wifiClient;
23
+PubSubClient client(mqtt_server, 1883, wifiClient); // 1883 is the listener port for the Broker
24
+
25
+void mqtt_connect() {
26
+  if( 0 == strcmp(aplist[currentAPIndex].ssid,"wifi1") ) {
27
+    //House Wifi
28
+    client.setServer(mqtt_server_int, mqtt_port);
29
+    //if (client.connect(clientID)) {
30
+    if (client.connect(clientID,mqtt_user,mqtt_password)) {
31
+      Serial.println("Connected to MQTT Broker : "+String(mqtt_server_int));
32
+    } else {
33
+      Serial.println("Connection to MQTT Broker "+String(mqtt_server_int)+"failed...");
34
+      delay(2000);
35
+    }
36
+  } else {
37
+    // External Wifi
38
+    client.setServer(mqtt_server_ext, mqtt_port);
39
+    if (client.connect(clientID,mqtt_user,mqtt_password)) {
40
+      Serial.println("Connected to MQTT Broker : "+String(mqtt_server_ext));
41
+    } else {
42
+      Serial.println("Connection to MQTT Broker "+String(mqtt_server_ext)+"failed...");
43
+      delay(2000);
44
+    }
45
+  }    
46
+}
47
+
48
+void mqtt_reconnect() {
49
+  byte count = 0;
50
+  while (!client.connected() && count < MAX_MQTT_CNX_RETRIES ) {
51
+    Serial.print("Attempting MQTT reconnection...");
52
+    mqtt_connect();
53
+    count++;
54
+  }
55
+}
56
+#endif //_MQTT_H
+35
my_ntp.h
... ...
@@ -0,0 +1,35 @@
1
+#ifndef _MY_NTP_H
2
+#define _MY_NTP_H
3
+
4
+#define TIMEZONE_OFFSET     8                                   // CET
5
+#define DST_OFFSET          0                                   // CEST
6
+#define UPDATE_CYCLE        (1 * 1000)                          // every second
7
+
8
+static char   acTimeString[32];
9
+static char   acTimeStringTZ[38];
10
+const char* getTimeString(void) {
11
+  time_t now = time(nullptr);
12
+  struct tm *ts;
13
+  ts = localtime(&now);
14
+  strftime(acTimeString, sizeof(acTimeString), "%Y-%m-%d %H:%M:%S", ts);
15
+  strftime(acTimeStringTZ, sizeof(acTimeStringTZ), "%Y-%m-%d %H:%M:%S+0800", ts);
16
+  return acTimeString;
17
+}
18
+
19
+
20
+void setClock(void) {
21
+  configTime((TIMEZONE_OFFSET * 3600), (DST_OFFSET * 3600), "time.google.com", "pool.ntp.org", "time.nist.gov");
22
+  int count = 0;
23
+  Serial.print("Waiting for NTP time sync: ");
24
+  time_t now = time(nullptr);   // Secs since 01.01.1970 (when uninitalized starts with (8 * 3600 = 28800)
25
+  while (now < 8 * 3600 * 2) {  // Wait for realistic value
26
+    delay(500);
27
+    Serial.print(".");
28
+    now = time(nullptr);
29
+    if(count>20) break;
30
+    count++;
31
+  }
32
+  Serial.printf("\nCurrent time: %s\n", getTimeString());
33
+}
34
+
35
+#endif //_MY_NTP_H
+41
my_ota.h
... ...
@@ -0,0 +1,41 @@
1
+#ifndef _MY_OTA_H
2
+#define _MY_OTA_H
3
+
4
+void ota_set() {
5
+  #ifdef USE_OTA
6
+  //ArduinoOTA.setPort(8266);
7
+  //ArduinoOTA.setHostname(clientID);
8
+  //ArduinoOTA.setPassword(WiFi.macAddress().c_str());
9
+  ArduinoOTA.onStart([]() {
10
+    String type;
11
+    displaySetStatus(1);
12
+    if (ArduinoOTA.getCommand() == U_FLASH) {
13
+      type = "sketch";
14
+    } else { // U_FS
15
+      type = "filesystem";
16
+    }
17
+
18
+    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
19
+    Serial.println("Start updating " + type);
20
+  });
21
+  ArduinoOTA.onEnd([]() {
22
+    Serial.println("\nEnd");
23
+    draw("DONE.", -1, -1, 100);
24
+  });
25
+  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
26
+    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
27
+    draw("Upgrading....", -1, -1, (progress / (total / 100)));
28
+  });
29
+  ArduinoOTA.onError([](ota_error_t error) {
30
+    Serial.printf("Error[%u]: ", error);
31
+    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
32
+    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
33
+    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
34
+    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
35
+    else if (error == OTA_END_ERROR) Serial.println("End Failed");
36
+  });
37
+  ArduinoOTA.begin();
38
+  #endif //USE_OTA
39
+}
40
+
41
+#endif //_MY_OTA_H
+86
my_wifi.h
... ...
@@ -0,0 +1,86 @@
1
+#ifndef _MY_WIFI_H
2
+#define _MY_WIFI_H
3
+
4
+//-----------------------------------------------------------------------------------
5
+//Wifi Constants
6
+//-----------------------------------------------------------------------------------
7
+String WiFiIP;
8
+typedef struct _ssid_list_t {
9
+  const char* ssid;
10
+  const char* password;
11
+} ssid_list_t;
12
+
13
+//#define _TEST
14
+#ifndef _TEST
15
+static int currentAPIndex = -1;
16
+const int MAX_CNX_RETRIES = 20;
17
+ssid_list_t aplist[]={
18
+  {"wifi1", "pass1"},
19
+  {"wifi2", "pass2"},
20
+  {"wifi3", "pass3"},
21
+  {NULL,NULL}
22
+};
23
+#else
24
+const int MAX_CNX_RETRIES = 1;
25
+ssid_list_t aplist[]={
26
+  {"Phony", "phonyaccount"},
27
+  {NULL,NULL}
28
+};
29
+#endif //_TEST
30
+
31
+byte WiFiConnect() {
32
+  WiFiIP = "No IP";
33
+  //WiFi.disconnect(true);
34
+  //delay(2000);
35
+  //WiFi.mode(WIFI_STA);
36
+  //WiFi.setAutoConnect(true);
37
+
38
+  byte i = 0;
39
+  while(aplist[i].ssid!= NULL) {
40
+    WiFi.persistent(false);
41
+    WiFi.mode(WIFI_STA);
42
+    WiFi.disconnect(true);
43
+    delay(1000);
44
+    WiFi.softAPdisconnect(true); 
45
+    delay(1000);
46
+    Serial.print("WIFI status = ");
47
+    Serial.println(WiFi.getMode());
48
+    
49
+    WiFi.begin(aplist[i].ssid, aplist[i].password);
50
+    byte count = 0;
51
+    Serial.print("WiFiConnect: Connecting to ");
52
+    Serial.print(aplist[i].ssid);
53
+    draw(aplist[i].ssid, -1, -1, -1);
54
+    while(WiFi.status() != WL_CONNECTED && count < MAX_CNX_RETRIES)
55
+    {
56
+      count ++;
57
+      #ifdef BLINK_FLASH
58
+        digitalWrite(LED_BUILTIN, 3);
59
+        delay(500);
60
+        digitalWrite(LED_BUILTIN, 0);
61
+        delay(500);
62
+      #else
63
+        delay(500);
64
+      #endif //BLINK_FLASH
65
+      Serial.print(".");
66
+      draw(aplist[i].ssid, NOLOGO, -1, 100*count/MAX_CNX_RETRIES);
67
+    }
68
+    if( WiFi.status() == WL_CONNECTED ) {
69
+      Serial.println("");
70
+      IPAddress ip = WiFi.localIP();
71
+      WiFiIP =  String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
72
+      Serial.println("WiFiConnect: "+WiFiIP);
73
+      currentAPIndex = i;
74
+      break;
75
+    }
76
+    if(WiFi.status() != WL_CONNECTED)
77
+    {
78
+      Serial.println("WiFiConnect: Failed");
79
+    }
80
+    i++;
81
+  }
82
+  digitalWrite(LED_BUILTIN, HIGH);
83
+  return (WiFi.status() == WL_CONNECTED) ? 1 : 0;
84
+}
85
+
86
+#endif //_MY_WIFI_H