[Rozwiązany] RTC, działania na podstawie czasu

Pytania, kody i porady dotyczące nie tylko Bascom.
Awatar użytkownika
pimowo
Posty: 392
Rejestracja: 28 maja 2016, 10:07

[Rozwiązany] RTC, działania na podstawie czasu

Post autor: pimowo » 21 sty 2020, 7:51

Hej,
Panowie, drapię się po głowie i nie mogę nic mądrego wymyślić odnośnie sterowania na podstawie czasu.
Mam dwie zagadki:
0. RTC to DS3231 - zegar działa i wszystko jest OK
1. Liczenie czasu (dni) od zmiennej. Chciałbym ustawić sobie jakąś zmienną, dajmy "start" (zmienną zapiszę do eeprom, aby nie zginęła) i od tej zmiennej liczyć dni. Przykładowo "start" ustawiłem w dniu 01/01/2020, a dziś mamy 21/01/2020 Jak obliczyć ile dni minęło? Jak obliczyć gdy "start" będzie np. 01/02/2020, a na zegarze już 15/08/2020?
2. Sterowanie wyjściami na podstawie czasu, taka czasówka włącz/wyłącz - tu to w ogóle już nie ogarniam.
Jak to miało by działać:
a) 8 wyjść
b) każde z wyjść:
- 4 czasy załączania na dobę
- włącz/wyłącz czas 1, 2, 3 i 4
- czas załączenia/wyłączenia to godzina, minuta, sekunda i dzień tygodnia - dla każdego z osobna

Jak zacząłem to rozpisywać to wychodzą mi dziesiątki linii kodu i mnóstwo zmiennych :(
Może ktoś robił coś podobnego i podzieli się pomysłem jak to ugryźć?

Z góry dziękuję i pozdrawiam.
Piotrek
Ostatnio zmieniony 04 lut 2020, 20:58 przez pimowo, łącznie zmieniany 1 raz.
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: RTC, działania na podstawie czasu

Post autor: niveasoft » 21 sty 2020, 8:15

Poczytaj o Sysday() Date() Datetime i podobnych w helpie. Są gotowe funkcje. Sam mam kilka gotowych czasówek z oledami, ze zwykłymi wyświetlaczami alfanumerycznymi, z aplikacjami na fona itd :D
Nawet sterownik dzwonów ma kalendarz na cały rok liturgiczny i pinka ludziom różnie w różnych porach roku ahahahha :D Podobnie sterownik Kurantów z MP3.

Np. W przypadku pierwszego pytania możesz chyba policzyć tak:
  1. Dim Myword1 As Word, Myword2 As Word
  2. Myword1 = Sysday("01/01/20")
  3. Myword2 = Sysday("02/02/20")
  4. Myword2 = Myword2 - Myword1
  5. Print "Minelo "; myword2 ; " dni."
Powinno zadzialać nawet w symulatorze, ale nie sprawdzałem.

Włączenie czegoś o danej porze w danym dniu tez jest proste. Zamieniasz datę i godzinę z RTC na LONG. Tu nic nie musisz robić. Puste nawiasy Target = SYSSEC() i Bascom sam to wyciągnie z zegarka. Potem liczysz drugi Long wpisując żądaną datę i godzinę. Target = SYSSEC(strTime, strDate) Potem piszesz warunek "Jeżeli Long1 = Long2 Then ....włącz/wyłącz.
  1. Dim Long1 As Long , Long2 As Long
  2. Long1 = Syssec()
  3. Long2 = Sysec("08:00:00","21/01/20")
  4. If Long1 = Long2 Then
  5.  
  6. End If
Awatar użytkownika
pimowo
Posty: 392
Rejestracja: 28 maja 2016, 10:07

Re: RTC, działania na podstawie czasu

Post autor: pimowo » 21 sty 2020, 8:43

Dzięki, będę wieczorkiem próbował.
Mówisz, że to proste he he, a ja już spędziłem kilka roboczogodzin nad tym i nic mi nie wychodziło. Tyle, że ja próbowałem inaczej, a dokładnie to tam gdzie program co sekundę wskakuje aby odczytać zegar dałem kilka if-ów i porównywałem czas z ustawionym czasem załączenia - dla jednego timera i jednego czasu gdy miał pracować codziennie to było OK, ale dla kilku timerów który ma kilka ustawień to wychodził mi jakiś kosmos normalnie.

A tak jeszcze teraz mnie naszło... Co zrobić w sytuacji gdy ustawię czas startu i czas zatrzymania, a w międzyczasie będzie jakiś zanik napięcia?
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: RTC, działania na podstawie czasu

Post autor: niveasoft » 21 sty 2020, 8:57

Chyba jeszcze tego nie czujesz ;)
Policz trzy Longi. Czas włączenia, wyłaczenia i czas aktualny.
"Jeśli Long czasu włączenia jest mniejszy od czasu aktualnego i Long czasu wyłączenia większy od czasu aktualnego to włącz urządzenie."
Taką procedurą możesz się przelecieć np. tylko po restarcie a potem już na bieżąco.

Na taką minimalną baze danych potrzebujesz 2x6Bajtów na jeden cykl Włącz/Wyłącz.
Czyli na bazę 10 wpisów potrzebujesz 120bajtów Eeprom - nie jest źle...
Warto jednak dodać do bazy numer porzadkowy i które wyjście ma być uruchamiane. Wyjdzie np po 14 bajtów...
Na bajtach działa się szybciej niz na stringach.

Robisz więc bazę "Dim Mybuff(140) As Byte" a potem możesz sobie latać po bazie np. najprostszym "For N = 1 to 126 Step 14" :D albo "Mypointer = Mypointer + 14" itd...
Awatar użytkownika
pimowo
Posty: 392
Rejestracja: 28 maja 2016, 10:07

Re: RTC, działania na podstawie czasu

Post autor: pimowo » 21 sty 2020, 10:33

No i znów namieszał mi w głowie... :shock:

Usiądę na spokojnie i jeszcze poczytam, teraz to chociaż wiem w którą stronę iść. Dzięki
Awatar użytkownika
pimowo
Posty: 392
Rejestracja: 28 maja 2016, 10:07

Re: RTC, działania na podstawie czasu

Post autor: pimowo » 21 sty 2020, 23:28

Dziś troszkę brakło czasu, ale zmajstrowałem coś takiego odnośnie punktu "1"
Kod testowy odpaliłem na płytce testowej z ATmega32 (docelowo ATmega2560) i LCD 16x2 (docelowo LCD graficzny 320x240)
.
  1. $regfile = "m32def.dat"
  2. $crystal = 16000000
  3. $swstack = 64
  4. $hwstack = 64
  5. $framesize = 200
  6.  
  7. Config Submode = New
  8.  
  9. $lib "bl_Lcd_i2c.lib"
  10.  
  11. Config Lcd = 16x2
  12.  
  13. Const Pcf_d4 = 4
  14. Const Pcf_d5 = 5
  15. Const Pcf_d6 = 6
  16. Const Pcf_d7 = 7
  17. Const Pcf_rs = 0
  18. Const Pcf_rw = 1
  19. Const Pcf_e1 = 2
  20.  
  21. Dim _lcd_e As Byte
  22. Dim Backlight As Byte
  23.  
  24. Backlight_on Alias &H08
  25. Backlight_off Alias &H00
  26. Backlight = Backlight_on
  27. _lcd_e = 128
  28.  
  29. Const Pcf8574_lcd = &H4E
  30.  
  31. Waitms 100 : Cls
  32.  
  33. Config Scl = Portc.0
  34. Config Sda = Portc.1
  35. I2cinit
  36. Config Twi = 400000
  37.  
  38. Config Clock = User
  39. Config Date = Dmy , Separator = /
  40.  
  41. Const Ds3231w = &HD0
  42. Const Ds3231r = &HD1
  43.  
  44. Dim Weekday As Byte
  45. Dim Myword1 As Word , Myword2 As Word
  46.  
  47. Dim Dzien As Byte , Miesiac As Byte , Rok As Byte
  48. Dim Data_start As String * 8
  49.  
  50. Dzien = 1
  51. Miesiac = 1
  52. Rok = 20
  53.  
  54. If Dzien < 10 Then
  55.  
  56.    Data_start = "0" + Str(dzien) + "/"
  57.  
  58. Else
  59.  
  60.    Data_start = Str(dzien) + "/"
  61.  
  62. End If
  63.  
  64. If Miesiac < 10 Then
  65.  
  66.    Data_start = Data_start + "0" + Str(miesiac) + "/"
  67.  
  68. Else
  69.  
  70.    Data_start = Data_start + Str(miesiac) + "/"
  71.  
  72. End If
  73.  
  74. Data_start = Data_start + Str(rok)
  75.  
  76. 'Time$ = "23:00:00"
  77. 'Date$ = "21/01/20"
  78.  
  79. Enable Interrupts
  80.  
  81. Do
  82.  
  83.    Locate 1 , 1 : Lcd Time$
  84.    Locate 2 , 1 : Lcd Date$
  85.  
  86.    Myword1 = Sysday(data_start)
  87.    Myword2 = Sysday(date$)
  88.    Myword2 = Myword2 - Myword1
  89.  
  90.    Locate 1 , 11 : Lcd "Minelo"
  91.    Locate 2 , 11 : Lcd Myword2 ; "dni"
  92.  
  93.    Wait 1
  94.  
  95. Loop
  96. End
  97.  
  98. Getdatetime:
  99.  
  100.    I2cstart                                                 ' Generate start code
  101.    I2cwbyte Ds3231w                                         ' send address
  102.    I2cwbyte 0                                               ' start address in 1307
  103.    I2cstart                                                 ' Generate start code
  104.    I2cwbyte Ds3231r                                         ' send address
  105.    I2crbyte _sec , Ack
  106.    I2crbyte _min , Ack                                      ' MINUTES
  107.    I2crbyte _hour , Ack                                     ' Hours
  108.    I2crbyte Weekday , Ack                                   ' Day of Week
  109.    I2crbyte _day , Ack                                      ' Day of Month
  110.    I2crbyte _month , Ack                                    ' Month of Year
  111.    I2crbyte _year , Nack                                    ' Year
  112.    I2cstop
  113.  
  114.    _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
  115.    _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
  116.  
  117. Return
  118.  
  119. Setdate:
  120.  
  121.    _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
  122.  
  123.    I2cstart                                                 ' Generate start code
  124.    I2cwbyte Ds3231w                                         ' send address
  125.    I2cwbyte 4                                               ' starting address in 1307
  126.    I2cwbyte _day                                            ' Send Data to SECONDS
  127.    I2cwbyte _month                                          ' MINUTES
  128.    I2cwbyte _year                                           ' Hours
  129.    I2cstop
  130.  
  131. Return
  132.  
  133. Settime:
  134.  
  135.    _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
  136.  
  137.    I2cstart                                                 ' Generate start code
  138.    I2cwbyte Ds3231w                                         ' send address
  139.    I2cwbyte 0                                               ' starting address in 1307
  140.    I2cwbyte _sec                                            ' Send Data to SECONDS
  141.    I2cwbyte _min                                            ' MINUTES
  142.    I2cwbyte _hour                                           ' Hours
  143.    I2cstop
  144.  
  145. Return
  146.  
  147. Weekdays:
  148.  
  149. Data "Poniedzialek" , "Wtorek" , "Sroda" , "Czwartek" , "Piatek" , "Sobota" , "Niedziela"
.
Wygląda na to, że działa.
Przygotowałem sobie od razu zmienne abym mógł wpisać dzień, miesiąc i rok dla dnia "start"

Jutro może uda się pokombinować z punktem "2" :D
Awatar użytkownika
pimowo
Posty: 392
Rejestracja: 28 maja 2016, 10:07

Re: RTC, działania na podstawie czasu

Post autor: pimowo » 24 sty 2020, 11:55

Jednak muszę prosić o pomoc ponieważ kompletnie nie wiem jak ugryźć tą bazę z danymi dla czasówek :(

Próbowałem sobie to jakoś rozrysować na papierze, ale nie wiem jak to przełożyć na kod uC.
Mam 8 timerów, które mogę włączyć lub wyłączyć - jeżeli wyłączę timer to żadne wpisy w nim nie działają, ale jak włączę to timer działa według ustawionego harmonogramu. W każdym timerze mam 4 czasy, które mogę włączyć lub wyłączyć - jeżeli wyłączę któryś czas to to nie będzie brane pod uwagę, ale jak włączę to ma działać według ustawionego czasu, czyli "start: godzina, minuta i sekunda" oraz "stop: godzina, minuta i sekunda" oraz muszę ustawić dzień/dni tygodnia.
Do tego dochodzi jeszcze jak uzupełniać taką bazę no i jak wyciągnąć dane z tej bazy aby sterować wyjściami? Dodatkowo chciałbym tą bazę trzymać w eeprom*
Zaczynam się zastanawiać czy to w ogóle jest możliwe.

*Dane, które chcę zapisywać w nieulotnej pamięci to lepiej zapisywać w uC czy może już się szykować na coś zewnętrznego? Jeżeli coś zewnętrznego to co kupić?

Mój testowy kod (działa dla jednego przekaźnika) wygląda teraz tak:
.
  1. '
  2. '
  3. '**********************************************************
  4. 'MIKROKONTROLER
  5.  
  6. $regfile = "m32def.dat"                                     'ATmega32
  7. $crystal = 16000000                                         'zewnętrzny rezonator  16MHz
  8.  
  9. $swstack = 64
  10. $hwstack = 64
  11. $framesize = 200
  12.  
  13. '**********************************************************
  14. 'WYJŚCIA "przekaźniki"
  15.  
  16. Config Porta.0 = Output : Porta.0 = 0 : Pk_1 Alias Porta.0  'wyjście nr1
  17. Config Porta.1 = Output : Porta.1 = 0 : Pk_2 Alias Porta.1  'wyjście nr2
  18. Config Porta.2 = Output : Porta.2 = 0 : Pk_3 Alias Porta.2  'wyjście nr3
  19. Config Porta.3 = Output : Porta.3 = 0 : Pk_4 Alias Porta.3  'wyjście nr4
  20. Config Porta.4 = Output : Porta.4 = 0 : Pk_5 Alias Porta.4  'wyjście nr5
  21. Config Porta.5 = Output : Porta.5 = 0 : Pk_6 Alias Porta.5  'wyjście nr6
  22. Config Porta.6 = Output : Porta.6 = 0 : Pk_7 Alias Porta.6  'wyjście nr7
  23. Config Porta.7 = Output : Porta.7 = 0 : Pk_8 Alias Porta.7  'wyjście nr8
  24.  
  25. '**********************************************************
  26. 'WYŚWIETLACZ LCD
  27.  
  28. $lib "bl_Lcd_i2c.lib"                                       'biblioteka I2C LCD
  29.  
  30. Config Lcd = 16x2                                           'wyświetlacz 16x2
  31.  
  32. Const Pcf_d4 = 4                                            'pin D4
  33. Const Pcf_d5 = 5                                            'pin D5
  34. Const Pcf_d6 = 6                                            'pin D6
  35. Const Pcf_d7 = 7                                            'pin D7
  36. Const Pcf_rs = 0                                            'pin RS
  37. Const Pcf_rw = 1                                            'pin RW
  38. Const Pcf_e1 = 2                                            'pin E
  39.  
  40. Dim _lcd_e As Byte
  41. Dim Backlight As Byte
  42.  
  43. Backlight_on Alias &H08
  44. Backlight_off Alias &H00
  45. Backlight = Backlight_on                                    'włącz podświetlenie
  46. _lcd_e = 128
  47.  
  48. Const Pcf8574_lcd = &H4E                                    'adres PCF8574
  49.  
  50. Waitms 100                                                  'odczekaj 100ms
  51.  
  52. Cls                                                         'wyczyść ekran
  53.  
  54. '**********************************************************
  55. 'I2C
  56.  
  57. Config Scl = Portc.0                                        'pin SCL
  58. Config Sda = Portc.1                                        'pin SDA
  59. I2cinit
  60. Config Twi = 400000                                         'prędkość I2C
  61.  
  62. '**********************************************************
  63. 'DS3231
  64.  
  65. Config Clock = User
  66. Config Date = Dmy , Separator = "/"                         'oddziel datę ukośnikiem
  67.  
  68. Const Ds3231w = &HD0                                        'adres DS3231 do zapisu
  69. Const Ds3231r = &HD1                                        'adres DS3231 do odczytu
  70.  
  71. '**********************************************************
  72. 'DZIEŃ "START"
  73.  
  74. Dim Co2_dzien As Byte , Co2_miesiac As Byte , Co2_rok As Byte
  75. Dim Co2_dzien_start As Word , Co2_dzien_teraz As Word
  76. Dim Co2_data_start_str As String * 8
  77.  
  78. Co2_dzien = 1                                               'ustaw dzień DNIA "START"
  79. Co2_miesiac = 1                                             'ustaw miesiąc DNIA "START"
  80. Co2_rok = 20                                                'ustaw rok DNIA "START"
  81.  
  82. '**********************************************************
  83. 'ZEGAR
  84.  
  85. Dim Dzien_tygodnia As Byte , Dzien_tygodnia_str As String * 2
  86. Dim Date_str As String * 10
  87.  
  88. '_hour = 22                                                  'ustaw godzinę
  89. '_min = 0                                                    'ustaw minutę
  90. '_sec = 0                                                    'ustaw sekundę
  91. 'Gosub Settime                                               'zapisz czas
  92.  
  93. '_day = 24                                                   'ustaw dzień
  94. '_month = 1                                                  'ustaw miesiąc
  95. '_year = 20                                                  'ustaw rok
  96. 'Gosub Setdate                                               'zapisz datę
  97.  
  98. '**********************************************************
  99. 'CZASÓWKA
  100.  
  101. Dim Pk_czas_start As String * 8                             'godzina włączenia
  102. 'Dim Pk_data_start As String * 8                             'data włączenia
  103. Dim Pk_long_start As Long                                   'czas włączenia
  104.  
  105. Dim Pk_czas_stop As String * 8                              'godzina wyłączenia
  106. 'Dim Pk_data_stop As String * 8                              'data wyłączenia
  107. Dim Pk_long_stop As Long                                    'czas wyłączenia
  108.  
  109. Dim Pk_dzien_tygodnia As Byte                               'dzień tygodnia
  110.  
  111. Dim Pk_long_teraz As Long                                   'teraźniejszy czas i data
  112.  
  113. Pk_czas_start = "11:00:00"                                  'ustaw godzinę włączenia
  114. 'Pk_data_start = "24/01/20"                                  'ustaw datę włączenia
  115.  
  116. Pk_czas_stop = "12:00:00"                                   'ustaw godzinę wyłączenia
  117. 'Pk_data_stop = "24/01/20"                                   'ustaw datę wyłączenia
  118.  
  119. Pk_dzien_tygodnia = 5                                       'ustaw dzień tygodnia włączenia/wyłączenia
  120.  
  121. '**********************************************************
  122. 'GLOBALNE PRZERWANIA
  123.  
  124. Enable Interrupts
  125.  
  126.  
  127. '==========================================================
  128. 'GOŁÓWNA PĘTLA PROGRAMU
  129. '==========================================================
  130.  
  131. Do
  132.  
  133. '----------------------------------------------------------
  134. 'WYLICZ ILE DNI MINĘŁO OD DNIA "START" DO TERAZ
  135.  
  136.    If Co2_dzien < 10 Then                                   'jeżeli dzień jest mniejszy niż 10 to dodaj "0"
  137.  
  138.       Co2_data_start_str = "0" + Str(co2_dzien) + "/"
  139.  
  140.    Else
  141.  
  142.       Co2_data_start_str = Str(co2_dzien) + "/"
  143.  
  144.    End If
  145.  
  146.    If Co2_miesiac < 10 Then                                 'jeżeli miesiąc jest mniejszy niż 10 to dodaj "0"
  147.  
  148.       Co2_data_start_str = Co2_data_start_str + "0" + Str(co2_miesiac) + "/"
  149.  
  150.    Else
  151.  
  152.       Co2_data_start_str = Co2_data_start_str + Str(co2_miesiac) + "/"
  153.  
  154.    End If
  155.  
  156.    Co2_data_start_str = Co2_data_start_str + Str(co2_rok)   'utwórz string daty dnia "START"
  157.  
  158.    Co2_dzien_start = Sysday(co2_data_start_str)             'data dnia "START"
  159.    Co2_dzien_teraz = Sysday()                               'teraźniejsza data
  160.    Co2_dzien_teraz = Co2_dzien_teraz - Co2_dzien_start      'odejmij datę dnia "START" od teraźniejszej daty
  161.  
  162.    Locate 2 , 15 : Lcd Co2_dzien_teraz                      'wyświetl ile dni minęło od dnia "START"
  163.  
  164. '----------------------------------------------------------
  165. 'WYLICZ DZIEŃ TYGODNIA
  166.  
  167.    Dzien_tygodnia = Dayofweek()
  168.    Dzien_tygodnia_str = Lookupstr(dzien_tygodnia , Dni_tygodnia)
  169.  
  170. '----------------------------------------------------------
  171. 'ZMIANA WYŚWIETLANIA ROKU Z 01/01/20 NA 01/01/2020
  172.  
  173.    Date_str = Date(_day)
  174.    Date_str = Mid(date_str , 1 , 6) + "20"
  175.    Date_str = Date_str + Str(_year)
  176.  
  177. '----------------------------------------------------------
  178. 'WYŚWIETL CZAS, DATĘ I DZIEŃ TYGODNIA
  179.  
  180.    Locate 1 , 1 : Lcd Time$                                 'wyświetl czas
  181.    Locate 2 , 1 : Lcd Date_str ; " " ; Dzien_tygodnia_str   'wyświetl datę i dzień tygodnia
  182.  
  183. '----------------------------------------------------------
  184. 'OBLICZ CZAS ZAŁĄCZANIA
  185.  
  186.    Pk_long_teraz = Syssec()                                 'czas teraźniejszy
  187.    'Pk_long_start = Syssec(pk_czas_start , Pk_data_start)    'czas i data włączenia
  188.    Pk_long_start = Syssec(pk_czas_start , Date$)            'czas i data włączenia
  189.    'Pk_long_stop = Syssec(pk_czas_stop , Pk_data_stop)       'czas i data wyłączenia
  190.    Pk_long_stop = Syssec(pk_czas_stop , Date$)              'czas i data wyłączenia
  191.  
  192. '----------------------------------------------------------
  193. 'WŁĄCZ/WYŁĄCZ WYJŚCIA
  194.  
  195. 'Jeżeli zostaną spełnione warunki:
  196. 'czas włączenia
  197. 'dzień tygodnia
  198. 'To włącz wyjście. Jeżeli któryś z warunków nie zostanie spełniony to wyłącz wyjście
  199.  
  200.    If Pk_long_start <= Pk_long_teraz And Pk_long_stop >= Pk_long_teraz And Pk_dzien_tygodnia = Dzien_tygodnia Then
  201.  
  202.       Set Pk_1                                              'włącz przekaźnik
  203.  
  204.       Locate 1 , 11 : Lcd "PK ON "                          'wyświetl, że przekaźnik jest włączony
  205.  
  206.    Else
  207.  
  208.       Reset Pk_1                                            'wyłącz przekaźnik
  209.  
  210.       Locate 1 , 11 : Lcd "PK OFF"                          'wyświetl, że przekaźnik jest wyłączony
  211.  
  212.    End If
  213.  
  214. Loop
  215. End
  216.  
  217. '==========================================================
  218. 'KONIEC GOŁÓWNEJ PĘTLI PROGRAMU
  219. '==========================================================
  220.  
  221.  
  222. '**********************************************************
  223. 'ODCZYT/ZAPIS ZEGARA
  224.  
  225. Getdatetime:                                                'czytaj czas i datę
  226.  
  227.    I2cstart                                                 'wygeneruj kod startowy
  228.    I2cwbyte Ds3231w                                         'wyślij adres
  229.    I2cwbyte 0                                               'adres początkowy DS3231
  230.    I2cstart                                                 'Wygeneruj kod startowy
  231.    I2cwbyte Ds3231r                                         'wyślij adres
  232.    I2crbyte _sec , Ack                                      'sekunda
  233.    I2crbyte _min , Ack                                      'minuta
  234.    I2crbyte _hour , Ack                                     'godzina
  235.    I2crbyte Dzien_tygodnia , Ack                            'dzień tygodnia
  236.    I2crbyte _day , Ack                                      'dzień
  237.    I2crbyte _month , Ack                                    'miesiąc
  238.    I2crbyte _year , Nack                                    'rok
  239.    I2cstop
  240.  
  241.    _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
  242.    _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
  243.  
  244. Return
  245.  
  246. Setdate:                                                    'zapisz datę
  247.  
  248.    _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
  249.  
  250.    I2cstart                                                 'wygeneruj kod startowy
  251.    I2cwbyte Ds3231w                                         'wyślij adres
  252.    I2cwbyte 4                                               'adres początkowy DS3231
  253.    I2cwbyte _day                                            'dzień
  254.    I2cwbyte _month                                          'miesiąc
  255.    I2cwbyte _year                                           'rok
  256.    I2cwbyte Dzien_tygodnia                                  'dzien tygodnia
  257.    I2cstop
  258.  
  259. Return
  260.  
  261. Settime:                                                    'zapisz czas
  262.  
  263.    _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
  264.  
  265.    I2cstart                                                 'wygeneruj kod startowy
  266.    I2cwbyte Ds3231w                                         'wyślij adres
  267.    I2cwbyte 0                                               'adres początkowy DS3231
  268.    I2cwbyte _sec                                            'sekunda
  269.    I2cwbyte _min                                            'minuta
  270.    I2cwbyte _hour                                           'godzina
  271.    I2cstop
  272.  
  273. Return
  274.  
  275. '**********************************************************
  276. 'DNI TYGODNIA
  277.  
  278. Dni_tygodnia:
  279.  
  280. Data "Pn" , "Wt" , "Sr" , "Cz" , "Pt" , "So" , "Nd"         'dzień tygodnia do wyświetlenia
Awatar użytkownika
Henryk
Posty: 348
Rejestracja: 22 sty 2018, 17:20

Re: RTC, działania na podstawie czasu

Post autor: Henryk » 24 sty 2020, 20:34

Witam 8-)

Na sam początek zrezygnowałbym z sekund , taka precyzja uważam jest zbędna w tego typu sterownikach .
Nie będę silił się na pisanie przykładu w Bascom , bo znowu wpadnę w wir elektroniki , a tego teraz nie chce ;)
Jak ja to widzę :
1. Podprogram zapis danych rok , miesiąc , dzień , godziny , minuty , sekundy do RTC .
2. Podprogram zapis do EEprom start/stop danych rok , miesiąc , dzień , godziny , minuty .
3.Warunek if start/stop zamknięty w pętli For Next w której odczytuję dane aktualne z zegara RTC i dane do porównania z EEprom .
Celowo zrezygnowałem z sekund , bo może się całe sprawdzanie pętli For Next nie zmieścić w czasie jednej sekundy zegara RTC ( to tylko moje przypuszczenia )
Awatar użytkownika
pimowo
Posty: 392
Rejestracja: 28 maja 2016, 10:07

Re: RTC, działania na podstawie czasu

Post autor: pimowo » 25 sty 2020, 10:52

Henryk pisze:
24 sty 2020, 20:34
Na sam początek zrezygnowałbym z sekund , taka precyzja uważam jest zbędna w tego typu sterownikach.
Pomysł sekund pojawił się ponieważ chciałem tym też sterować pompami perystaltycznymi, ale to chyba jednak zły pomysł. Pompki zrobię na osobnym sterowaniu - mam do tego fajny kod, ale niestety w Arduino.
Kombinuję dalej ;)

Zrobiłem bazę (mam nadzieję, że dobrze zrozumiałem co Bartek pisał) do której mogę wpisać: czas 1-4 dla 8 czasówek, godzinę włączenia, minutę włączenia, godzinę wyłączenia, minutę włączenia, dni tygodnia kiedy ma pracować dana czasówka oraz przypisanie przekaźnika do czasówki
.
  1. '
  2. '
  3. '**********************************************************
  4. 'MIKROKONTROLER
  5.  
  6. $regfile = "m32def.dat"                                     'ATmega32
  7. $crystal = 16000000                                         'zewnętrzny rezonator  16MHz
  8.  
  9. $swstack = 64
  10. $hwstack = 64
  11. $framesize = 200
  12.  
  13. '**********************************************************
  14. 'WYJŚCIA "przekaźniki"
  15.  
  16. Config Porta.0 = Output : Porta.0 = 0 : Pk_1 Alias Porta.0  'wyjście nr1
  17. Config Porta.1 = Output : Porta.1 = 0 : Pk_2 Alias Porta.1  'wyjście nr2
  18. Config Porta.2 = Output : Porta.2 = 0 : Pk_3 Alias Porta.2  'wyjście nr3
  19. Config Porta.3 = Output : Porta.3 = 0 : Pk_4 Alias Porta.3  'wyjście nr4
  20. Config Porta.4 = Output : Porta.4 = 0 : Pk_5 Alias Porta.4  'wyjście nr5
  21. Config Porta.5 = Output : Porta.5 = 0 : Pk_6 Alias Porta.5  'wyjście nr6
  22. Config Porta.6 = Output : Porta.6 = 0 : Pk_7 Alias Porta.6  'wyjście nr7
  23. Config Porta.7 = Output : Porta.7 = 0 : Pk_8 Alias Porta.7  'wyjście nr8
  24. Config Portd.0 = Output : Portd.0 = 0 : Pk_9 Alias Portd.0  'wyjście nr9
  25. Config Portd.1 = Output : Portd.1 = 0 : Pk_10 Alias Portd.1 'wyjście nr19
  26. Config Portd.2 = Output : Portd.2 = 0 : Pk_11 Alias Portd.2 'wyjście nr11
  27. Config Portd.3 = Output : Portd.3 = 0 : Pk_12 Alias Portd.3 'wyjście nr12
  28. Config Portd.4 = Output : Portd.4 = 0 : Pk_13 Alias Portd.4 'wyjście nr13
  29. Config Portd.5 = Output : Portd.5 = 0 : Pk_14 Alias Portd.5 'wyjście nr14
  30. Config Portd.6 = Output : Portd.6 = 0 : Pk_15 Alias Portd.6 'wyjście nr15
  31. Config Portd.7 = Output : Portd.7 = 0 : Pk_16 Alias Portd.7 'wyjście nr16
  32.  
  33. '**********************************************************
  34. 'WYŚWIETLACZ LCD
  35.  
  36. $lib "bl_Lcd_i2c.lib"                                       'biblioteka I2C LCD
  37.  
  38. Config Lcd = 16x2                                           'wyświetlacz 16x2
  39.  
  40. Const Pcf_d4 = 4                                            'pin D4
  41. Const Pcf_d5 = 5                                            'pin D5
  42. Const Pcf_d6 = 6                                            'pin D6
  43. Const Pcf_d7 = 7                                            'pin D7
  44. Const Pcf_rs = 0                                            'pin RS
  45. Const Pcf_rw = 1                                            'pin RW
  46. Const Pcf_e1 = 2                                            'pin E
  47.  
  48. Dim _lcd_e As Byte
  49. Dim Backlight As Byte
  50.  
  51. Backlight_on Alias &H08
  52. Backlight_off Alias &H00
  53. Backlight = Backlight_on                                    'włącz podświetlenie
  54. _lcd_e = 128
  55.  
  56. Const Pcf8574_lcd = &H4E                                    'adres PCF8574
  57.  
  58. Waitms 100                                                  'odczekaj 100ms
  59.  
  60. Cls                                                         'wyczyść ekran
  61.  
  62. '**********************************************************
  63. 'I2C
  64.  
  65. Config Scl = Portc.0                                        'pin SCL
  66. Config Sda = Portc.1                                        'pin SDA
  67. I2cinit
  68. Config Twi = 400000                                         'prędkość I2C
  69.  
  70. '**********************************************************
  71. 'DS3231
  72.  
  73. Config Clock = User
  74. Config Date = Dmy , Separator = "/"                         'oddziel datę ukośnikiem
  75.  
  76. Const Ds3231w = &HD0                                        'adres DS3231 do zapisu
  77. Const Ds3231r = &HD1                                        'adres DS3231 do odczytu
  78.  
  79. '**********************************************************
  80. 'ZEGAR
  81.  
  82. Dim Dzien_tygodnia As Byte , Dzien_tygodnia_str As String * 2
  83. Dim Date_str As String * 10
  84.  
  85. '_hour = 14                                                  'ustaw godzinę
  86. '_min = 13                                                   'ustaw minutę
  87. '_sec = 0                                                    'ustaw sekundę
  88. 'Gosub Settime                                               'zapisz czas
  89.  
  90. '_day = 25                                                   'ustaw dzień
  91. '_month = 1                                                  'ustaw miesiąc
  92. '_year = 20                                                  'ustaw rok
  93. 'Gosub Setdate                                               'zapisz datę
  94.  
  95. '**********************************************************
  96. 'CZASÓWKA
  97.  
  98. Dim Czasowka(392) As Byte , Czasowka_ee(392) As Eram Byte
  99.  
  100. 'dane dla testów - docelowe dane będą wpisywane z menu sterownika
  101. Czasowka_ee(1) = 1                                          'włącz pierwszy czas dla czasówki nr1
  102.  
  103. Czasowka_ee(33) = 16                                        'ustaw godzinę włączenia dla pierwszego czasu, czasówki nr1
  104. Czasowka_ee(65) = 0                                         'ustaw minutę włączenia dla pierwszego czasu, czasówki nr1
  105.  
  106. Czasowka_ee(97) = 17                                        'ustaw godzinę wyłączenia dla pierwszego czasu, czasówki nr1
  107. Czasowka_ee(129) = 11                                       'ustaw minutę wyłączenia dla pierwszego czasu, czasówki nr1
  108.  
  109. Czasowka_ee(161) = 1                                        'włącz załączanie pierwszego czasu dla czasówki nr w poniedziałek
  110. Czasowka_ee(193) = 1                                        'włącz załączanie pierwszego czasu dla czasówki nr we wtorek
  111. Czasowka_ee(225) = 1                                        'włącz załączanie pierwszego czasu dla czasówki nr w środę
  112. Czasowka_ee(257) = 1                                        'włącz załączanie pierwszego czasu dla czasówki nr w czwartek
  113. Czasowka_ee(289) = 1                                        'włącz załączanie pierwszego czasu dla czasówki nr w piątek
  114. Czasowka_ee(321) = 1                                        'włącz załączanie pierwszego czasu dla czasówki nr w sobotę
  115. Czasowka_ee(353) = 0                                        'wyłącz załączanie pierwszego czasu dla czasówki nr w niedzielę
  116.  
  117. Czasowka_ee(385) = 1                                        'przypisz przekaźnik "Pk_1" dla czasówki nr1
  118.  
  119. '----------------------------------------------------------
  120. '==========================================================
  121. '----------------------------------------------------------
  122. 'BAZA CZASÓWEK
  123.  
  124. '--------------------------------------------------------------------------------------------------------------------------------
  125. 'czas (zakres 0-1) wyłącz/włącz
  126. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  127.  
  128. 'pozycja w bazie
  129. '1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32
  130.  
  131. '--------------------------------------------------------------------------------------------------------------------------------
  132. 'godzina start (zakres 0-23)
  133. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  134.  
  135. 'pozycja w bazie
  136. '33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64
  137.  
  138. '--------------------------------------------------------------------------------------------------------------------------------
  139. 'minuta start (zakres 0-59)
  140. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  141.  
  142. 'pozycja w bazie
  143. '65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96
  144.  
  145. '--------------------------------------------------------------------------------------------------------------------------------
  146. 'godzina stop (zakres 0-23)
  147. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  148.  
  149. 'pozycja w bazie
  150. '97  98  99  100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
  151.  
  152. '--------------------------------------------------------------------------------------------------------------------------------
  153. 'minuta stop (zakres 0-59)
  154. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  155.  
  156. 'pozycja w bazie
  157. '129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
  158.  
  159. '--------------------------------------------------------------------------------------------------------------------------------
  160. 'poniedziałek (zakres 0-1) wyłącz/włącz
  161. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  162.  
  163. 'pozycja w bazie
  164. '161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
  165.  
  166. '--------------------------------------------------------------------------------------------------------------------------------
  167. 'wtorek (zakres 0-1) wyłącz/włącz
  168. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  169. 'pozycja w bazie
  170.  
  171. '193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
  172.  
  173. '--------------------------------------------------------------------------------------------------------------------------------
  174. 'środa (zakres 0-1) wyłącz/włącz
  175. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  176.  
  177. 'pozycja w bazie
  178. '225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
  179.  
  180. '--------------------------------------------------------------------------------------------------------------------------------
  181. 'czwartek (zakres 0-1) wyłącz/włącz
  182. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  183.  
  184. 'pozycja w bazie
  185. '257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
  186.  
  187. '--------------------------------------------------------------------------------------------------------------------------------
  188. 'piątek (zakres 0-1) wyłącz/włącz
  189. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  190.  
  191. 'pozycja w bazie
  192. '289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
  193.  
  194. '--------------------------------------------------------------------------------------------------------------------------------
  195. 'sobota (zakres 0-1) wyłącz/włącz
  196. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  197.  
  198. 'pozycja w bazie
  199. '321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
  200.  
  201. '--------------------------------------------------------------------------------------------------------------------------------
  202. 'niedziela (zakres 0-1) wyłącz/włącz
  203. '1-1 1-2 1-3 1-4 2-1 2-2 2-3 2-4 3-1 3-2 3-3 3-4 4-1 4-2 4-3 4-4 5-1 5-2 5-3 5-4 6-1 6-2 6-3 6-4 7-1 7-2 7-3 7-4 8-1 8-2 8-3 8-4
  204.  
  205. 'pozycja w bazie
  206. '353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
  207.  
  208. '--------------------------------------------------------------------------------------------------------------------------------
  209. 'przekaźnik (zakres 1-16) przypisz przekaźnik do czasówki
  210. '1               2               3               4               5               6               7               8
  211.  
  212. 'pozycja w bazie
  213. '385             386             387             388             389             390             391             392
  214.  
  215. '--------------------------------------------------------------------------------------------------------------------------------
  216. 'Wczytaj dane czasówek z eeprom
  217.  
  218. Dim N As Word
  219.  
  220. For N = 1 To 392
  221.    Czasowka(n) = Czasowka_ee(n)
  222. Next
  223.  
  224. Dim Pk_czas_start As String * 8                             'godzina włączenia
  225. Dim Pk_long_start As Long                                   'czas włączenia
  226.  
  227. Dim Pk_czas_stop As String * 8                              'godzina wyłączenia
  228. Dim Pk_long_stop As Long                                    'czas wyłączenia
  229.  
  230. Dim Pk_long_teraz As Long                                   'teraźniejszy czas i data
  231.  
  232. 'czas włączenia
  233. If Czasowka(33) < 10 Then
  234.    Pk_czas_start = "0" + Str(czasowka(33))
  235. Else
  236.    Pk_czas_start = Str(czasowka(33))
  237. End If
  238.  
  239. If Czasowka(65) < 10 Then
  240.    Pk_czas_start = Pk_czas_start + ":0" + Str(czasowka(65)) + ":00"
  241. Else
  242.    Pk_czas_start = Pk_czas_start + ":" + Str(czasowka(65)) + ":00"
  243. End If
  244.  
  245. 'czas wyłączenia
  246. If Czasowka(97) < 10 Then
  247.    Pk_czas_stop = "0" + Str(czasowka(97))
  248. Else
  249.    Pk_czas_stop = Str(czasowka(97))
  250. End If
  251.  
  252. If Czasowka(129) < 10 Then
  253.    Pk_czas_stop = Pk_czas_stop + ":0" + Str(czasowka(129)) + ":00"
  254. Else
  255.    Pk_czas_stop = Pk_czas_stop + ":" + Str(czasowka(129)) + ":00"
  256. End If
  257.  
  258.  
  259. 'sprawdzam przypisanie czasu włączenia/wyłączenia
  260. Locate 1 , 1 : Lcd Pk_czas_start
  261. Locate 2 , 1 : Lcd Pk_czas_stop
  262.  
  263. Wait 1 : Cls
  264.  
  265. '**********************************************************
  266. 'GLOBALNE PRZERWANIA
  267.  
  268. Enable Interrupts
  269.  
  270.  
  271. '==========================================================
  272. 'GŁÓWNA PĘTLA PROGRAMU
  273. '==========================================================
  274.  
  275. Do
  276.  
  277. '----------------------------------------------------------
  278. 'WYLICZ DZIEŃ TYGODNIA
  279.  
  280.    Dzien_tygodnia = Dayofweek()
  281.    Dzien_tygodnia_str = Lookupstr(dzien_tygodnia , Dni_tygodnia)
  282.  
  283. '----------------------------------------------------------
  284. 'ZMIANA WYŚWIETLANIA ROKU Z 01/01/20 NA 01/01/2020
  285.  
  286.    Date_str = Date(_day)
  287.    Date_str = Mid(date_str , 1 , 6) + "20"
  288.    Date_str = Date_str + Str(_year)
  289.  
  290. '----------------------------------------------------------
  291. 'WYŚWIETL CZAS, DATĘ I DZIEŃ TYGODNIA
  292.  
  293.    Locate 1 , 1 : Lcd Time$                                 'wyświetl czas
  294.    Locate 2 , 1 : Lcd Date_str ; " " ; Dzien_tygodnia_str   'wyświetl datę i dzień tygodnia
  295.  
  296. '----------------------------------------------------------
  297. 'OBLICZ CZAS ZAŁĄCZANIA
  298.  
  299.    Pk_long_teraz = Syssec()                                 'czas teraźniejszy
  300.    Pk_long_start = Syssec(pk_czas_start , Date$)            'czas i data włączenia
  301.    Pk_long_stop = Syssec(pk_czas_stop , Date$)              'czas i data wyłączenia
  302.  
  303. '----------------------------------------------------------
  304. 'WŁĄCZ/WYŁĄCZ WYJŚCIA
  305.  
  306. '  Jeżeli zostaną spełnione warunki:
  307. '  1. Czas włączenia jest mniejszy lub równy od teraźniejszego czasu
  308. '  2. Czas wyłączenia jest większy lub równy od teraźniejszego czasu
  309. '  3. Dzień tygodnia jest zgodny z dzisiejszym dniem tygodnia - w bazie ma wartość "1"
  310. '  To włącz wyjście.
  311. '  Jeżeli któryś z warunków nie zostanie spełniony to wyłącz wyjście
  312.  
  313.    If Pk_long_start <= Pk_long_teraz And Pk_long_stop >= Pk_long_teraz And Czasowka(321) = 1 Then
  314.  
  315.       Set Pk_1                                              'włącz przekaźnik
  316.  
  317.       Locate 1 , 11 : Lcd "PK ON "                          'wyświetl, że przekaźnik jest włączony
  318.  
  319.    Else
  320.  
  321.       Reset Pk_1                                            'wyłącz przekaźnik
  322.  
  323.       Locate 1 , 11 : Lcd "PK OFF"                          'wyświetl, że przekaźnik jest wyłączony
  324.  
  325.    End If
  326.  
  327. Loop
  328. End
  329.  
  330. '==========================================================
  331. 'KONIEC GŁÓWNEJ PĘTLI PROGRAMU
  332. '==========================================================
  333.  
  334.  
  335. '**********************************************************
  336. 'ODCZYT/ZAPIS ZEGARA
  337.  
  338. Getdatetime:                                                'czytaj czas i datę
  339.  
  340.    I2cstart                                                 'wygeneruj kod startowy
  341.    I2cwbyte Ds3231w                                         'wyślij adres
  342.    I2cwbyte 0                                               'adres początkowy DS3231
  343.    I2cstart                                                 'Wygeneruj kod startowy
  344.    I2cwbyte Ds3231r                                         'wyślij adres
  345.    I2crbyte _sec , Ack                                      'sekunda
  346.    I2crbyte _min , Ack                                      'minuta
  347.    I2crbyte _hour , Ack                                     'godzina
  348.    I2crbyte Dzien_tygodnia , Ack                            'dzień tygodnia
  349.    I2crbyte _day , Ack                                      'dzień
  350.    I2crbyte _month , Ack                                    'miesiąc
  351.    I2crbyte _year , Nack                                    'rok
  352.    I2cstop
  353.  
  354.    _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
  355.    _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
  356.  
  357. Return
  358.  
  359. Setdate:                                                    'zapisz datę
  360.  
  361.    _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
  362.  
  363.    I2cstart                                                 'wygeneruj kod startowy
  364.    I2cwbyte Ds3231w                                         'wyślij adres
  365.    I2cwbyte 4                                               'adres początkowy DS3231
  366.    I2cwbyte _day                                            'dzień
  367.    I2cwbyte _month                                          'miesiąc
  368.    I2cwbyte _year                                           'rok
  369.    I2cwbyte Dzien_tygodnia                                  'dzien tygodnia
  370.    I2cstop
  371.  
  372. Return
  373.  
  374. Settime:                                                    'zapisz czas
  375.  
  376.    _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
  377.  
  378.    I2cstart                                                 'wygeneruj kod startowy
  379.    I2cwbyte Ds3231w                                         'wyślij adres
  380.    I2cwbyte 0                                               'adres początkowy DS3231
  381.    I2cwbyte _sec                                            'sekunda
  382.    I2cwbyte _min                                            'minuta
  383.    I2cwbyte _hour                                           'godzina
  384.    I2cstop
  385.  
  386. Return
  387.  
  388. '**********************************************************
  389. 'DNI TYGODNIA
  390.  
  391. Dni_tygodnia:
  392.  
  393. Data "Pn" , "Wt" , "Sr" , "Cz" , "Pt" , "So" , "Nd"         'dzień tygodnia do wyświetlenia
.
No i teraz tak, dane będę wpisywał z menu sterownika (teraz wpisałem przykładowe dane dla pierwszego czasu, pierwszej czasówki) dane trafią do eeprom. Baza działa, ale ja nie wiem jak napisać program aby wyciągnąć te dane i na ich podstawie sterować wyjściami - teraz działa, ale tylko dla jednego czasu, a będzie ich w sumie 32
Druga sprawa, jak przypisać czasówkę do przekaźnika?
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: RTC, działania na podstawie czasu

Post autor: niveasoft » 26 sty 2020, 17:15

Wydaje mi się, że niektóre rzeczy niepotrzebnie sobie komplikujesz :P
Nie znalazłbym się w tych Twoich numerach bajtów za to ja pisze to używając stałych. Wiem że jeden wpis ma mieć np. osiem bajtów. W pierwszym mogę sobie dać numer porządkowy lub aktywne dni tygodnia a w ostatnim numer wyjścia którym chcę sterować. Wpisów ma być 32 tak? No to piszę Liczba_wpisów = 32 a potem niżej, że Rozmiar_bazy to Liczba_wpisów * 8 i kompilator mi to sam policzy a ja dokładnie wiem ile bajtów muszę zarezerwować (a dokładniej to nie muszę tego wiedzieć :D)

Później buduję sobie buforek na osiem bajtów a po bazie będę się poruszał "co osiem bajtów" (Idx = Idx + 8)
Bascomowe funkcje do czasu wymagaja tylko jednego. Musisz mieć w kodzie zdefiniowane trzy bajty, jeden za drugim w których będzie sekanda, minuta i godzina.
Na taki buforek nakładam sobie takie fantowowe zmienne poprzez Overlay i już moge napisać Time_on = Syssec(Sec_on) Wszystko prosto i króciutko.
Jak znajdę taki wpis że akurat coś ma być włączone to sprawdzam ostatni bajt buforka żeby sprawdzić którym wyjściem mamy się zająć...i to pomału wszystko.
Wystarczy teraz dopisać Eeprom. To chyba na razie tylko 256bajtów a masz 1KB

Możesz to sobie sprawdzać nawet co sekundę. Procek i tak będzie ziewał.
Zauważ tylko ile mniej jest myślenia jak tworzysz pętle a masz stałe - piszesz np "For N = 1 To Liczba_wpisów"
W ten sposób możesz sobie kiedyś dodać kilka wpisów i nie martwić się że gdzieś w kodzie masz za małą cyferkę :D
Niestety na razie muszę wracać do swoich zadań no i nie chciałem psuć Tobie całej zabawy :D
  1. $regfile = "m32def.dat"                                     'ATmega32 SRAM 2KB, EEPROM 1KB
  2. $crystal = 16000000                                         'zewnętrzny rezonator  16MHz
  3. $swstack = 64
  4. $hwstack = 64
  5. $framesize = 200
  6. Config Submode = New
  7.  
  8. Const Liczba_wpisow = 32
  9.  
  10. Config Clock = User
  11.  
  12. Dim Helpb As Byte , N As Byte , M As Byte , Idx As Word
  13.  
  14. '|NR|SEC_ON|MIN_ON|HOUR_ON|SEC_OFF|MIN_OFF|HOUR_OFF|OUT_NR|   <-osiem bajtów
  15. Const Rozmiar_bazy = Liczba_wpisow * 8
  16.  
  17. Dim Base(rozmiar_bazy) As Byte                              'zarezerwuj tyle bajtów
  18.  
  19. Dim Mybuff(8) As Byte
  20. Dim Sec_on As Byte At Mybuff(2) Overlay
  21. Dim Sec_off As Byte At Mybuff(5) Overlay
  22.  
  23. Dim Time_now As Long , Time_on As Long , Time_off As Long
  24.  
  25. Dim Outs As Long
  26. Dim _out(4) As Byte At Outs Overlay
  27.  
  28. Sub Check_scheduler()
  29.  Outs = 0
  30.   Idx = 1
  31.  For N = 1 To Liczba_wpisow
  32.   M = Memcopy(base(idx) , Mybuff(1) , 8)
  33.  
  34.   Time_now = Syssec(_sec)                                   'czas aktualny
  35.   Time_on = Syssec(sec_on)
  36.   Time_off = Syssec(sec_off)
  37.  
  38.   If Time_now > Time_on Then
  39.    If Time_now < Time_off Then
  40.     Helpb = Mybuff(8)                                       'które wyjście
  41.     _out(helpb) = 1                                         'zapamietaj że mamy to włączyć
  42.    End If
  43.   End If
  44.  
  45.   Idx = Idx + 8
  46.  Next
  47.  
  48.  For N = 1 To 4
  49.   If _out(n) = 1 Then
  50.    Select Case N
  51.     Case 1 : Set Porta.4
  52.     Case 2 : Set Portb.1
  53.     Case 3 : Set Portc.2
  54.     Case 4 : Set Portd.7
  55.    End Select
  56.   Else
  57.    Select Case N
  58.     Case 1 : Reset Porta.4
  59.     Case 2 : Reset Portb.1
  60.     Case 3 : Reset Portc.2
  61.     Case 4 : Reset Portd.7
  62.    End Select
  63.   End If
  64.  Next
  65. End Sub
  66.  
  67.  
  68. Do
  69.  If _sec = 0 Then Call Check_scheduler                      'np.raz na minute
  70. Loop
ODPOWIEDZ