środa, 13 grudnia 2017

Raspberry pi - Python - RTC DS3231

Ten post chciałbym poświęcić na opisanie sposobu podłączenia RTC DS3231 do Raspberry pi.

Znalezione obrazy dla zapytania raspberry pi
[Źródło: https://www.element14.com/community/community/raspberry-pi]

Program Python:


Poniżej przejdę do opisu dwóch klas jedna ma za zadanie obsługę zegara systemowego, druga natomiast odpowiada za obsługę układu DS3231.

Klasa dla obsługi zegara systemowego:

  1. class SystemTimeDate:
  2.    
  3.     ###################################
  4.     #get time and date
  5.     def getTimeDate():
  6.         now = datetime.datetime.now()
  7.         timeDate = [now.second,
  8.                     now.minute,
  9.                     now.hour,
  10.                     datetime.date.weekday(now),
  11.                     now.day,
  12.                     now.month,
  13.                     now.year]
  14.         #debug
  15.         #print("getTimeDateFunc: %d:%d:%d %d %d/%d/%d"  %(timeDate[2], timeDate[1],
  16.         #                               timeDate[0], timeDate[3],
  17.         #                               timeDate[4], timeDate[5],
  18.         #                               timeDate[6]));
  19.         return timeDate;
  20.  
  21.     ###################################
  22.     #get only date
  23.     def getDate():
  24.         now = datetime.datetime.now()
  25.         date = [datetime.date.weekday(now),
  26.                 now.day,
  27.                 now.month,
  28.                 now.year]
  29.         #print("getDateFun: %d %d/%d/%d"  %(date[0],date[1],date[2],date[3]));
  30.         return date;
  31.  
  32.     ###################################
  33.     #get only time
  34.     def getTime():
  35.         now = datetime.datetime.now()
  36.         time = [now.second,
  37.                 now.minute,
  38.                 now.hour]
  39.         #print("getTimeFun: %d:%d:%d"  %(time[2], time[1], time[0]));
  40.         return time;
  41.  
  42.     ###################################
  43.     #get string with week day
  44.     def getWeekDay():
  45.         weekDay = [ "Poniedziałek",
  46.                     "Wtorek",
  47.                     "Środa",
  48.                     "Czwartek",
  49.                     "Piątek",
  50.                     "Sobota",
  51.                     "Niedziela"];
  52.         now = datetime.datetime.now()
  53.         weekDayNumber = datetime.date.weekday(now)
  54.         retWeekDay = weekDay[weekDayNumber]
  55.         return retWeekDay

Pierwsze trzy funkcje od góry zajmują się pobieraniem daty oraz czasu, kolejna daty, następna czasu. Ostatnia funkcja zamienia dzień tygodnia w formacie numerycznym na ciąg znaków.

Klasa dla obsługi zegara RTC DS3231:

  1. class RtcDs3231:
  2.     address = 0x68
  3.     register = 0x00
  4.     bus = smbus.SMBus(1)
  5.  
  6.     #sec min hour weekDay day month year
  7.     NowTime = [0x00,0x00,0x18,0x04,0x12,0x08,0x17]
  8.     weekDay = ["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"];
  9.  
  10.     ########################################
  11.     #set time base on system time
  12.     def ds3231SetSystemTime():
  13.         dataTable = SystemTimeDate.getTimeDate()
  14.                         #sec min hour weekDay day month year
  15.         tableToPass = [dataTable[0], dataTable[1], dataTable[2], dataTable[3],
  16.                         dataTable[4], dataTable[5], (dataTable[6] - 2000)]
  17.  
  18.         RtcDs3231.bus.write_i2c_block_data(RtcDs3231.address,
  19.                                            RtcDs3231.register,
  20.                                            RtcDs3231.NowTime)
  21.  
  22.     ########################################
  23.     #set time base on static value NowTime
  24.     def ds3231SetTime():
  25.         RtcDs3231.bus.write_i2c_block_data(RtcDs3231.address,
  26.                                            RtcDs3231.register,
  27.                                            RtcDs3231.NowTime)
  28.  
  29.     ########################################
  30.     #set time with passing parameters
  31.     def ds3231SetTimeParam(dsSec, dsMin, dsHour, dsWeek, dsDay, dsMonth, dsYear):
  32.         timeToSet = [dsSec, dsMin, dsHour, dsWeek, dsDay, dsMonth, dsYear]
  33.         RtcDs3231.bus.write_i2c_block_data(RtcDs3231.address,
  34.                                  RtcDs3231.register,
  35.                                  timeToSet)
  36.  
  37.     ########################################
  38.     #read time and date from device
  39.     def ds3231ReadTime():
  40.         return RtcDs3231.bus.read_i2c_block_data(RtcDs3231.address,
  41.                                        RtcDs3231.register,
  42.                                        7);
  43.  
  44.     ########################################
  45.     #read and dislay time and date
  46.     def ds3231GetTimeData():
  47.         RtcDs3231.readTime = RtcDs3231.ds3231ReadTime()
  48.         RtcDs3231.readTime[0] = RtcDs3231.readTime[0]&0x7F  #sec
  49.         RtcDs3231.readTime[1] = RtcDs3231.readTime[1]&0x7F  #min
  50.         RtcDs3231.readTime[2] = RtcDs3231.readTime[2]&0x3F  #hour
  51.         RtcDs3231.readTime[3] = RtcDs3231.readTime[3]&0x07  #week
  52.         RtcDs3231.readTime[4] = RtcDs3231.readTime[4]&0x3F  #day
  53.         RtcDs3231.readTime[5] = RtcDs3231.readTime[5]&0x1F  #month
  54.         print("20%x/%x/%x %x:%x:%x %s" %(RtcDs3231.readTime[6],
  55.                                          RtcDs3231.readTime[5],
  56.                                          RtcDs3231.readTime[4],
  57.                                          RtcDs3231.readTime[2],
  58.                                          RtcDs3231.readTime[1],
  59.                                          RtcDs3231.readTime[0],
  60.                                          RtcDs3231.weekDay[RtcDs3231.readTime[3]-1]))

Idąc od góry po funkcjach. ds3231SetSytemTime wysyła do układu pobrany czas systemowy. ds3231SetTime ustawia czas jaki jest umieszczony w tablicy NowTime. ds3231SetTimeParam ustawia czas podany przez użytkownika. No i teraz funkcje główne czyli ds3231ReadTime pobiera czas z układu. Ostatnia funkcja ds32321GetTimeData pobiera dane z układu, po czym je przekształca i wypisuje na ekranie.

Główna funkcja programu będzie wyglądała następująco:

  1. import os
  2. import sys
  3. import time
  4. from rtcDS3231.rtcDS3231 import RtcDs3231
  5. if __name__ == '__main__':
  6.     RtcDs3231.ds3231SetTime()
  7.    
  8.     while 1:
  9.         RtcDs3231.ds3231GetTimeData()
  10.         time.sleep(1)

W przypadku wykorzystywania tego układu jako zegar systemowy nie ma możliwości

Kody do plików można pobrać z dysku Google pod tym linkiem. W zakładce Python.