Strona 1 z 1

Zegar na module czasu rzeczywistego

: 04 lis 2021, 23:33
autor: WitekR
Projekt przedstawia realizację prostego układu zegara czasu rzeczywistego (Fig. 1). Projekty tego typu są wykorzystywane jako samodzielne zegary bądź jako moduły pomocnicze w realizacjach układów wymagających ciągłego dostępu do informacji o aktualnym czasie (np. systemy rejestrujące, alarmowe itp.).
uklad1.jpg
uklad1.jpg (51.13 KiB) Przejrzano 1204 razy
Hardware
Urządzenie zrealizowano w oparciu o popularny moduł zegara czasu rzeczywistego DS3231 (Fig. 2). Układ wymaga baterii podtrzymującej napięcie w momencie ustania napięcia zasadniczego źródła zasilania (Fig. 3).
DS3231.jpg
DS3231.jpg (40.71 KiB) Przejrzano 1201 razy
DS3231-rufs.jpg
DS3231-rufs.jpg (25.98 KiB) Przejrzano 1200 razy
Sercem układu jest platforma Arduino Leonardo (Fig. 4). Do mikrokontrolera, za pośrednictwem magistrali I2C podłączono moduł zegara czasu rzeczywistego DS3231. Do tej samej magistrali I2C podłączono wyświetlacz LCD 20×4.

Schemat ideowy
schemat-stykowa.jpg
schemat-stykowa.jpg (129.31 KiB) Przejrzano 1200 razy
Działanie
Układ w czasie rzeczywistym wyświetla bieżący czas oraz datę na wyświetlaczu ciekłokrystalicznym oraz przekazuje te informacje do minitora portu szeregowego.

Lista części
platforma prototypowa Arduino Leonardo,
płytka prototypowa,
moduł zegara czasu rzeczywistego DS3231,
wyświetlacz LCD 20×4,
przewody/mostki.
Kod:

Kod: Zaznacz cały

#include "Wire.h"
#include <LiquidCrystal_I2C.h> 

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Ustawienie adresu ukladu na 0x27

#define DS3231_I2C_ADDRESS 0x68

// Konwersja liczby dziesiętnej do postaci binarnej
byte decToBcd(byte val){
  return( (val/10*16) + (val%10) );
}

// Konwersja liczby binarnej do postaci dziesiętnej
byte bcdToDec(byte val){
  return( (val/16*10) + (val%16) );
}

void setup(){
  Wire.begin();
  Serial.begin(9600);
  // Ustawienie czasu w momencie inicjacji układu:
  // DS3231 seconds, minutes, hours, day, date, month, year
  // setDS3231time(00,01,11,7,11,03,17);

  lcd.begin(20,4);   
  lcd.backlight(); // załączenie podświetlenia 
  lcd.setCursor(0,0);
  lcd.print("Prosty zegar");
  delay(500);  
}

void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
  // ustawienie czasu i daty w DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0);                    // określa, że następna wartość ma trafić do rejestru sekund
  Wire.write(decToBcd(second));     // ustawienie sekund
  Wire.write(decToBcd(minute));     // ustawienie minuty
  Wire.write(decToBcd(hour));       // ustawienie godziny
  Wire.write(decToBcd(dayOfWeek));  // ustawienie dnia tygodnia (1=niedziela, 7=sobota)
  Wire.write(decToBcd(dayOfMonth)); // ustawienie dnia (1-31)
  Wire.write(decToBcd(month));      // ustawienie miesiąca
  Wire.write(decToBcd(year));       // ustawienie roku (0-99)
  Wire.endTransmission();
}

void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // ustawia rejestr DS3231 na 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // żąda 7 bajtów danych od modułu DS3231 począwszy od rejestru 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}

void displayTime(){
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
  &year);
  
// Przekazanie danych do wyświetlenie w serial monitorze i do LCD

  // CZAS
  // Godziny
    // podczas wyświetlania konwertuje wartość zmiennej typu bitowego do postaci dziesiętnej
  Serial.print(hour, DEC);
  if (hour<10) {
    lcd.setCursor(0,1); 
    lcd.print("0");
    lcd.print(hour, DEC); 
  } else {
    lcd.setCursor(0,1); 
    lcd.print(hour, DEC); 
    }
  Serial.print(":");
 // lcd.setCursor(2,1); 
  lcd.print(":");
  
  // Minuty
  Serial.print(minute, DEC);
  if (minute<10) {
    Serial.print("0");
    lcd.setCursor(3,1); 
    lcd.print("0");
    lcd.print(minute, DEC); 
  } else {
    lcd.setCursor(3,1); 
    lcd.print(minute, DEC); 
    }
  Serial.print(":");
  lcd.print(":");
  
  //Sekundy
  if (second<10){
    Serial.print("0");
    lcd.setCursor(6,1); 
    lcd.print("0");
    lcd.print(second, DEC); 
  } else {
    Serial.print(second, DEC);
    lcd.setCursor(6,1); 
    lcd.print(second, DEC); 
    }

// DATA
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  lcd.setCursor(0,2); 
  lcd.print("0");

  // Dzień
  if (dayOfMonth<10){
    lcd.setCursor(0,2); 
    lcd.print("0");
    lcd.print(dayOfMonth, DEC); 
  } else {
    lcd.setCursor(0,2); 
    lcd.print(dayOfMonth, DEC); 
    }
    lcd.print(".");
    
  // Miesiąc
  if (month<10){
    lcd.setCursor(3,2); 
    lcd.print("0");
    lcd.print(month, DEC); 
  } else {
    lcd.setCursor(3,2); 
    lcd.print(month, DEC); 
    }
    lcd.print(".");

   //Rok
    lcd.print("20");
    if (year<10){
    lcd.setCursor(8,2); 
    lcd.print("0");
    lcd.print(year, DEC); 
  } else {
    lcd.setCursor(8,2); 
    lcd.print(year, DEC); 
    }
  
  Serial.print(" ");
  lcd.setCursor(0,3); 
  switch(dayOfWeek){
  case 1:
    Serial.println("Niedziela");
    lcd.print("Niedziela");
    break;
  case 2:
    Serial.println("Poniedzialek");
    lcd.print("Poniedzialek");
    break;
  case 3:
    Serial.println("Wtorek");
    lcd.print("Wtorek");
    break;
  case 4:
    Serial.println("Środa");
    lcd.print("Środa");
    break;
  case 5:
    Serial.println("Czwartek");
    lcd.print("Czwartek");
    break;
  case 6:
    Serial.println("Piątek");
    lcd.print("Piątek");
    break;
  case 7:
    Serial.println("Sobota");
    lcd.print("Sobota");
    break;
  }
}
void loop()
{
  displayTime(); // wyświetlanie czasu rzeczywistego
  delay(1000);   // odśwież co sekundę
}