Created
January 25, 2018 02:52
-
-
Save mercdev/f0fea967a82fb87e92a425c5f12580af to your computer and use it in GitHub Desktop.
Using Blynk with WeMos D1 R2 and RTC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define BLYNK_PRINT Serial | |
// Blynk app | |
#include <BlynkSimpleEsp8266.h> | |
#include <RTClib.h> | |
#include <WidgetRTC.h> | |
// Non Blynk specific, local files | |
#include <WiFiUdp.h> | |
#include "NTP.h" | |
// device hardware specific | |
#include <PCF85063TP.h> | |
PCD85063TP RTC; | |
// WiFi settings | |
char ssid[] = "xxx"; | |
char pass[] = "xxx"; | |
// Blynk Settings | |
char auth[] = "xxxxxx"; | |
// Blynk Widgets | |
WidgetTerminal terminalWidget(V8); | |
WidgetRTC rtcWidget; // requires RTC widget in app | |
BlynkTimer blynkTimer; // SimpleTimer replacement | |
// Sketch variables | |
boolean connectInProgress; | |
boolean syncBlynkTime = true; | |
boolean ntpStarted = false; | |
int blynkTimerId; | |
int connectTimerId; | |
// | |
// This is called for all virtual pins that do not have BLYNK_WRITE handler | |
// | |
BLYNK_WRITE_DEFAULT() | |
{ | |
terminalWidget.print("BLYNK_WRITE for pin V"); | |
terminalWidget.print(request.pin); | |
terminalWidget.println(" not defined."); | |
terminalWidget.println("Values: "); | |
for (auto i = param.begin(); i < param.end(); ++i) | |
{ | |
terminalWidget.print("* "); | |
terminalWidget.println(i.asString()); | |
} | |
terminalWidget.flush(); | |
} | |
// | |
// This is called for all virtual pins that do not have BLYNK_READ handler | |
// | |
BLYNK_READ_DEFAULT() | |
{ | |
terminalWidget.print("BLYNK_READ for pin V"); | |
terminalWidget.print(request.pin); | |
terminalWidget.println(" not defined."); | |
terminalWidget.flush(); | |
} | |
// | |
// This is called when Blynk has successfully connected | |
// | |
BLYNK_CONNECTED() | |
{ | |
syncBlynkTime = true; // (re)set time to synchronize with Blynk by default | |
rtcWidget.begin(); // sets setSyncProvider internally and immediately call Blynk.sendInternal("rtc", "sync"); | |
setSyncInterval(5*60); // subsequent time sync interval in seconds (5 minutes), once that interval has elapsed, time will set itself to timeNeedsSync | |
// cancel NTP time synchronization | |
if (ntpStarted) | |
{ | |
ntpStop(); | |
ntpStarted = false; | |
// reset checkBlynkConnection to default/startup interval of 5 minutes | |
blynkTimer.changeInterval(connectTimerId, 300000L); | |
blynkTimer.restartTimer(connectTimerId); | |
} | |
} | |
/* | |
* Blynk feature was postponed until a later release | |
BLYNK_DISCONNECTED() | |
{ | |
#ifdef BLYNK_PRINT | |
Serial.println("[_\\|/_] Blynk Disonnected."); | |
#endif | |
} | |
*/ | |
// | |
// This is called when Smartphone App is opened | |
// | |
BLYNK_APP_CONNECTED() | |
{ | |
#ifdef BLYNK_PRINT | |
Serial.println("[_\\|/_] Blynk App Connected."); | |
#endif | |
} | |
// | |
// This is called when Smartphone App is closed | |
// | |
BLYNK_APP_DISCONNECTED() | |
{ | |
#ifdef BLYNK_PRINT | |
Serial.println("[_\\|/_] Blynk App Disconnected."); | |
#endif | |
} | |
// | |
// synchronize the RTC hardware device with our TimeLib provided date/time values | |
// The time library is synchronized by the Blynk WidgetRTC on connect | |
// NOTE: most RTC's require a battery in order to oscillate, otherwise time doesn't increment on the hardware | |
// | |
void syncRTCHardware() | |
{ | |
#ifdef BLYNK_PRINT | |
char currentTime[16]; | |
char currentDate[16]; | |
#endif | |
if (!Blynk.connected() && syncBlynkTime) | |
{ | |
#ifdef BLYNK_PRINT | |
Serial.println("[_\\|/_] Blynk not connected. Changing to NTP Sync"); | |
#endif | |
syncBlynkTime = false; | |
ntpStarted = ntpStart(); // starts the udp listener for NTP sync | |
if (ntpStarted) | |
{ | |
setSyncProvider(getNtpTime); | |
setSyncInterval(5*60); // 5 minutes | |
// change checkBlynkConnection to check every 1 minute | |
blynkTimer.changeInterval(connectTimerId, 60000L); | |
blynkTimer.restartTimer(connectTimerId); | |
} | |
else | |
{ | |
#ifdef BLYNK_PRINT | |
Serial.println("[_\\|/_] NTP start failed."); | |
#endif | |
} | |
} | |
// get the time library status | |
// enums: timeNotSet = 0, timeNeedsSync = 1, timeSet = 2 | |
timeStatus_t timestatus = timeStatus(); | |
if (timestatus == 0) | |
{ | |
#ifdef BLYNK_PRINT | |
Serial.println("[_\\|/_] TimeLib: not set."); // this is where you get concerned | |
#endif | |
// time library has never been set exit the function so we don't overwrite RTC values | |
return; | |
} | |
if (timestatus == 1) | |
{ | |
// time library needs synchronization, wait for time status to change | |
// before comparing RTC | |
#ifdef BLYNK_PRINT | |
Serial.println("[_\\|/_] TimeLib: needs synchronization."); | |
#endif | |
return; | |
} | |
if (timestatus == 2) | |
{ | |
RTC.getTime(); | |
// check RTC values against the synchronized TimeLib value | |
// TODO: change this to do simple unix epoch comparison, PCF85063TP.h doesn't support this | |
if ((RTC.year + 2000) != year() || RTC.month != month() || RTC.dayOfMonth != day() || RTC.hour != hour() || RTC.minute != minute() || RTC.second != second()) | |
{ | |
#ifdef BLYNK_PRINT | |
// display the current values of each | |
Serial.println("[_\\|/_] TimeLib: RTC not matched. Resynchronizing RTC."); | |
sprintf(currentDate, "%02d/%02d/%04d", month(), day(), year()); | |
sprintf(currentTime, "%02d:%02d:%02d", hour(), minute(), second()); | |
Serial.print("[_\\|/_] TimeLib: "); | |
Serial.print(currentDate); | |
Serial.print (" "); | |
Serial.println(currentTime); | |
// depending on the RTC library used, the RTC property names could be different | |
// i.e. RTC.month vs RTC.month() | |
sprintf(currentDate, "%02d/%02d/%04d", RTC.month, RTC.dayOfMonth, RTC.year); | |
sprintf(currentTime, "%02d:%02d:%02d", RTC.hour, RTC.minute, RTC.second); | |
Serial.print("[_\\|/_] RTC Time: "); | |
Serial.print(currentDate); | |
Serial.print(" "); | |
Serial.println(currentTime); | |
#endif | |
// set the RTC to TimeLib values here | |
RTC.stopClock(); | |
RTC.fillByYMD(year(), month(), day()); | |
RTC.fillByHMS(hour(), minute(), second()); | |
RTC.setTime(); | |
RTC.startClock(); | |
return; | |
} | |
#ifdef BLYNK_PRINT | |
Serial.println("[_\\|/_] TimeLib: RTC matches."); | |
#endif | |
} | |
} | |
// | |
// checks connection to Blynk server and attempts reconnect if needed | |
// | |
void checkBlynkConnection() | |
{ | |
if (!Blynk.connected() && !connectInProgress) | |
{ | |
connectInProgress = true; | |
if(!Blynk.connect()) | |
{ | |
#ifdef BLYNK_PRINT | |
Serial.println("[_\\|/_] Blynk Connect failed"); | |
#endif | |
} | |
else | |
{ | |
#ifdef BLYNK_PRINT | |
Serial.println("[_\\|/_] Blynk Connected"); | |
#endif | |
} | |
connectInProgress = false; // either it connected or timed out | |
} | |
} | |
int freeRam() | |
{ | |
extern int __heap_start, *__brkval; | |
int v; | |
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); | |
} | |
void checkMemory() | |
{ | |
#ifdef BLYNK_PRINT | |
Serial.print("[_\\|/_] SRAM: "); | |
Serial.println(freeRam()); | |
#endif | |
} | |
// | |
// all initialization and timer setups go here | |
// | |
void setup() | |
{ | |
Serial.begin(115200); | |
RTC.begin(); | |
// timer tasks | |
blynkTimerId = blynkTimer.setInterval(150000L, syncRTCHardware); // synchronize the RTC every 2.5 minutes | |
connectTimerId = blynkTimer.setInterval(300000L, checkBlynkConnection); // check Blynk connection every 5 minutes | |
// non-blocking Blynk setup | |
Blynk.config(auth, BLYNK_DEFAULT_DOMAIN, BLYNK_DEFAULT_PORT); | |
Blynk.disconnect(); // skip connecting to the Blynk server until checkBlynkConnection timer fires | |
// this allows setup() to continue/exit and the main loop() to begin without blocking | |
blynkTimer.setTimeout(2000L, checkBlynkConnection); // in 2 seconds, do initial connection check | |
blynkTimer.setTimeout(10000L, syncRTCHardware); // in 10 seconds, do initial time check | |
blynkTimer.setTimeout(3000L, checkMemory); | |
} | |
// Main processing loop. | |
void loop() | |
{ | |
blynkTimer.run(); | |
// only attempt Blynk-related functions when connected to Blynk | |
if (Blynk.connected()) | |
{ | |
Blynk.run(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment