I am following up on this bug in the Android Blynk IoT Time Input widget. I spent time developing simplified code to demonstrate the problem. Hopefully, Blynk can duplicate it.
The bug: When WRITING to the Time Input widget, the iOS shows the time as expected. The Android does not.
Android shows widget label, widget color and day of week, but not the Start or Stop times.
IOS shows it all. This behavior was also evident in the Old Blynk version of this widget.
Any hope of a fix to this persistent issue? I use both platforms, but am most often on Android.
Thanks.
Complete code showing the problem is below, written for ESP32 and ESP8266.
I have tested on both. I have a LED widget on V0, the Time Input widget on V1 and a reset Text Input widget on V99. The Key routines are at the end of the sketch. Everything else is pretty standard.
You will need to
#define key Blynk values in lines 14-16 (I use an #include file)
#define MY_WIFI_SSID
#define MY_WIFI_PASSWORD
Here’s working ESP32 and ESP8266 code. Screen shots at bottom.
All help appreciated. Thanks.
#define SERIAL_SPEED 230400
#define SKETCH_NAME "Real_Simple_New_BLYNK_Debugging_Android"
#define BLYNK_PRINT Serial // Generates Blynk debug prints. Comment out if not needed, saving space
// My Helper Files
#include "MY_WIFI_CREDENTIALS.h" // #defines MY_WIFI_SSID AND MY_WIFI_PASSWORD
#include "MY_BLYNK_CREDENTIALS.h" // #defines MY_BLYNK_SERVER and MY_xxx_AUTHCODEs
#define BLYNK_TEMPLATE_ID MY_TIME_WIDGET_DEBUG_TEMPLATE_ID // FROM MY_BLYNK_CREDENTIALS.h
#define BLYNK_DEVICE_NAME MY_TIME_WIDGET_DEBUG_DEVICE_NAME // FROM MY_BLYNK_CREDENTIALS.h
#define MY_BLYNK_AUTHCODE MY_TIME_WIDGET_DEBUG_DEVICE_AUTHCODE // FROM MY_BLYNK_CREDENTIALS.h
// This is WiFiMulti library selection for ESP32 or 8266
#if ESP8266
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti; // set up the WiFi object
const uint32_t connectTimeoutMs = 8000; // timing for WiFiMulti testing connection
#include <BlynkSimpleEsp8266_SSL.h>
#elif ESP32
#include <WiFiMulti.h>
WiFiMulti wifiMulti; // set up the WiFi object
const uint32_t connectTimeoutMs = 5000; // timing for WiFiMulti testing connection
#include <BlynkSimpleEsp32_SSL.h>
#endif
///////////////////////////////////////////////////////////////////////////////////////////
//// COMPILER VALUE SELECTION - VIRTUAL PINS FOR THE 3 WIDGETS ////////////////////////////
#define HEARTBEAT_VPIN V0 // Vpin for the Blynk App LED widget
#define DISPLAY1_VPIN V1 // Vpin for the Blynk App Labeled Value widget
#define RESET_VPIN V99 // Vpin for the widget to REBOOT the device
#define HEARTBEAT_LABEL "Buhdum"
#define DISPLAY1_LABEL "Time Widget"
#define RESET_LABEL "Nuke Me"
#define BLYNK_DARK_BLUE "#5F7CD8"
#define DEFAULT_HEARTBEAT_COLOR BLYNK_DARK_BLUE
#define DEFAULT_DISPLAY1_COLOR BLYNK_DARK_BLUE
// BLYNK TIMERS FOR HEARTBEAT and Rotating Time Display
// THIS SKETCH SETS UP A HEARTBEAT LED ON A TIMER TO SHOW SYSTEM IS ALIVE AND WELL
BlynkTimer myTimer;
// Blynk timers to blink a heartbeat LED on and
int heartbeatLEDinterval = 4250; // interval between heartbeats for Blynk Virtual LED in millisec
int heartbeatLEDtimerID; // heartbeatLEDinterval
int heartbeatLEDduration = 1250; // duration of each blink in millisec
int heartbeatLEDdurationTimerID; // (set as an interval timer once heartbeat is ON ... to turn it back OFF)
bool heartbeatLEDon = false; // this lets me use the same routine for the turn-on timer and the turn-off interval
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SETUP WIFI, BLYNK, HEARTBEAT, AND WIDGETS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
// Never enough good printouts
Serial.begin ( SERIAL_SPEED );
delay ( 500 );
Serial.println ( "\n\n=======================================" );
Serial.print ( SKETCH_NAME );
Serial.println ( "\nNew BLYNK Info:" );
Serial.print ( "BLYNK_TEMPLATE_ID: " ); Serial.println ( BLYNK_TEMPLATE_ID );
Serial.print ( "BLYNK_DEVICE_NAME: " ); Serial.println ( BLYNK_DEVICE_NAME );
// Connect to WiFi and Blynk
connectToWLANandBlynk(); // Connect to WiFi, then to Blynk server
Serial.println ( " Checkpoint setupBlynkTimers..." );
setupBlynkTimers(); // Establish Blynk timers after Blynk is connected
Serial.println ( " Checkpoint first heartbeat..." );
// Set Blynk Virtual Heartbeat LED OFF
heartbeatLEDon = false;
Blynk.virtualWrite ( HEARTBEAT_VPIN, 000 );
heartbeatLEDblink(); // start first heartbeat
Serial.println ( " Checkpoint first rotateTimerWidgetDisplay..." );
rotateTimerWidgetDisplay();
// this is called via the heartbeat timer from now on
Serial.println();
Serial.print ( " " );
Serial.println( "... Setup complete \n\n" );
} //end setup
// KEEPING IT SIMPLE
void loop()
{
Blynk.run(); ;
myTimer.run();
} // end loop
// Connects to MultiWiFi and to Blynk gracefully
// Call once in Setup()
// #include after BLYNK and WIFI_CREDENTIALS
// #include "CONNECT_TO_WIFI_AND_BLYNK.h"
void connectToWLANandBlynk() // No more Blynk_WM.
{
WiFi.persistent ( false ); // Don't save anything in EEPROM or LittleFS
WiFi.mode ( WIFI_STA ); // Station mode
// Register multi WiFi networks
wifiMulti.addAP ( MY_WIFI_SSID, MY_WIFI_PASSWORD );
wifiMulti.addAP ( MY_WIFI_SSID2, MY_WIFI_PASSWORD2 );
int WiFiTries = 0;
while ( WiFiTries < 5 )
if ( wifiMulti.run ( connectTimeoutMs ) == WL_CONNECTED )
{
Serial.print ( "WiFi connected just fine to ");
Serial.print ( WiFi.SSID() ); Serial.print ( " at " ); Serial.println ( WiFi.localIP() );
break;
}
else
{
WiFiTries++;
Serial.print ( "WiFi not connected... #" ); Serial.println ( WiFiTries );
if ( WiFiTries >= 5 )
{
Serial.println ( "RESTARTING!\n\n" );
delay ( 5000 );
ESP.restart();
}
delay ( 5000 );
}
Serial.println ( "Next, connect to Blynk. \n" );
Blynk.config ( MY_BLYNK_AUTHCODE );
Blynk.connect() ;
if ( Blynk.connected() )
{
Serial.println ( "\nBlynk connected just fine. " );
}
else Serial.println ( "Blynk NOT CONNECTED \n\n" );
Serial.println();
} // end connectToWLANandBlynk
// SET UP BLYNK TIMER FOR HEARTBEAT (and anything eles you may want later)
void setupBlynkTimers()
{
Serial.println ( "Setting up Blynk timers" );
// Interval timer for heartbeatLED
heartbeatLEDtimerID = myTimer.setInterval ( heartbeatLEDinterval, heartbeatLEDblink );
Serial.println ( "... Blynk timers all set up." );
} //end setupBlynkTimers
// BLYNK_WRITE_DEFAULT GETS CALLED WHEN THERE IS NO SPECIFIC BLYNK_WRITE FOR THAT VIRTUAL PIN
// This makes it a flexible - and programmable - receiver
// I have used this for a RESET button
BLYNK_WRITE ( RESET_VPIN )
{
Serial.println ( "\n\n\n*** Hit the reset button!!\n\n" );
Serial.println ( " \n REBOOTING \n\n" );
delay ( 5000 );
ESP.restart();
} //end BLYNK_WRITE_DEFAULT
// BLYNK_CONNECTED GETS CALLED WHEN CONNECTING TO BLYNK SERVERS
// GETS CALLED IMMEDIATELY ON FIRST CONNECT TO BLYNK SERVER, TOO
BLYNK_CONNECTED()
{
Serial.println ( "\nBLYNK_CONNECTED..." );
// Update the various Blynk App widget labels
setupWidgetLabelsAndColors();
} // end BLYNK_CONNECTED
// LED HEARTBEAT
// Updated may 2020 for PWM reduced brightness on LED_BUILTING and Blynk LED Widget. ESP32 and ESP8266
void heartbeatLEDblink()
/* Blink the Virtual Blynk LED
* If LED is off, it turne the LEDs on, then sets a timer to turn LED off
* When the timer triggers, same routine turns the LEDs off
*/
{
if ( heartbeatLEDon ) // if LED is on, turn it off and vice cersa
{
// Turn Blynk LED Widget OFF
Blynk.virtualWrite ( HEARTBEAT_VPIN, 000 ); // Blynk LED off
Serial.println ( " ..." );
}
else // LED is off. Turn it on and set a timer to to turn it off again
{
Blynk.virtualWrite ( HEARTBEAT_VPIN, 1 ); // BLynk LED on
Serial.print ( "... heartbeat of <" ); Serial.print ( SKETCH_NAME );
Serial.print ( "> WiFi.status() = " ); Serial.print ( WiFi.status() );
// Set a timer to turn off the LEDs in a bit
heartbeatLEDdurationTimerID = myTimer.setTimeout ( heartbeatLEDduration, heartbeatLEDblink );
}
heartbeatLEDon = ! heartbeatLEDon; // flip status
// *************************************************************
// *************************************************************
// Update the TIME WIDGET with each heartneat call
rotateTimerWidgetDisplay();
} //end heartbeatLEDblink
// Initial setup of TIME WIDGET LABELS AND COLORS
void setupWidgetLabelsAndColors()
{
Serial.println ( "\nsetupWidgetLabelsAndColors() called..." );
// Set up heartbeat label and color
Blynk.setProperty ( HEARTBEAT_VPIN, "label", HEARTBEAT_LABEL );
Blynk.setProperty ( HEARTBEAT_VPIN, "color", DEFAULT_HEARTBEAT_COLOR );
// Set up the Time Widget label and color
Blynk.setProperty ( DISPLAY1_VPIN, "label", DISPLAY1_LABEL );
Blynk.setProperty ( DISPLAY1_VPIN, "color", DEFAULT_DISPLAY1_COLOR );
// Set up the REBOOT widget label
Blynk.setProperty ( RESET_VPIN, "label", RESET_LABEL );
} // end setupWidgetLabelsAndColors
// rotateTimerWidgetDisplay refreshes ALL the Start/Stop DISPLAY Time widgets
// rotateTimerWidgetDisplay gets called by a TIMER
int rotatingDisplayDayOfWeek = 1; // 1=MON, 7=SUN in Blynkland - Start rotating displays after reboot with Monday
void rotateTimerWidgetDisplay()
{
Serial.println ( "\nrotateTimerWidgetDisplay called (TIMER event)..." );
// Write the Start/Stop DISPLAY times for this rotating day
updateAllStartStopTimeDISPLAYwidget ( rotatingDisplayDayOfWeek );
// Rotate to next day for the upcoming display
if ( rotatingDisplayDayOfWeek >=7 ) rotatingDisplayDayOfWeek = 1; else rotatingDisplayDayOfWeek++;
Serial.println ( "\n... exiting rotateTimerWidgetDisplay (TIMER event)\n" );
} // end rotateTimerWidgetDisplay
// Blynk Time Input widget wants chars for the days of the week
const char *dayChar[7] = { "1", "2", "3", "4", "5", "6", "7" }; // For Blynk Time Input Widget (input parameter for display)
// Mon Tue Wed Thu Fri Sat Sun
const char tzone[] = "AmericaNew_York"; // For use in loading up Time Input Widgets
// Write to the Time Input DISPLAY Widget Start, Stop and ROTATING Day of Week
// This is called by rotateTimerWidgetDisplay from the heartbeat
void updateAllStartStopTimeDISPLAYwidget ( const int dayOfWeek ) // dayOfWeek starts at 1 = Mon
{
Serial.print ( "updateAllStartStopTimeDISPLAYwidget called for today = " ); Serial.println ( dayOfWeek );
int convertedDayOfWeek = dayOfWeek - 1; // dayOfWeek runs from 1-7
int vPinX = 1; // virtual pin
long startTimeX = 63367 + random ( 0, 360 ); // slightly randomized time
long stopTimeX = 77887 + random ( 0, 360 ); // slightly randomized time
char dayCharX[2];
strcpy ( dayCharX, dayChar[convertedDayOfWeek] ); // char string of day of week
// Write to the Start/Stop Time Widget - works for iOS, not for Android
Blynk.virtualWrite ( vPinX, startTimeX, stopTimeX, tzone, dayCharX );
// label, color and day of week work. Start/stop times do not.
Serial.print ( "... start: " ); Serial.print ( startTimeX ); //startTime[schedule][convertedDayOfWeek] );
Serial.print ( "; stop: " ); Serial.println ( stopTimeX ); //[schedule][convertedDayOfWeek] );
Serial.print ( "... tzone: " ); Serial.println ( tzone );
Serial.print ( "... days: " ); Serial.println ( dayCharX ); //[convertedDayOfWeek] );
Serial.print ( "... Vpin: " ); Serial.println ( vPinX ); //timeWidgetVpin[schedule][1] );
Serial.println();
Serial.println ( "... exiting updateAllStartStopTimeDISPLAYwidget" );
} // end updateAllStartStopTimeDISPLAYwidget
Here are a couple of screen shots
iOS (iPad)
Android (Google Pixel 3a XL)