Blynk Android Time Input Widget - Android display problem I observe

Hi Blynkers. The Blynk Time Input widget is my new best friend.

Not only can you set Start and Stop times by day of week, you can also use it as a time display.

When I write to the Blynk Time Input Widget using the documented parameters, it displays whatever times and days of week you wish. Terrific for displaying the day by day schedules you’ve inputted.

Using the Time Input Widget for data input works on iOS and Android.
Time Input as a display works on iOS, but seems to fail on Android.
The day of week display works, but the Start and Stop times do not display,
show dashes. --:-- --:–

I am using Blynk’s public servers. Blynk library 0.6.1.
I use Khoi Hoang’s fabulous Blynk_WiFiManager 1.2.0.
I am running Arduino IDE 1.8.13 on Win 10,
targeting Adafruit’s ESP32 Feather, using library 1.0.5.
Android 11 on a Google Pixel
iPad iOS 14.4

Here’s some code that writes to the Time Input widget. Thanks for the helpful doc, Blynk!
It was easy.

int revolvingDisplayDay = 1; // allows revolvingDisplay to cycle through each day on the Time Input Widget

#define SET_START_STOP_TIME_VPIN 2
#define SET_START_STOP_TIME_VPIN 3

void revolvingDisplay()
{
  Serial.println ( "\nrevolvingDisplay called..." );

  long startTime[7], stopTime[7]; 
  char tzone[] = "AmericaNew_York";

  // Display the current day's schedule on the Time Input Widget
  int today = weekday() - 1;   // using TimeLib, weekday() starts on Sunday. Blynk starts on Monday. Duh. 
  if ( today == 0 ) today = 7; // Sunday, Bloody Sunday

  Serial.print ( "in revolvingDisplay, today is = " ); Serial.print ( today );  
  Serial.print ( ", also showing day # " ); Serial.println ( revolvingDisplayDay );  

  String dayOfWeekString = String ( today );  
  Blynk.virtualWrite ( SET_START_STOP_TIME_VPIN, startTime [today-1], stopTime [today-1], tzone, dayOfWeekString ); 


  // Display a rotating day-by-day schedule on the Display Widget
  dayOfWeekString = String ( revolvingDisplayDay );    // revolvingDisplayDay starts at 1;  index starts at 0
  bool haveValidTimes = ! ( ( startTime[revolvingDisplayDay-1] == -1 ) 
                         || ( stopTime[revolvingDisplayDay-1]  == -1) 
                         || ( startTime[revolvingDisplayDay-1] == stopTime[today-1] ) );
  if ( haveValidTimes )
  {
    Blynk.virtualWrite ( DISPLAY_START_STOP_SCHEDULE_VPIN, startTime [revolvingDisplayDay-1], stopTime [revolvingDisplayDay-1], 
                         tzone, dayOfWeekString ); 
  } 
  else
  {
    Blynk.virtualWrite ( DISPLAY_START_STOP_SCHEDULE_VPIN, 0, 0, tzone, dayOfWeekString );     
  }
  // Revolve to beginning of week
  if ( revolvingDisplayDay >= 7 ) revolvingDisplayDay = 1; else revolvingDisplayDay++;
  
  Serial.println ( "revolvingDisplay done..." );  
}

It Would Be Nice if the Android version of your handy Time Input WIdget would show the start and stop times just as it does on iOS.

Thanks, all.

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)

@BlynkAndroidDev for info…

Pete.

Thanks, kind sir.

@thorathome can you send logs from your device? I will try to include a fix into the next versions which will be released next week

Thanks for responding so quickly.
Will try to send Android an iOS logs by tomorrow.

1 Like

Just sent two logs…
Thanks for taking interest in this issue.

1 Like

Received them, It looks like some timezone ID issue between platforms, Android app can’t recognize timezone id received from iOs

I will add handling of such issue into the next Android release

Much appreciated. Looking forward to the next Android revision.
Always happy to beta test Androids.

1 Like

The new version is postponed till the next week, as it requires a server update due to several new features we implemented in it. I will update this thread once It will be available.

Thank you for the update and for your constant progress. I remain a (paying) fan.
Blynk on!

I believe new build is already available to update everywhere - it should contain a fix to this issue with timezone sync between android and ios. Our bad it took several weeks due to server upgrade.

Nice work. You’ve fixed a number of Android issues, including the Start Stop Time Widget issue I mentioned.

Thanks for keeping Android current. Much appreciated.

1 Like