How to create a character (in this case a colon ":") that can blink to represent seconds on a digital clock

I made a program on the ESP8266 with the addition of RTC, DHT22, lcd i2c 16x2 and SDcard. then to show the time on the power lcd use RTC hours and minutes. for the seconds pointer I want to symbolize it as a colon ":" which flashes every second. at first I managed to make the program but then when I added another function to send data to firebase. the colon that should be ticking actually freezes. any suggestions what i should do?

#include "SPI.h"
#include "SD.h"
#include "DHT.h"
#include "RTClib.h"
#include <Wire.h>
#include "PCF8574.h"
#include <LiquidCrystal_I2C.h>
#include <ESP8266WiFi.h>
#include <Firebase_ESP_Client.h>
/*======================================================================================*/
#define DHTPIN D4
#define DHTTYPE DHT22
/*Default Trigger Setting*/
int tTrigger = 0;
int hTrigger = 0;
/*======================================================================================*/
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS1307 rtc;
DHT dht(DHTPIN, DHTTYPE);
File dataFile;
PCF8574 io(0x20);
/*======================================================================================*/
#include "addons/TokenHelper.h"
#include "addons/RTDBHelper.h"
#define WIFI_SSID 
#define WIFI_PASSWORD 
#define API_KEY 
#define USER_EMAIL  
#define USER_PASSWORD 
#define STORAGE_BUCKET_ID 
#define DATABASE_URL

FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
/*======================================================================================*/
const int chipSelect = D8;
int rkipas  = 0;
int rpump   = 1;
const unsigned long intervalSdcard  = 5000;
unsigned long       timeSdcard      = 0;
const unsigned long intervalStorage = 360000;
unsigned long  timeStorage          = 0;
const unsigned long intervalRTDB = 1000;
unsigned long  timeRTDB          = 0;

unsigned long getDataPrevMillis = 0;
unsigned long getDataDisplayPrevMillis = 0;
unsigned long sendIntPrevMillis = 0;
/*======================================================================================*/
int P1=2;
int P2=3;
int P3=4;

int hourupg;
int minupg;
int yearupg;
int monthupg;
int dayupg;
int menu =0;
/*======================================================================================*/
char FileName[] = "000000.txt";

void setup() {
  
  Serial.begin(115200);
  while (!Serial) {}
  delay(3000); // wait for console opening
/*======================================================================================*/
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (!rtc.isrunning()) {
    Serial.println("RTC lost power, lets set the time!");
    rtc.adjust(DateTime(__DATE__, __TIME__));
  }
  rtc.adjust(DateTime(__DATE__, __TIME__));
  
/*======================================================================================*/
  if (!SD.begin(chipSelect)) {
    Serial.println("Initialization failed!");
    while (1);
  }
/*======================================================================================*/  
  io.begin();
  dht.begin();
  lcd.init();
  lcd.backlight();
  int menu=0;
/*======================================================================================*/
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
  for(int i=0; i <= 100; i++)
  {
    lcd.setCursor(0,0);
    lcd.print("connecting wifi!");
    lcd.print("   ");
    updateProgressBar(i, 100, 1);
    delay(100);
  }
  delay(500);
  }
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Connected IP: ");
  lcd.setCursor(0,1);
  lcd.print(WiFi.localIP());
  delay(3000);
  lcd.clear();
/*======================================================================================*/
  Serial.printf("Firebase Client v%s\n\n", FIREBASE_CLIENT_VERSION);
  config.api_key = API_KEY;
  auth.user.email = USER_EMAIL;
  auth.user.password = USER_PASSWORD;
  config.token_status_callback = tokenStatusCallback;
  config.database_url = DATABASE_URL;
  
  lcd.setCursor(0,0);
  lcd.print("Connected to"); 
  lcd.setCursor(0,0);
  lcd.print("Firebase Client");
  lcd.clear();
  
  Firebase.begin(&config, &auth);
  Firebase.reconnectWiFi(true);

  Serial.printf("Set int... %s\n", Firebase.RTDB.setInt(&fbdo, "/SetVal/SetTemp", 27) ? "ok" : fbdo.errorReason().c_str());
  Serial.printf("Set int... %s\n", Firebase.RTDB.setInt(&fbdo, "/SetVal/SetHumi", 85) ? "ok" : fbdo.errorReason().c_str());

  
  #if defined(ESP8266)
    fbdo.setBSSLBufferSize(1024, 1024);
  #endif
    fbdo.setResponseSize(1024);
}
/*======================================================================================*/
void loop() {
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

/*======================================================================================*/
  if(io.read(P1))
  {
   menu=menu+1;
  }
  if (menu==0)
  {
    DisplayDateTime();
    SavingData();
    }
  if (menu==1)
  {
    DisplaySetHour();
    }
  if (menu==2)
  {
    DisplaySetMinute();
    }
  if (menu==3)
  {
    DisplaySetYear();
    }
  if (menu==4)
  {
    DisplaySetMonth();
    }
  if (menu==5)
  {
    DisplaySetDay();
    }
  if (menu==6)
  {
    StoreAgg();
    delay(500);
    menu=0;
    }
  delay(100);
}
/*======================================================================================*/
void updateProgressBar(unsigned long count, unsigned long totalCount, int lineToPrintOn)
 {
    double factor = totalCount/80.0;
    int percent = (count+1)/factor;
    int number = percent/5;
    int remainder = percent%5;
    if(number > 0)
    {
       lcd.setCursor(number-1,lineToPrintOn);
       lcd.write(5);
    }
   
       lcd.setCursor(number,lineToPrintOn);
       lcd.write(remainder);   
 }
/*======================================================================================*/
void SavingData(){
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  if (isnan(h) || isnan(t)) {
  lcd.setCursor (0,0);
  lcd.print("sensor failed!");
  return;
  }
/*======================================================================================*/
  DateTime now = rtc.now();
  FileName[0] = now.day()/10 + '0';
  FileName[1] = now.day()%10 + '0';
  dayupg=now.day();
  FileName[2] = now.month()/10 + '0';
  FileName[3] = now.month()%10 + '0';
  monthupg=now.month();
  FileName[4] = (now.year()/10)%10 + '0';
  FileName[5] = now.year()%10 + '0';
  yearupg=now.year();
  FileName[10] = '\0';

  String fileNameStr = "/";
  fileNameStr += FileName;
/*======================================================================================*/
  String dataString = "";
  if (now.day()<=9)
  {
    dataString += "0";
    }
  dataString += String(now.day(), DEC);
  dayupg=now.day();
  dataString += "/";
  if (now.month()<=9)
  {
    dataString += "0";
    }
  dataString += String(now.month(), DEC);
  monthupg=now.month();
  dataString += "/";
  dataString += String(now.year() - 2000);
  yearupg=now.year();
  dataString += " | ";
  if (now.hour()<=9)
  {
    dataString += "0";
    }
  dataString += String(now.hour(), DEC);
  hourupg=now.hour();
  dataString += ":";
  if (now.minute()<=9)
  {
    dataString += "0";
    }
  dataString += String(now.minute(), DEC);
  minupg=now.minute();
  dataString += " | ";
  dataString += String(h);
  dataString += String("%");
  dataString += " | ";
  dataString += String(t);
  dataString += String("°C");
/*======================================================================================*/

unsigned long currentTime = millis();
  if ( currentTime - timeSdcard >= intervalSdcard) {
    dataFile = SD.open(FileName, FILE_WRITE);
    if (dataFile) {
      dataFile.println(dataString);
      dataFile.close();
      Serial.println(dataString);
    }
    else {
      Serial.print("error opening : ");
      Serial.println(FileName);
    }
    timeSdcard = currentTime;
  }
/*======================================================================================*/
  if (Firebase.ready() && currentTime - timeStorage >= intervalStorage)
  {  
    Serial.print("Upload file : ");
    Serial.println(FileName);
    if (Firebase.Storage.upload(&fbdo, STORAGE_BUCKET_ID, fileNameStr.c_str(), mem_storage_type_sd, FileName, "data.txt"))
      Serial.printf("\nDownload Link: %s\n", fbdo.downloadURL().c_str());
    else
      Serial.println(fbdo.errorReason());
    timeStorage = currentTime;
  }
/*======================================================================================*/
 Serial.printf("Suhu send to RTDB... %s\n", Firebase.RTDB.setInt (&fbdo, "/Hasil_Pembacaan/suhu", t) ? "ok" : fbdo.errorReason().c_str());
 Serial.printf("Kelembaban send to RTDB.... %s\n", Firebase.RTDB.setInt(&fbdo, "/Hasil_Pembacaan/kelembaban", h) ? "ok" : fbdo.errorReason().c_str());
/*======================================================================================*/  
  Serial.printf("tTrigger Control... %s\n", Firebase.RTDB.getInt(&fbdo, "/SetVal/SetTemp") ? String(fbdo.intData()).c_str() : fbdo.errorReason().c_str());
  tTrigger = fbdo.intData();

   if ( t >= tTrigger){
    io.write (rkipas, LOW);
    lcd.setCursor(10, 0);
    lcd.print(">");
  }
  else {
    io.write (rkipas, HIGH);
    lcd.setCursor(10, 0);
    lcd.print(" ");
  }

  Serial.printf("tTrigger Control... %s\n",  Firebase.RTDB.getInt(&fbdo, "/SetVal/SetHumi") ? String(fbdo.intData()).c_str() : fbdo.errorReason().c_str());
  hTrigger = fbdo.intData();
  
  if ( h <= hTrigger){
    io.write (rpump, LOW);
    lcd.setCursor(10, 1);
    lcd.print(">");
  }
  else {
    io.write (rpump, HIGH);
    lcd.setCursor(10, 1);
    lcd.print(" ");
  }
/*======================================================================================*/
}
void DisplayDateTime ()
{
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  if (isnan(h) || isnan(t)) {
  lcd.setCursor (0,0);
  lcd.print("sensor failed!");
  return;
  }

  DateTime now = rtc.now();
/*======================================================================================*/
  lcd.setCursor(11, 0);
  lcd.print(" ");
  lcd.print(t);
  lcd.print(char(223));
  lcd.print("C");
  lcd.setCursor(11, 1);
  lcd.print(" ");
  lcd.print(h);
  lcd.print("% ");
/*======================================================================================*/
  lcd.setCursor(0, 0);
  if (now.hour()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.hour(), DEC);
  hourupg=now.hour();

  lcd.setCursor(3, 0);
  if (now.minute()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.minute(), DEC);
  minupg=now.minute();
  int detik = now.second();
  if (detik % 2 == 0)
  {
    lcd.setCursor(2, 0);
    lcd.print(":");
  }
  else
  {
    lcd.setCursor(2, 0);
    lcd.print(" ");
  }
/*======================================================================================*/
 lcd.setCursor(0, 1);
  if (now.day()<=9){
    lcd.print("0");
    }
  lcd.print(now.day(), DEC);
  dayupg=now.day();
  lcd.print("/");
  if (now.month()<=9){
    lcd.print("0");
    }
  lcd.print(now.month(), DEC);
  monthupg=now.month();
  lcd.print("/");
  lcd.print((now.year()-2000), DEC);
  yearupg=now.year();
/*======================================================================================*/

}
/*======================================================================================*/
void DisplaySetHour()
{
  lcd.clear();
  DateTime now = rtc.now();
  if(io.read(P2)==HIGH){
    if(hourupg==23)
    {
      hourupg=0;
    }
    else
    {
      hourupg=hourupg+1;
    }
  }
   if(io.read(P3)==HIGH){
    if(hourupg==0)
    {
      hourupg=23;
    }
    else
    {
      hourupg=hourupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set time:");
  lcd.setCursor(0,1);
  lcd.print(hourupg,DEC);
  delay(200);
}
/*======================================================================================*/
void DisplaySetMinute()
{
  lcd.clear();
  if(io.read(P2)==HIGH)
  {
    if (minupg==59)
    {
      minupg=0;
    }
    else
    {
      minupg=minupg+1;
    }
  }
   if(io.read(P3)==HIGH)
   {
    if (minupg==0)
    {
      minupg=59;
    }
    else
    {
      minupg=minupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Minutes:");
  lcd.setCursor(0,1);
  lcd.print(minupg,DEC);
  delay(200);
}
/*======================================================================================*/
void DisplaySetYear()
{
  lcd.clear();
  if(io.read(P2)==HIGH)
  {    
    yearupg=yearupg+1;
  }
   if(io.read(P3)==HIGH)
   {
    yearupg=yearupg-1;
  }
  lcd.setCursor(0,0);
  lcd.print("Set Year:");
  lcd.setCursor(0,1);
  lcd.print(yearupg,DEC);
  delay(200);
}
/*======================================================================================*/
void DisplaySetMonth()
{
  lcd.clear();
  if(io.read(P2)==HIGH)
  {
    if (monthupg==12)
    {
      monthupg=1;
    }
    else{monthupg=monthupg+1;
    }
  }
   if(io.read(P3)==HIGH){
    if (monthupg==1)
    {
      monthupg=12;
    }
    else{monthupg=monthupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Month:");
  lcd.setCursor(0,1);
  lcd.print(monthupg,DEC);
  delay(200);
}
/*======================================================================================*/
void DisplaySetDay()
{
  lcd.clear();
  if(io.read(P2)==HIGH)
  {
    if (dayupg==31)
    {
      dayupg=1;
    }
    else
    {
      dayupg=dayupg+1;
    }
  }
   if(io.read(P3)==HIGH){
    if (dayupg==1)
    {
      dayupg=31;
    }
    else{dayupg=dayupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Day:");
  lcd.setCursor(0,1);
  lcd.print(dayupg,DEC);
  delay(200);
}
/*======================================================================================*/
void StoreAgg()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("SAVING IN");
  lcd.setCursor(0,1);
  lcd.print("PROGRESS");
  rtc.adjust(DateTime(yearupg,monthupg,dayupg,hourupg,minupg,0));
  lcd.clear();
  delay(200);
}ketik atau tempel kode di sini

this my code for colon ticking/blinking on LCD

when i added this code the colon start freezing and sometimer do not appear

anyone can help?
i don't know why i'am so obsessed with this colon ticking :roll_eyes:

How long does the firebase thingy takes ?

rapidly data changes, i'am not using millis or delay
on serial monitor show like this

If it’s slow and you test if seconds are even or not only when the seconds are even, it will not blink. May worth checking exactly how often you come back to that’s part

The idea is to test whether the second is an even number or not.
Although slightly more verbose, I think this is more easy to diagnose (and works on my projects):

int detik = now.second();
if ((int(detik/2)*2)==detik){
lcd.print(":");
}
else{
lcd.print(" ");
}

I get that but if you come to this test every 2 seconds, it will never blink hence my question about the time it takes to issue the firebase command

My question is how useful it is to send data to the database as fast as you can? Do you really care if you store temperature and humidity every second in the database or every 5 seconds?

I'm not familiar with Firebase; there is a setIntAsync method which does not seem to wait for the transaction to complete so should basically not cause a delay. I however suspect that sending too much will somewhere create a bottleneck and a slowing down. Looking at the output on serial monitor, the total of the storing in the DB takes about 2 seconds; I would slow it down and only store temperature and humidity every 2.5 seconds or maybe even 5 seconds.

As said, not familiar with Firebase but it looks like you're sending humidity and temperature to two different tables; is there a reason for that? I might be wrong though.

Try changing the colon wherever you call that blink code. If at least 1000 milliseconds has elapsed since the last time you changed it.

The blinking might stutter and be uneven but you won't risk falling into sync and getting no charge per @J-M-L 's trap.

a7

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.