PCF8583 i odczyt daty z dniem tygodnia


Witam!

Od dłuższego czasu pracuję nad urządzeniem, które ma być prezentem dla mojej nażeczonej ;) Czas mi się kończy powoli, a zatrzymał mnie w miejscu pewien problem.
Urządzenie ma być zegarem-budzikiem z kilkoma nietypowymi (jak na zegarki) funkcjami.
Wykorzystuję wyświetlacz alfanumeryczny 4 linijki po 20 znaków. Do odmierzania czasu użyłem zegara RTC PCF8583 - jest to moja pierwsza próba jego zastosowania i obsługi programowej. Jako że zegar (szczególnie już budzik) musi mieć czytelne i wyraźne cyfry wymyśliłem sposób na wyświetlanie na zwykłym wyświetlaczu alfanumerycznym dużych cyfr. Póki co zrealizowałem wszystko tak, że przez 30 sekund jest wyświetlana godzina, następnie przez około 4 sekundy temperatura. Na chwilę obecną wygląda to tak:

Jednak chciałbym wykorzystać możliwości PCF'a i razem z temperaturą wyświetlać również datę. O ile wyświetlanie samego miesiąca i jego dnia nie jest problemem, a na wyświetlaniu roku mi nie zależy (trzeba pisać obsługę lat przestępnych, bo jak wiadomo PCF8583 zlicza lata tylko do 3) to przydałaby mi się możliwość odczytu dnia numeru dnia tygodnia - nie tylko do wyświetlania jego nazwy na ekranie, ale również do orpogramowania budzika na każdy dzień tygodnia. I właśnie na tym etapie stanąłem - przegrzebałem już mnóstwo for, ale nigdzie nie znalazłem żadnej wartościowej informacji, poza tą, że jest to dosyć skomplikowane ;(

Fragment kodu odpowiedzialny za odczytywanie czasu z PCF'a wygląda tak:

I2cstart
  I2cwbyte 162
  I2cwbyte 2
  I2cstart
  I2cwbyte 163
  I2crbyte Sekundy , Ack
  I2crbyte Minuty_bcd , Ack
  I2crbyte Godziny_bcd , Nack
  I2cstop
 
Minuty = Makedec(minuty_bcd)
Godziny = Makedec(godziny_bcd)
 
Minuty_dziesiatki = Minuty / 10 : Minuty_jednosci = Minuty Mod 10
Godziny_dziesiatki = Godziny / 10 : Godziny_jednosci = Godziny Mod 10

Jak widać jest to dosyć standardowe rozwiązanie - bo i nie ma tu nic niezwykłego. Może poza tym, że wartości godzin i minut rozdzielam na części dziesiętne i jedności - jest mi to potrzebne do sprawnego wyświetlania dużych cyfr. W przypadku sekund nie jest to konieczne - są one wyświetlane w standardowy sposób.

I tu pojawia się moja gorąca prośba: może Ty Mirley'u, albo ktoś z Was forumowicze borykał się już kiedyś z podobnym do mojego problemem, znalazł rozwiązanie i zechciałby mi pomóc?

Jak zmodyfikować mój fragment kodu, tak by odczytywać jeszcze numer dnia miesiąca, numer miesiąca i numer dnia tygodnia?

Dziękuję z góry za wszelkie zainteresowanie i podpowiedzi!
Janusz




Portret użytkownika mirley

Re: Miesiące i dni

Numer dnia i miesiąca to są normalnie w rejestrze PCFA przechowywane, z latami to tak jak mówisz, tylko 4 kolejne są zapisywane. Żeby odczytać miesiąc i dzień miesiąca wystarczy odczytać dwa kolejne bajty z rejestru czasu (tak mi się wydaje bo kiedyś czytałem jak zaczynałem zabawę z PCF'em ale teraz już tak dobrze nie pamiętam. Zerknij do PDF'a jak jest to zorganizowane)

Żeby policzyć dzień tygodnia, czy jest to poniedziałek czy wtrek, itd. To ja bym przeliczył numer miesiąca i numer dnia na jedną zmienną określającą numer dnia w roku, potem w ustawieniach wprowadził parametr umożliwiający ustawienie określonego dnia. Teraz masz np dzień numer 132 w roku, ktoś ustawił sobie jednorazowo że jest to np wtorek. Dzielisz liczbę 132 modulo przez 7 uzyskując wartość w tym przypadku 6 (niedziela), normalnie będzie wartość 0-6 (o=pn, 1=wt, itd). Zatem trzeba wprowadzic przesuniecie o te 5 dni niedziela - wtorek. Dalej liczym modulo 7 dla kolejnego dnia (133)i wychodzi 0, wynik po odjęciu przesunięcia to -5 ale ponieważ jest ujemna wartośc to +7dni czyli wyjdzie 2 co daje środę itd.

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika villen

Tylko że po co komplikować

Tylko że po co komplikować sobie życie, skoro na 100% numer dnia tygodnia jest gdzieś zakamuflowany w PCF'ie? Przeliczanie może nie jest złym pomysłem, jednak jak by nie patrzeć komplikuje ono program, który i tak będzie skomplikowany - oprócz tego co jest już zrobione będę odbierał komendy RC.5, wysyłał komendy w standardzie Sony, sterował 2 sprzętowymi PWM'ami i odczytywał napięcie z dzielnika napięcia przez wewnętrzny A/C Atmegi...
Znalazłem przetłumaczoną dokumentację PCF'a, przynajmniej sporą jej część. Będę próbował coś z niej wykoncypować i szukać jeszcze jakiś informacji.

Portret użytkownika mirley

Re: Odczyt PCF

Teraz sie dopatrzyłem że odczyt jest następujący:
Sekundy, minuty, godziny, rok/data, dzień tygodnia/miesiąc, timer

wartości jakie przyjmują kolejne rejestry też są zapisane w karcie

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika villen

Kurcze, z tego co wyczytałem

Kurcze, z tego co wyczytałem dochodze do wniosku (nie wiem czy poprawnego) że dzień tygodnia jest wysyłany razem z numerem miesiąca. Po odczycie trzeba przesunąć 6 miejsc w prawo i zostanie dzień tygodnia. Tyle że domyślnie chyba jest ta opcja ukryta, i przed odbiorem trzeba odblokować jakiś bit. Kurcze, trzeba bylo sie lepiej do nauki angielskiego przykładać... :P

Muszę chyba poszukać jakiegoś przykładowego programu i z niego spróbować coś wywnioskować...

Portret użytkownika matrix

Re: PCF8583 i odczyt daty z dniem tygodnia

a ja mam prośbę. przedstawisz całość jak skończysz? zapowiada się ciekawie. wyświetlanie czasu mi się podoba.

Portret użytkownika villen

Jeśli uda mi się skończyć

Jeśli uda mi się skończyć całość, to oczywiście że zaprezentuję. Ale póki co stanąłem na tej nieszczęsnej dacie, a bez tego nie mam właściwie po co ruszać dalej... ;(

Portret użytkownika villen

Z radością informuję, że w

Z radością informuję, że w końcu udało mi się rozgryść PCF'a 8583! Działa mi wszystko, łącznie z latami przestępnymi!

Jeśli znajdę chwilę, to mogę napisać krótki artykuł nt. pełnej obsługi czasu i daty z wykorzystaniem tego RTC, tak by inni mieli już łatwiej ;)

Portret użytkownika matrix

opis pdf'a układu PCF 8583

villen wrote:
Jeśli znajdę chwilę, to mogę napisać krótki artykuł nt. pełnej obsługi czasu i daty z wykorzystaniem tego RTC, tak by inni mieli już łatwiej ;)

jestem jaknajbardziej za, wręcz bardzo proszę.

Portret użytkownika villen

Okazało się, że nie jest to

Okazało się, że nie jest to w cale takie trudne. Ba, wręcz banalne. Bardzo pomógł mi fragment noty katalogowej przetłumaczonej na język polski, który znalazłem w internecie. Wszystko sprowadza się do banalnego przesówania bitów i odróżnienia który rok jest przestępny a który nie ;)
Postaram się opisac wszystko najdokładniej i najprościej jak tylko będę potrafił, ale to dopiero jak skończę prace nad tym projektem, bo muszę zdążyć do urodzin narzeczonej a pracy jeszcze sporo ;)

Portret użytkownika villen

No dobrze, postaram się

No dobrze, postaram się krótko omówić to co do tej pory udało mi się poprawnie zrealizować.
Tak jak mówiłem nie taki diabeł straszny i po przeczytaniu ze zrozumieniem kilku stron noty katalogowej bez większego problemu po kilku eksperymentach wypracowałem rozwiązanie mojego problemu.
Zacznijmy od odczytu danych z PCF'a:

I2cstart
  I2cwbyte 162
  I2cwbyte 2
  I2cstart
  I2cwbyte 163
  I2crbyte Sekundy , Ack
  I2crbyte Minuty , Ack
  I2crbyte Godziny , Ack
  I2crbyte Dzien , Ack
  I2crbyte Miesiac , Nack
  I2cstop

Ten krótki fragment programu odczytuje z naszego RTC dane i zapisuje je do zmiennych o nazwach Sekundy ... Miesiac. Ale uwaga! Układ operuje w systemie BCD (Binary-Coded Decimal). Więc w zmiennych tych nie "siedzą" ładne dziesiętne wartości, a ich odpowiedniki zakodowane w tym systemie. Cyfry oznaczające części dziesiętne i jedności sekund, minut i godzin odczytywane są bezpośrednio. W zmiennej Dzien zaczynajac od najbardziej znaczącego (MSB, czyli ostatniego licząc od prawej do lewej) bitu mamy na dwóch pierwszych nr roku (w dziesiętnym 0-3), na dwóch następnych dziesiętne części dnia (0-3) i na czterech ostatnich jedności dnia (0-9). Podobna sytuacja jest w przypadku zmiennej Miesiac. W niej (licząc tak jak wyżej) mamy ma pierwszych 3 bitach dzień tygodnia (0-6), na czwartym bicie dziesiętne cześci miesiąca (0-1) i na czterech ostatnich jedności miesiąca (0-9). Myślę że lepiej zobrazuje to rysunek - po wykonaniu fragmentu programu umieszczonego powyżej otrzymujemy w zmiennych Sekundy ... Minuty następującą zawartość:

Mam nadzieję że wygląda to w miarę przejrzyście. W razie czego proszę pytać.
Słowo wyjaśnienia w kwestii roku: PCF8583 zlicza lata od 0 (bin: 00) do 3 (bin: 11) - wartość 0 odpowiada rokowi przestępnemu, a następne 3 są to lata normalne. Więc niestety aby mieć pełną obsługę lat i kalendarz na np 100 najbliższych lat trzeba ich obsługę realizować programowo. Póki co nie mam tego punku zrealizowanego na tyle dobrze, by pokazywać go jako przykład innym - ale pewnie to jeszcze poprawię.

No dobrze, wiemy jak wygląda zawartość poszcególnych zmiennych i "co jest co" w tym całym bajzlu. Teraz to wszystko rozdzielmy. Jak mówiłem całość sprowadza się do prostego przesówania i operacji na bitach. Myślę że poniższy kod ma wystarczająco dużo komentarzy i nie trzeba będzie nic więcej tłumaczyć:

Sekundy = Makedec(sekundy)   'konwesja sekund z BDC do dziesiętnego
Minuty = Makedec(minuty)     'konwesja minut z BDC do dziesiętnego
Godziny = Makedec(godziny)   'konwesja godzin z BDC do dziesiętnego
 
 
Rok = Dzien                  'Przypisanie zmiennej Rok wartości zmiennej Dzien w BCD
Shift Rok , Right , 6        'Przesunięcie zmiennej Rok 6 miejsc w prawo - zostają 2 bity oznaczające rok
Rok = Makedec(rok)               'Konwersja wartości z BCD do systemu dziesiętnego
Dzien.7 = 0 : Dzien.6 = 0        'Wyzerowanie 6 i 7 bita zmiennej Dzien - zostaje tylko numer dnia
Dzien = Makedec(dzien)           'I konwersja do systemu dziesiętnego
Dzien_tygodnia = Miesiac         'Przypisanie zmiennej Dzien_tygodnia wartosci zmiennej Miesiac w BCD
Shift Dzien_tygodnia , Right , 5 'Przesunięcie zmiennej Dzien_tygodnia 5 bitów w prawo - zostają 3 bity oznaczające numer dnia tygodnia
Dzien_tygodnia = Makedec(dzien_tygodnia) 'Konwersja wartości do systemu dziesiętnego 
Miesiac.7 = 0 : Miesiac.6 = 0 : Miesiac.5 = 0  'Wyzeorwanie 7, 6, i 5 bitu zmiennej Miesiac - zostaje numer miesiaca
Miesiac = Makedec(miesiac)   'I konwersja wartosci do systemu dziesietnego

Po przeprowadzeniu tych operacji otrzymujemy w zmiennych Sekundy, Minuty, Godziny, Rok, Dzien, Dzien_tygodnia i Miesiac liczbowe wartości w systemie dziesiętnym. Zwrócic nalezy uwagę tylko na to, że Dzien_tygodnia będzie przybierał wartości od 0 (poniedziałek) do 6 (niedziela).

Całość takiego programu, łącznie z wyświetleniem tych danych może wyglądać tak:

Dim Sekundy As Byte : Dim Minuty As Byte : Dim Godziny As Byte
Dim Dzien As Byte : Dim Miesiac As Byte
Dim Rok As Byte : Dim Dzien_tygodnia As Byte
 
Do
 
I2cstart
  I2cwbyte 162
  I2cwbyte 2
  I2cstart
  I2cwbyte 163
  I2crbyte Sekundy , Ack
  I2crbyte Minuty , Ack
  I2crbyte Godziny , Ack
  I2crbyte Dzien , Ack
  I2crbyte Miesiac , Nack
  I2cstop
 
Sekundy = Makedec(sekundy)
Minuty = Makedec(minuty)
Godziny = Makedec(godziny)
 
 
Rok = Dzien
Shift Rok , Right , 6
Rok = Makedec(rok)
Dzien.7 = 0 : Dzien.6 = 0
Dzien = Makedec(dzien)
Dzien_tygodnia = Miesiac
Shift Dzien_tygodnia , Right , 5
Dzien_tygodnia = Makedec(dzien_tygodnia)
Miesiac.7 = 0 : Miesiac.6 = 0 : Miesiac.5 = 0
Miesiac = Makedec(miesiac)
 
Cls
Lcd "Godzina: " ; Godziny ; ":" ; Minuty ; ":" ; Sekundy
Lowerline
Lcd "Data: " ; Dzien ; "-" ; Miesiac ; "-" ; Rok ; " : " ; Dzien_tygodnia
Wait 1
 
Loop : End

Tyle udało mi się na tą chwilę zrobić. Do zrobienia jeszcze programowa obsługa lat (normalnych i przestępnych) aby otrzymać pełnowartościowy kalendarz. No i zapis danych do PCF'a - ale jak już rozgryzie się zasade jego działania jest to proste - te same zasady, tylko nie odczytujemy a zapisujemy ;)

Mój zegarek pracuje póki co w ten sposób:

Przez minutę wyświetlany jest czas, potem przez ~8sekund data z dniem tygodnia i temperaturą. Ostatnie 2 linie wyświetlacza rezerwuję na imieniny danego dnia. Ale to zacznę robić dopiero po opracowaniu reszty funkcji - póki co zajęte jest 37% pamięci atmegi16. W razie czego podmienię ją na mege32 :D

Mam nadzieję że te moje wypociny komuś się przydadzą.
Czy są choć w miarę zrozumiałe? ;)

Pozdrawiam!

Portret użytkownika matrix

super

podoba mi się jak diabli. nie za bardzo kumam jeszcze rozkminkę z tymi kolorowymi liczbami, ale przeczytam kilka razy i zakumam. świetnie.

Portret użytkownika villen

Na obrazku jest błąd: Pod

Na obrazku jest błąd: Pod objaśnieniami do zawartości zmiennej "Dzien", na niebiesko oznaczone są dziesiętne części dnia. W systemie binarnym na tym przykładzie jest 11, ja niżej podpisałem dziesiętnie cyfrą 2, a oczywiście powinno być 3. Mój błąd :P

Portret użytkownika mirley

Re: Projekt Zegara

Jak Skończysz to proszę o pełny opis na forum w dziale Własne opracowania -> projekty Inne. Część już możesz przekleić potem z tego wpisu

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika villen

Z chęcią ;) Najpóźniej myślę

Z chęcią ;) Najpóźniej myślę skończyć całość za 2 tygodnie.

Muszę tylko wymyśleć jeszcze jakieś rozsądne rozwiązanie obsługi roku i dalej już pójdzie z górki ;)

Portret użytkownika matrix

Re: Projekt Zegara

ja mam małą prośbę. możesz wrzucic kawałek kodu odpowiedzialny za wyświetlanie tak dużej godziny? i dał bys link gdzie kupiłeś ten wyświetlacz? odpowiada mi i wielkość i jego barwa.

Portret użytkownika villen

Wyświetlacz kupiłem na

Wyświetlacz kupiłem na allegro od użytkownika "zyscom" - miał w ofercie jeszcze kilka innych kolorów, m.in. taki ładny bursztynowy i zielony (ale zielone znaki a nie podświetlanie). Ale ostatecznie zdecydowałem się na biały z czarnym tłem ;)

A kodu odpowiedzialnego za wyświetlanie dużych cyfr na razie nie planuję udostępniać - kosztowało mnie to sporo pracy i myślenia. Ale służę pomocą i podpowiedzią jakby co ;)

Dziś udało mi się już uruchomić przetwornik A/C który mierzy napięcie na wyjściu rezystorowego dzielnika napięcia - z tym że zamiast jednego rezystora zastosowałem fotorezystor. Dzięki temu będę regulował intensywność podświetlania wyświetlacza i obudowy w zalezności od jasności na zewnątrz. Chodzi głównie o to, żeby nocą nie raziło po oczach i dało spać :P
W związku z powyższym uruchomiłem też już 2 PWM'y które przez bufory na darlingtonach BC516 regulują jasność podświetlania i diody.

Tak wygląda moje stanowisko testowe :D

Ciągle czekam na pilot RC.5 z allegro - kiedy w końcu go dostanę myślę że prace ruszą już ostro na ostatnią prostą - zostanie mi oprogramowanie menu ustawień, nadawanie komend IR w standardzie Sony i wyświetlanie imienin, jeśli starczy miejsca w pamięci.

Portret użytkownika McGiver1

50Hz

Hej nie chciałem tworzyć nowego temaru ,więc zapytam.
Podłączałem już tego pcf'a na kwarcu 32768Hz ,a teraz chciałbym wypróbować
rozwiązanie z 50hz. Jak sądze musze je wziąć z sieci. Czytałem trochę datasheeta ,
ale jestem niezbyt zawansowany z angielskiego i nie doczytałem się jak to trzeba zrobić.
Wiem jedynie ,że muszę wpisać jakąś komendę po adres chyba 01 ,ale z tym bez problemu
sobie poradzę. Ciekawi mnie tylko jak już pisałem samo podłączenie. Wydaje się ,ze 50hz
można wziąć z sieci ,ale tam jest 230V i to w sinusoidze ,a nie w prostokącie. No kompletnie
nie wiem jak się za to zabrać :(
Więc jeśli miał ktoś z was jakieś doświadczenie z tym RTC i 50Hz to prosiłbym ,o podzielenie
się informacją ;] Zresztą niektórzy może bardziej znają angielski ,to możecie się również
zainteresować tym faktem.
Z góry dzięki. Pozdrawiam ;]

Portret użytkownika mirley

Re: PCF

Dokładność częstotliwości w sieci jest dość dobra, jednak problem będzie kiedy zabraknie napięcia i zegar przejdzie na zasilanie bateryjne :)

Obniżyć napięcie w sieci możesz za pomocą transformatora, potem albo obciąć wartość amplitudy np za pomocą diody zenera i zrobi się "prawie prostokąt", albo jakiś komparator przełączany w zerze. Jednak może się okazać że zrobienie prostokąta z sinusa obarczonego szumami itp nie jest taka prosta. Napewno będziesz musiał mieć oscyloskop i trochę innych przyrządów żeby ocenić jakość powstałego przebiegu. Może są takie gotowe układy które zajmują się odzyskiwaniem przebiegu wzorcowego z napięcia sieciowego.

Nie zajmowałem się tym problemem więc dokładnie nie powiem jak to zrobić. Może tez okazać się że wystarczy zrobić to o wiele prościej niż myślę i poprostu podać na układ odpowiedniego sinusa zamiast prostokąta.... musisz przeprosić się z google i coś znaleźć na ten temat

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.