• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Zegar na DS1307 liczenie czasu, alarm co ten sam okres czasu.
#1
Witam, przepraszam za kiepski tytuł ale nie mam pomysłu jak opisać problem.

Robię sobie urządzenie posiadające RTC, jest to na razie moduł DS1307. Docelowo chciałbym móc wybrać dzień tygodnia, określić ramy godzinowe np 10:00 - 15:00 i w tych godzinach załączać przekaźnik co określony czas, np co 30 minut.

Właściwie mam cały program ale przyszedł czas napisania metody dla uruchamiania tego przekaźnika co 30 minut. i tutaj zaczynają się problemy bo jeśli uruchomię tą funkcję i będziemy mieli np 11:40 da to 11:70, a co za tym idzie funkcja nigdy nie zadziała. Oczywiście żaden to problem, można zrobić to np.  (40 + 30) - 60 = 10 i w takim wypadku dodać +1 do godziny a jako minuty ustawić to co zostało z działania i problem się rozwiązał. Ale idąc dalej to samo zacznie się dziać z godzinami a następnie dniami miesiącami (uwzględnienie miesięcy 30 i 31 dniowych plus luty) później lata przestępne itp.

dlatego mam pytanie, czy jest na to jakieś proste rozwiązanie jakaś biblioteka etc ?

Jedyne co przychodzi mi do głowy to zmiana modułu na DS3231 który obsługuje dwa alarmy sprzętowo które można by podstawić pod zmienne i funkcje ustawiania alarmu, wtedy co ustawiony okres czasu moduł sam wyśle do atmegi sygnał, że "już pora"
 
Odpowiedź
#2
czas= (godziny *60)+minuty; // zmienna jest co minute

biorąc pod uwagę 10-15
if(czas >= 600 && czas <= 900){
napisz kod na "czas" by co wymagany czas włączał wyłączał przekaźnik
}
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#3
(04-12-2019, 00:06)Jarewa0606 napisał(a): czas= (godziny *60)+minuty;  // zmienna jest co minute

biorąc pod uwagę 10-15
if(czas >= 600 && czas <= 900){
  napisz kod na "czas" by co wymagany czas włączał wyłączał przekaźnik
}

Nie chodzi o ramy czasowe, to nie jest żaden problem. To nic nie da, ja potrzebuję mieć możliwość określenia wszystkich parametrów. Urządzenie ma wyświetlacz z menu gdzie można wybrać w jakie dni tygodnia ma działać, w jakich godzinach w każdym z dni tygodnia oraz jaki jest interwał uruchamiania przekaźnika (przekaźnik tutaj to tylko uproszczenie żeby nie zaciemniać obrazu sytuacji)

Problem to poprawne odliczanie czasu kiedy np od 21:00 do 02:00 urządzenie ma być aktywne, i interwał uruchamiania przekaźnika to 40 minut to ja potrzebuję, żeby w tych godzinach co 40 minut uruchamiał się przekaźnik a do tego muszę wziąć aktualny czas dodać do niego precyzyjnie to 40 minut i tak ustawiona metoda ma wypluć dokładną datę kiedy uruchomię funkcję przekaźnika, i tak za każdym razem. Reszta problemu jest opisana w pierwszym poście, głównie chodzi o to, że jest dużo zmiennych i ten czas mi się szybko rozjedzie bez sporej metody do jego poprawnego liczenia. Dlatego szukam biblioteki lub podobnego rozwiązania.

Oczywiście mogę pójść na łatwiznę i po prostu uruchamiać licznik np w millis() dla każdego interwału ale nie jest to eleganckie rozwiązanie i zegar w atmedze szybko rozjedzie się z zegarem w module RTC (osobne taktowania). Do tego jeśli procek się zawiesi to nawet jak WDT go podniesie to odliczanie rozpocznie się od nowa czyli znów interwał się rozjedzie a o zapisywaniu millis() np co 1s do EEPROM nie ma mowy bo żywotność skończy się po tygodniu.

//EDIT
Problem rozwiązany w bardzo prosty sposób. Jakby ktoś miał podobny problem to wystarczy wyrzucić czas w unixtime, a później napisać metodę która sobie na tym operuje czyli dla mnie wystarczy, że co np 1s sprawdzi czy upłynęła odpowiednia ilość sekund i jeśli tak to wykona akcje po czym zegar się zresetuje i zacznie liczyć od początku. Rozwiązanie o tyle fajne, że czas nadal jest pobierany z RTC więc nic się nie rozjedzie.

Dzięki i pozdrawiam.
 
Odpowiedź
#4
Można napisać tak kod, żeby nie trzeba było tego czasu sprawdzać w pętli. Wystarczy podłączyć wyjście SQ zegara do wejścia INTx Arduino i w przerwaniu zliczać sekundy i porównywać ze zmienną. Procesor nic nie robi tylko włącza ten przekaźnik.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#5
(04-12-2019, 12:11)Robson Kerman napisał(a): Można napisać tak kod, żeby nie trzeba było tego czasu sprawdzać w pętli. Wystarczy podłączyć wyjście SQ zegara do wejścia INTx Arduino i w przerwaniu zliczać sekundy i porównywać ze zmienną. Procesor nic nie robi tylko włącza ten przekaźnik.

Masz rację, pomyślałem o tym, niestety użyłem atmegi328, a poruszanie się po menu zrealizowałem na enkoderze który używa obu pinów przerwan. Bez dodatkowego scalak by się to nie udało a mam do tego zrobione na zamówienie pcb więc drutowanie odpada Smile
 
Odpowiedź
#6
Poszukaj na naszym forum wątku Przerwania na każdym pinie.

Edit: O znalazłem https://forum.arduinopolska.pl/watek-prz...pin%C3%B3w
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#7
(04-12-2019, 14:00)Robson Kerman napisał(a): Poszukaj na naszym forum wątku Przerwania na każdym pinie.

Edit: O znalazłem https://forum.arduinopolska.pl/watek-prz...pin%C3%B3w

Dzięki, przyda się
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości