Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Atmega 32 - czas w Bascom - potrzebny pomysł

Qetli 17 Apr 2014 10:20 1353 15
Relpol
  • #1
    Qetli
    Level 13  
    Witam.
    Mam dwie zmienne czas_stop i czas_start

    Czas odmierza DS1307 jego zmienne czasowe to _hour , _min , _sec.

    Potrzebuje procedury która o godzinie czas_start ustawi Pinb.0 w pozycji 1 i o gadzinie czas_stop ustawi go w pozycji 0 .
    Reasumując port ma być w stanie 1 od czas_start do czas stop a reszta w pozycji 0.

    Zabrałem się do tego już kilka razy i nie mam pomysłu jak to zrobić .
    Pomocy Pozdrawiam
  • Relpol
  • #2
    tehaceole

    Level 28  
    Przerzutnik RS :)
    W jakiej formie masz "czas_start" i czas_stop? Jest to liczba sekund od północy czy jak?
    Najprościej albo zamienić to na format hh.mm.ss albo czas z DS zamienić na postać liczby sekund od północy. Ewentualnie możesz to zawęzić do liczby minut po północy jeżeli nie potrzebujesz dokładności nastawiania co do sekundy.

    Taki pseudokod bo nie znam bascoma:

    Code: c
    Log in, to see the code

    Tylko należy uwzględnić to, że w tym przypadku czas stop musi być większy od czas start. Chyba ze nie moze być takiego ograniczenia to wtedy musisz dać warunek w którym sprawdzasz 2 warianty:
    czasstart>czasstop
    czasstart<czasstop



    Zasadniczo to bardzo proste :)
  • Relpol
  • #3
    Qetli
    Level 13  
    Własnie czas jest w formie xx czyli sama godzina wraz nie wiem jak to rozwiązać i własnie chodzi że czas start nie zawsze jest mniejszy od czas stop no bo przecież nap od 22 do 4 to już nie będzie grało..
  • #4
    tehaceole

    Level 28  
    No to robi się jeszcze prościej:
    - najpierw sprawdzasz czy aktualnie masz pełną godzinę:
    coś w stylu
    Code: c
    Log in, to see the code

    - wewnątrz tego warunku ustawiasz sobie bit
    Code: c
    Log in, to see the code

    - a nastepnie sprawdzasz warunek wyłączenia
    Code: c
    Log in, to see the code


    czyli reasumując tak to powinno mniej wiecej wygladac:
    Code: c
    Log in, to see the code

    Ale jak ten pseudokod zapisać w bascomie to pojęcia bladego nie mam bo na codzień piszę w C. :)

    Taka mała uwaga techniczna: jeżeli w kodzie będziesz się odwoływać bezpośrednio do fizycznego wyprowadzenia to może być to niewskazane w pewnych sytuacjach (jeżeli chcesz tylko sterować przekaźnikiem itp. to nie ma to większego znaczenia). Ja wzorem programowania PLC zawsze robię sobie w pętli głównej tak:
    - na początku mapowanie stanu wejść
    - obsługa mojego kodu programu i zapis wymuszeń stanów wyjściowych do zmiennych tymczasowych
    - przepisanie zmiennych tymczasowych do fizycznych portów

    Dzięki temu mam pewność, że w pojedynczym obiegu pętli nic mi nie będzie bruździć na wypadek zmiany stanu pinu w trakcie jej wykonywania. Co prawda przy pisaniu programów w sposób tzw nieblokujący nie ma to większego znaczenia (takie przyzwyczajenie ze sterowników PLC).
  • #5
    tehaceole

    Level 28  
    Możesz jeszcze nieco to zmodyfikować:

    Code: c
    Log in, to see the code

    Wszak chodzi o to, aby jakiekolwiek obliczenia / porównania wykonywać tylko wtedy kiedy są potrzebne.
    Zauważ też że ten kod śmiesznie prosto przerobisz na sterowanie wielokanałowe podmieniając zmienne czasstart, czasstop i bit na tablice o "n" elementach.
  • #6
    kuuczoo
    Level 26  
    Witam
    Jeśli jesteś pewien że odczytasz godzinę dostatecznie często i nie jest Ci potrzebna dokładność z sekundami (do minut) to sprawa jest banalna. Zamieniasz czas_start i czas_stop na minuty od północy , zamieniasz aktualną godzinę na minuty od północy i wystarczają 2 warunki
    if (czas = czas_start) then set_bit
    if (czas = czas_stop) then reset_bit
    Warunek konieczny że co najmniej raz na minutę odczytasz czas. Jeśli częściej to po prostu o danej godzinie bit zostanie ustawiony lub skasowany kilka razy, ale nie ma to znaczenia...
  • #7
    tehaceole

    Level 28  
    kuuczoo wrote:
    if (czas = czas_start) then set_bit
    if (czas = czas_stop) then reset_bit

    kuuczoo a tak właśnie sobie kojarzyłem, że można to zapisać jeszcze prościej. Chyba za mało jeszcze kawy w organizmie :) hehehe


    EDIT:
    Już mi się przypomniało skąd te warunki u mnie: kiedyś w jakimś projekcie musiałem tak to zrobić żeby było to sprawdzane co minutę a założenie wtedy było takie, że nie mogłem skorzystać z eepromu ani z innej pamięci jak choćby RAM zewn. RTC. Chodziło o wymuszanie tego stanu nawet w przypadku wyłączenia i włączenia zasilania. Dlatego nie mogłem zrobić tego tak jak zaproponowałeś kuuczoo.
  • #8
    Qetli
    Level 13  
    A co powiecie na coś takiego...

    Code: basic4gl
    Log in, to see the code

    Dim Time_start_h As Byte
    Dim Time_start_m As Byte
    Dim Time_stop_h As Byte
    Dim Time_stop_m As Byte



    _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)


    Lampa Alias Pinb.0


    If Time_start_h <= Time_stop_h Then
    If Time_start_h = Time_stop_h Then
    If Time_start_h = Time_stop_h And Time_start_h = _hour And Time_stop_h = _hour And Time_start_m <= _min And Time_stop_m >= _min
    Lampa = 1
    Else
    Lampa = 0
    End If
    Else
    'tu mam problem
    End If
    Else
    End If
    [/syntax]

    Dodano po 5 [minuty]:

    Dobra mam to teraz chyba najgorsze .

    Code: basic4gl
    Log in, to see the code


    Dodano po 16 [minuty]:

    Code: basic4gl
    Log in, to see the code


    Nie wiem czy nie przekombinowałem ?
  • #10
    Qetli
    Level 13  
    Ok a jeżeli włacze zasilanie w pomiędzy tymi czasami .
    Jeżeli czas ustawiony będzie np start 23 stop 3 ?
  • #11
    M. S.
    Level 34  
    To kicha.
    Zrób sobie dodatkowy przycisk do włączania i wyłączania, a przybędzie dodatkowa funkcjonalność - sterowanie ręczne i będziesz mógł ustawić stan początkowy.
  • #12
    Qetli
    Level 13  
    To mi nie rozwiązuje problemu
  • #13
    kuuczoo
    Level 26  
    Jeśli chcesz wziąć pod uwagę możliwość wyłączenia zasilania to zrób to tak:
    ..zamiana czasów na minuty (sekundy) od północy...
    if (czas_start > czas_stop) then
       if (czas>=czas_start or czas<czas_stop) then 
          set_bit
       else 
          reset_bit
       end if
    else
       if (czas>=czas_start and czas<czas_stop) then 
          set_bit
       else 
          reset_bit
       end if
    end if
  • #14
    Qetli
    Level 13  
    Jeszcze jedno pytanie jak przejść do głównej pętli z np Sub xxx ?
  • #15
    kuuczoo
    Level 26  
    "Przejść" w jakim sensie? Jak się Sub skończy to wracasz do miejsca z którego był wywoływany...
  • #16
    M. S.
    Level 34  
    Miałbym jeszcze jeden pomysł. Te karkołomne IF'y można byłoby przejść przed pętlą główną w celu zsynchronizowania lampy, a później w pętli sprawdzać to co napisałem, no chyba że procek i tak nie będzie miał nic innego do roboty.