LCD hodiny s RTC a využitím času kompilace

Zdravím, chtěl jsem se s Vámi podělit o svůj kód. Vím, že tento modul je celkem starý a moc se už nepoužívá, přesto se s ním asi začátečníci jako já potkají. Mě například přišel v krabičce se spoustou ostatního. Teprve se učím, ale podařilo se zprovoznit MH-Real TIME Clock module 2 a spolu s 16x2 LDC displejem si udělat hodiny.

Oříšek pro mne byl ale počáteční nastavení času do modulu – samozřejmě je to jednoduché to tam napsat ručně. Ale protože programátor je v zásadě velmi líný tvor a lenost je matka pokroku, napsal jsem takovou rutinu, která uloží do modulu automaticky čas při kompilaci a nahrání do modulu (procedura se jmenuje AutoSetBuildTime). Má to nějaké omezení, například pokud nebudete u PC a vyndáte baterku, nahraje se automaticky čas při poslední kompilaci.

// ** Modified by MaaRty ** 
// ** To set the build time into RTC module automatically - **
// ** - is necessary to unplug the battery or CVV before compiling **
//
// Ukazka pouziti  DS1302-knihovny k udelani hodin -
//  - pomoci DS1302 a 16x2 LCD displaye s pouzitim I2C prevodniku.
// Show how to use the DS1302l ibrary to get clock working -
// - on the 16x2 LCD display with I2C 
//
// DS1302:  CLK pin   -> Arduino UNO Digital 2
//          DAT pin   -> Arduino UNO Digital 3
//          RST pin   -> Arduino UNO Digital 4
//          VCC pin   -> Arduino UNO 5V POWER
//          GND pin   -> Arduino UNO GND
// LCD16x2 I2C:    
//          GND       -> Arduino UNO GND 
//          VCC       -> Arduino UNO 5V POWER
//          SDA       -> Arduino UNO SDA
//          SLC       -> Arduino UNO SLC

#include <Wire.h>          
#include <LiquidCrystal_I2C.h>
#include <DS1302RTC.h>
#include <Time.h>
#include <TimeLib.h>
#include <string.h>

// Init the DS1302
// Set pins:  RST, DAT, CLK
DS1302RTC RTC(4, 3, 2);

// Optional connection for RTC module
//#define DS1302_GND_PIN 33
//#define DS1302_VCC_PIN 35

// Init the LCD
//   initialize the library with the numbers of the interface pins
// set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27,16,2);

void setup()
{
  lcd.init(); //inicializace lcd // initialize the lcd
  lcd.backlight(); // rozsviceni // open the backlight 
  
  // Hodiny bezi nebo ne? pokud ne nastavi cas // Clock runing? If not set time.
  //  RTC.haltRTC(true); // true - nebezi, false bezi (casovac) // true - running
  if(RTC.haltRTC()){
    lcd.print("Clock stopped!");
      //Aktualizace datumu a casu manualne //manual set time and date
        //setTime(22, 29, 00, 02, 03, 2019);
        //setTime(hour,minute,second,day,month,year);
        //RTC.set(now());
               
      //AKTUALIZACE CASU AUTOMATICKY NA BULID TIME // ------
      // Automatically sets the time when the code is compiled // 
      AutoSetBuildTime();
      RTC.haltRTC(false);
  }
  else
    lcd.print("Clock working.");
    
 delay(500);
 
  lcd.setCursor(0,1);
  if (RTC.writeEN())
    lcd.print("Write allowed.");
  else
    lcd.print("Write protected.");

  delay ( 2000 );
  
  // Setup time library  
  lcd.clear();
  lcd.print("RTC Sync");
  setSyncProvider(RTC.get);          // the function to get the time from the RTC
 
  if(timeStatus() == timeSet)
    lcd.print(" Ok!");
  else
    lcd.print(" FAIL!");
  
  delay ( 2000 );
  
  lcd.clear();
}

void loop()
{
  static int sday = 0; // Saved day number for change check

  // Display time centered on the upper line
  lcd.setCursor(3, 0);
  print2digits(hour());
  lcd.print("  ");
  print2digits(minute());
  lcd.print("  ");
  print2digits(second());
  
  // Update in 00:00:00 hour only
  if(sday != day()) {
    // Display abbreviated Day-of-Week in the lower left corner
    lcd.setCursor(0, 1);
    lcd.print(dayShortStr(weekday()));

    // Display date in the lower right corner
    lcd.setCursor(5, 1);
    lcd.print(" ");
    print2digits(day());
    lcd.print("/");
    print2digits(month());
    lcd.print("/");
    lcd.print(year());
  }
  // Warning!
  if(timeStatus() != timeSet) {
    lcd.setCursor(0, 1);
    lcd.print(F("RTC ERROR: SYNC!"));
  }

  // Save day number
  sday = day();

  // Wait small time before repeating :)
  delay (100);
}

//AKTUALIZACE CASU AUTOMATICKY NA BULID TIME // ------
      // Automatically sets the time when the code is compiled // 
void AutoSetBuildTime() 
{
char input[] =__TIME__ " " __DATE__; //Input
String H,M,S,D,N,Y; // Output
const char del[] = " :,"; //Delimiters 
char *token; 
int i=0;
char *array[6]; // Number of variables to save
int Hi,Mi,Si,Di,Ni,Yi;

   token = strtok(input, del);
   while( token != NULL ) //splitted
   {
     array[i++] = token;
     token = strtok(NULL, del);
   }
    H = array[0];
     Hi = H.toInt();
    M = array[1];
     Mi = M.toInt();
    S = array[2];
     Si = S.toInt();
    D = array[4];
     Di = D.toInt();
    N = array[3]; // prevod mesicu na cisla :) // month to number   
     if       (N == "Jan")
     Ni = 1;
     else if ( N == "Feb")
     Ni = 2 ;
     else if ( N == "Mar")
     Ni = 3 ;
     else if ( N == "Apr") 
     Ni = 4 ;
     else if ( N == "May")
     Ni = 5 ;
     else if ( N == "Jun")
     Ni = 6 ;
     else if ( N == "Jul")
     Ni = 7 ;
     else if ( N == "Aug")
     Ni = 8 ;
     else if ( N == "Sep")
     Ni = 9 ;
     else if ( N == "Oct")
     Ni = 10 ;
     else if ( N == "Nov")
     Ni = 11 ;
     else if ( N = "Dec")
     Ni = 12 ;
    Y = array[5];
     Yi = Y.toInt();
  setTime(Hi,Mi,Si,Di,Ni,Yi);
  RTC.set(now());
}
//------------------------------------------------- 

//Prints alway two digits to display (00)
void print2digits(int number) {
  if (number >= 0 && number < 10) {
    lcd.write('0');
  }
  lcd.print(number);
}

Takže to shrnu. Kód je kompletní rozchození hodin RTC modulu DS1302 na 16x2 LCD display s I2C sběrnicí a automatickým nahráním aktuálního času z PC při kompilaci (musí být prvně odpojen zdroj pro nové nastavení času). Kód je popsán podrobně v poznámkách.

Další podobné články

Ovládání teploty pomocí relé a senzoru DS18B20

Tento projekt umožňuje měřit teplotu pomocí senzoru DS18B20, zobrazit ji na I2C LCD displeji, a ovládat relé podle teplotních limitů. Relé bude aktivní, když je teplota mezi 0 a 22 stupni Celsia. Projekt může sloužit k ovládání topení, ventilace nebo jiného zařízení podle okolní teploty.