logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Zegar DCF77 z termometrem 2 x ds18b20 i podświetleniem .

Skoniecki 11 Lut 2010 05:23 3057 9
REKLAMA
  • #1 7676654
    Skoniecki
    Poziom 10  
    Witajcie ponownie , w głowie mojej zrodził się nowy pomysł , a że z Bascomem słabo więc znowu zwracam się do was .Jak w temacie chcę złożyć zegarek synchronizowany sygnałem DCF 77 , termometrem in - out na 2 x ds18b20 pod jedny gniazdem 1-wire , datą i podświetleniem włączanym czasowo po naciśnięciu klawisza. Mam parę programików do obsługi zegara dcf , do termometru i samodzielnie one działają ale po połączeniu ich do kupy nie wyświetlają nic,lub wyświetlają 1 z 4 żądanych linii a reszta pojawia się tylko na ułamek sekundy , bądź też wyświetla wszystko tj.
    1 linia - godzina
    2 linia - data
    3 linia - temp wew
    4 linia - temp zew
    ale linia godziny i daty nie są aktualizowane godzina pozostaje na 00:00:01, i koniec.
    W załączniku programiki z których próbowałem coś sklecić , może ktoś przerabiał już ten temat .Proszę o poradę ,pomoc. P.S Z czasem będę chciał dodać obsługę 2 klawiszy :
    1 do zmiany ustawianego parametru -godzina , minuta, dzień ,miesiąc,rok
    2 do zmiany wartości danego parametru
  • REKLAMA
  • #2 7676753
    leon1313
    Poziom 15  
    wklej cały program, a nie poszczególne części, które i tak ci działają.
  • #3 7678327
    Skoniecki
    Poziom 10  
    Oto kod całego programu , wyświetla wszystkie linie ,jednak w momencie gdy zaczyna odczytywać temperature- ekran zaczyna mrygać, wygasza co ok 1s na 1s, potem kilka razu krócej aż przez całą sekundę jest obraz i tak od nowa .Po paru minutach chyba łapie błąd bo wyświetlacz zaczyna wyświetlać znaki graficzne jakie ma w pamięci.

                'Zegar DCF77
    $regfile = "m8def.dat"
    $crystal = 8000000
    $lib "dcf77.lib"
    'Sygnał z odbiornika DCF podłączony do Portb.2
    Config Dcf77 = Pinb.2 , Debug = 1 , Inverted = 0 , Check = 1 , Update = 0 , Updatetime = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1 , Gosub = Sectic
    'Config Dcf77 = Pinb.2 , Debug = 1 , Inverted = 0 , Check = 1 , Update = 0 , Updatetime = 0 , Switchpower = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1 , Gosub = Sectic
    'Config Dcf77 = Pinb.1 , Debug = 1 , Inverted = 0 , Check = 2 , Update = 0 , Updatetime = 0 , Switchpower = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1 , Gosub = Sectic
    
    
    'Wyświetlacz LCD 16*2. Sygnały jak poniżej.
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Lcd = 20 * 4
    Config 1wire = Portb.0                                      'deklaracja portu na którym będ? podpięte DS18b20
    
    Dim I1 As Integer , Ss1 As String * 6
    Dim I2 As Integer , Ss2 As String * 6
    
    
    Dim Dsid1(8) As Byte
    Dim Dsid2(8) As Byte
    Dim B As Byte                                               'deklaracja zmiennej do odczytu kodów ID
    Dim W As Byte                                               'deklaracja zmiennej do odczytu ilo?c czujników
    
    Deflcdchar 0 , 8 , 20 , 11 , 4 , 4 , 4 , 3 , 32             'znak stopnia Celsjusza
    Cls
    'Lcd " " ;                                                   'ekran startowy (pojawia się tylko podczas wł?czania urz?dzenia)
    'Cursor Off
    'Locate 1 , 17
    'Lcd " termometr "
    'Wait 5
    'Cls
    W = 1wirecount()
    'Locate 2 , 17
    'Lcd "Czujniki:"                                             'Informuje ile czujników jest podpiętych do układu (pojawia się tylko podczas wł?czania urz?dzenia)
    'Waitms 500
    'Locate 2 , 27
    'Lcd W
    'Wait 3
    'Cls                                                         'Znajd? pierwszy czujnik podpięty do portu
    Dsid1(1) = 1wsearchfirst()                                  'Znajd? kolejny czujnik podpięty do portu
    Dsid2(1) = 1wsearchnext()
    
    
    Enable Interrupts
    Config Date = Dmy , Separator = /
    Do
    Wait 5
    
    Do
    1wreset
    1wwrite &H55
    1wverify Dsid1(1)                                           'wysyłamy adres pierwszego czujnika
    1wwrite &HBE
    I1 = 1wread(2)
    '---------------------------------
    1wreset
    1wwrite &H55
    1wverify Dsid2(1)                                           'wysylam adres drugiego czujnika
    1wwrite &HBE
    I2 = 1wread(2)
    '--------konwersja temp dla wszystkich dsow
    1wreset
    1wwrite &HCC
    1wwrite &H44
    Wait 1
    
    '****Je?li pracujesz z wy?wietlaczem innym niż 2x20 to tutaj trzeba wprowadzić zmiany w LOCATE********
    
    I1 = I1 * 10
    I1 = I1 / 16
    'If I1 > 0 Then Cls                                          'korekta przesuniecia znaku st C przy przej?ciu z temp ujemnej na dodatni?
    Ss1 = Str(i1)
    Ss1 = Format(ss1 , " 0.0")
    
    I2 = I2 * 10
    I2 = I2 / 16
    'If I2 > 0 Then Cls
    Ss2 = Str(i2)
    Ss2 = Format(ss2 , " 0.0")
    
    Loop
    
    Loop
    
    'Co sekundę aktualizuje wyświetlacz
    Sectic:
       Cls
       Locate 1 , 1
          Lcd Time$ ; "    ";
       If Pinb.2 = 0 Then Lcd "Rcvr" Else Lcd "    "
       Locate 2 , 1
       Lcd Date$
    
       Locate 2 , 17                                            'Pozycja wy?wietlania nazwy i temperatury (1.1 -> 1 linia 1 kolumna, 2.10 -> 2 linia 10 kolumna itd)
    Lcd "ZEW: " ; Ss1 ; Chr(0) ;
        Locate 1 , 17
    Lcd "WEW: " ; Ss2 ; Chr(0) ;
       Locate 2 , 1
       Lcd Date$
       Return
    
    End

    EDIT. Troszkę ztuningowałem , wyświetla poprawnie 4 linie,chociaż co 1 sekundę widoczne mrugnięcie, ale jest przesunięcie wyświetlanych temperatur:

    WEW:_26.6C
    ZEW:__-3.6C
    nie bardzo wiem jak to poprawić i gdzie oraz jak dopisać obsługę klawiszy.
    Może jakieś osobne suby w których będzie zawarta instrukcja , ale później trzeba ją wywołać naciśnięciem przycisku (gdzie dać wywołanie , jak rozbić czas na godz ,min ,żeby później móc je zwiększać).
  • REKLAMA
  • #4 7679437
    leon1313
    Poziom 15  
    Po co ci te 2-a do..loop?
    W sectic powinneś mieć:
    cls
    wyświetlenie godziny
    wyświetlenie daty
    pobranie danych z DS-ów i ich wyświetlenie
    na końcu zlecenie konwersji temperatury dla DS

    i zlikwiduj to end sub na końcu!
  • #5 7679819
    Skoniecki
    Poziom 10  
    Na razie jest tak :
                'Zegar DCF77
    $regfile = "m8def.dat"
    $crystal = 8000000
    $lib "dcf77.lib"
    'Sygnał z odbiornika DCF podłączony do Portb.2
    Config Dcf77 = Pinb.2 , Debug = 1 , Inverted = 0 , Check = 1 , Update = 0 , Updatetime = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1 , Gosub = Sectic
    'Config Dcf77 = Pinb.2 , Debug = 1 , Inverted = 0 , Check = 1 , Update = 0 , Updatetime = 0 , Switchpower = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1 , Gosub = Sectic
    'Config Dcf77 = Pinb.1 , Debug = 1 , Inverted = 0 , Check = 2 , Update = 0 , Updatetime = 0 , Switchpower = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1 , Gosub = Sectic
    
    
    'Wyświetlacz LCD 16*2. Sygnały jak poniżej.
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Lcd = 20 * 4
    Config 1wire = Portb.0                                      'deklaracja portu na którym będ? podpięte DS18b20
    
    Dim I1 As Integer , Ss1 As String * 6
    Dim I2 As Integer , Ss2 As String * 6
    
    
    Dim Dsid1(8) As Byte
    Dim Dsid2(8) As Byte
    Dim B As Byte                                               'deklaracja zmiennej do odczytu kodów ID
    Dim W As Byte                                               'deklaracja zmiennej do odczytu ilo?c czujników
    
    Deflcdchar 0 , 8 , 20 , 11 , 4 , 4 , 4 , 3 , 32             'znak stopnia Celsjusza
    Cls
    'Lcd " " ;                                                   'ekran startowy (pojawia się tylko podczas wł?czania urz?dzenia)
    'Cursor Off
    'Locate 1 , 17
    'Lcd " termometr "
    'Wait 5
    'Cls
    W = 1wirecount()
    'Locate 2 , 17
    'Lcd "Czujniki:"                                             'Informuje ile czujników jest podpiętych do układu (pojawia się tylko podczas wł?czania urz?dzenia)
    'Waitms 500
    'Locate 2 , 27
    'Lcd W
    'Wait 3
    'Cls                                                         'Znajd? pierwszy czujnik podpięty do portu
    Dsid1(1) = 1wsearchfirst()                                  'Znajd? kolejny czujnik podpięty do portu
    Dsid2(1) = 1wsearchnext()
    
    
    Enable Interrupts
    Config Date = Dmy , Separator = /
    Do
    Wait 5
    
    
    1wreset
    1wwrite &H55
    1wverify Dsid1(1)                                           'wysyłamy adres pierwszego czujnika
    1wwrite &HBE
    I1 = 1wread(2)
    '---------------------------------
    1wreset
    1wwrite &H55
    1wverify Dsid2(1)                                           'wysylam adres drugiego czujnika
    1wwrite &HBE
    I2 = 1wread(2)
    '--------konwersja temp dla wszystkich dsow
    1wreset
    1wwrite &HCC
    1wwrite &H44
    Wait 1
    
    '****Je?li pracujesz z wy?wietlaczem innym niż 2x20 to tutaj trzeba wprowadzić zmiany w LOCATE********
    
    I1 = I1 * 10
    I1 = I1 / 16
    'If I1 > 0 Then Cls                                          'korekta przesuniecia znaku st C przy przej?ciu z temp ujemnej na dodatni?
    Ss1 = Str(i1)
    Ss1 = Format(ss1 , " 0.0")
    
    I2 = I2 * 10
    I2 = I2 / 16
    'If I2 > 0 Then Cls
    Ss2 = Str(i2)
    Ss2 = Format(ss2 , " 0.0")
    
    
    
    Loop
    
    'Co sekundę aktualizuje wyświetlacz
    Sectic:
       Cls
       Locate 1 , 1
          Lcd Time$ ; "    ";
       If Pinb.2 = 0 Then Lcd "Rcvr" Else Lcd "    "
       Locate 2 , 1
       Lcd Date$
    
       Locate 2 , 17                                            'Pozycja wy?wietlania nazwy i temperatury (1.1 -> 1 linia 1 kolumna, 2.10 -> 2 linia 10 kolumna itd)
    Lcd "ZEW:" ;
        Locate 2 , 23
    Lcd Ss1 ; Chr(0) ;
    
        Locate 1 , 17
    Lcd "WEW:" ;
       Locate 1 , 23
    Lcd Ss2 ; Chr(0) ;
    
       Locate 2 , 1
       Lcd Date$
       Return
    
       End
    
    


    Zlikwidowanie drugej pętli do - loop powoduje po każdym wyświetleniu temperatury resetowanie i ponowne uruchomienie procedur mierzenia temperatury, i tak w kółko.
    Na razie programik działa ,tylko nie mogę ustawić wyświetlania równo , dziesiątki pod dziesiątkami ,jedności pod jednościami itp. Jak to zwalczę powalcze z klawiszami.
    Tylko nie wiem co będzie lepsze , czy obsługa 1 klaw. do godzin (zwiększanie ) i 1 klawisz do minut itd. ale da to minimum 5 klawiszy z datą , czy też 2 lub 3 klawisze jeden do wyboru jednostki która ma być zmieniana i 1 lub 2 do zmian , ale tego podprogramu to ja nie napisze.Jak zrobić ,żeby wyświetlacz nie był odświeżany a zmieniało się tylko to co na bieżąco się zmienia (minuty , sekundy itp), ewentualnie żeby był odświeżany na tyle szybko ,żeby było to nie zauważalne.
  • #6 7680258
    leon1313
    Poziom 15  
    Najlepiej na 3 klawisze, ale nadal masz złą koncepcje kodu. albo decydujesz się wyświetlać wszystko przy obsłudze przerwania ( DS potrzebuje 750ms na konwersję), w jedne sekundzie chyba się wyrobisz, albo za pomocą przerwania ustwaić flagę zlecenia wykonania programu (hm.. profesjonalnie :-) ).
    ogólny algorytm tego powinien wyglądać następująco:
    
    
    
    ...
    dim flaga1 as bit
    ...
    ...
    do
        if flaga1=1 then
            flaga1=0
            wyświetl date
            wyświetl temp
            zleć konwersje
        end if
        ewentualna obsluga przycisku 1
        ewentualna obsluga przycisku 2
        itp...
    loop
    sectic:
        set flaga1
    return
    
  • REKLAMA
  • #7 7683412
    Skoniecki
    Poziom 10  
    Witam , dzisiaj chyba za dużo nie powalczę -dopiero w niedziele będzie więcej czasu.
    Leon1313 dziękuje za pomoc ,czy obsługę klawiszy można napisać tak :
    Załóżmy flaga Mode której stan będzie się zmieniał po naciśnięciu przycisku 1 stan flagi 0, po naciśnięciu 1 i tak do 5 po 5 znów 0.
    If Mode > 5 then
    Mode = 0
    Klawisz UP i tu warunek
    If mode = 1 and up = 0 then incr (i tu jakieś odwołanie do godziny ) albo H=H+1
    If mode = 2 and up = 0 then incr minuta albo MIN=MIN+1
    podobnie z minutami i całą datą po kolei.
    Tylko nie wiem jak rozdzielić czas i datę na pojedyńcze wartości które będę mógł modyfikować.

    
    Cls
       Locate 1 , 1
       Lcd Time$ ; "    ";                                     'Wyświetlenie czasu
       If Pinb.2 = 0 Then Lcd "Rcvr" Else Lcd "    "
       Locate 2 , 1
       Lcd Date$                                                'Wyświetlenie daty
    
       Locate 2 , 17                                            
    Lcd "ZEW:" ;
        Locate 2 , 23
    Lcd Ss1 ; Chr(0) ;
    Locate 1 , 17
    Lcd "WEW:" ;
       Locate 1 , 23
    Lcd Ss2 ; Chr(0) ;
    
    
    1wreset
    1wwrite &HCC
    1wwrite &H44 
          Return 
    

    Czy tak ma wyglądać ta flaga czy coś pominąłem ?
  • REKLAMA
  • #8 7683786
    leon1313
    Poziom 15  
    Flaga to flaga, znacznik, że masz wykonać część programu :-)

    Wyjaśnię to inaczej. Przerwanie sectic co 1 sekundę ustawia flaga1 w stan wysoki. główny program w pętli do...loop, jeżeli wykryje, że flaga 1 jest ustawiona w stan wysoki, wykona polecenia między THEN a END IF, czyli najpierw:
    - zresetuje tą flagę, aby nie wykonać programu dopóki przerwanie znowu na to nie pozwoli
    - powinien wyświetlić czas i datę
    - odczytać temperaturę z DS ( czego ci brak) i wyświetlić ją
    - zlecić ponownie konwersję ( tu przypominam, pętla if flaga1..end if jest wykonywana co sekundę!), i przy ponownym przebiegu powtórzyć
    - to, co jest w do.loop a za if flaga1..end if będzie szybko wykonywane, więc warto tu dać obsługę klawiszy i menu
    Jeśli masz problemy z uporządkowaniem kodu, podziel to sobie na sub-y : wszakże to nieprofesjonalne, jak jeden z userów już zwrócił mi uwagę, ale pod względem czytelności przydatne.
  • #9 7686516
    Skoniecki
    Poziom 10  
    Witam , program w tej chwili wygląda tak :
    'Zegar DCF77
    $regfile = "m8def.dat"
    $crystal = 8000000
    $lib "dcf77.lib"
    'Sygnał z odbiornika DCF podłączony do Portb.2
    Config Dcf77 = Pinb.2 , Debug = 1 , Inverted = 0 , Check = 1 , Update = 0 , Updatetime = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1 , Gosub = Sectic
    'Config Dcf77 = Pinb.2 , Debug = 1 , Inverted = 0 , Check = 1 , Update = 0 , Updatetime = 0 , Switchpower = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1 , Gosub = Sectic
    'Config Dcf77 = Pinb.1 , Debug = 1 , Inverted = 0 , Check = 2 , Update = 0 , Updatetime = 0 , Switchpower = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1 , Gosub = Sectic
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Lcd = 20 * 4
    Config 1wire = Portb.0                                      'deklaracja portu na którym będ? podpięte DS18b20
    Klmode Alias Portb.3
    Klup Alias Portb.4
    Kldown Alias Pinb.5
    Set Klmode
    Set Klup
    Set Kldown
    
    Dim Flaga1 As Bit
    Dim I1 As Integer , Ss1 As String * 6
    Dim I2 As Integer , Ss2 As String * 6
    Dim Dsid1(8) As Byte
    Dim Dsid2(8) As Byte
    Dim B As Byte                                               'deklaracja zmiennej do odczytu kodów ID
    Dim W As Byte                                               'deklaracja zmiennej do odczytu ilo?c czujników
    
    Deflcdchar 0 , 8 , 20 , 11 , 4 , 4 , 4 , 3 , 32             'znak stopnia Celsjusza
    Cls
    Lcd " " ;                                                   'ekran startowy (pojawia się tylko podczas wł?czania urz?dzenia)
    Cursor Off
    Locate 1 , 17
    Lcd " termometr "
    Wait 5
    Cls
    
    W = 1wirecount()
    Dsid1(1) = 1wsearchfirst()                                  'Znajd? pierwszy czujnik podpięty do portu
    Dsid2(1) = 1wsearchnext()                                  'Znajd? kolejny czujnik podpięty do portu
    
    Enable Interrupts
    Config Date = Dmy , Separator = /
    
    Do
    If Flaga1 = 1 Then
    Flaga1 = 0
    
    1wreset
    1wwrite &H55
    1wverify Dsid1(1)                                           'wysyłamy adres pierwszego czujnika
    1wwrite &HBE
    I1 = 1wread(2)
    '---------------------------------
    1wreset
    1wwrite &H55
    1wverify Dsid2(1)                                           'wysylam adres drugiego czujnika
    1wwrite &HBE
    I2 = 1wread(2)
    '--------konwersja temp dla wszystkich dsow
    1wreset
    1wwrite &HCC
    1wwrite &H44
    Wait 1
    
    I1 = I1 * 10
    I1 = I1 / 16
    If I1 > 0 Then Cls                                          'korekta przesuniecia znaku st C przy przej?ciu z temp ujemnej na dodatni?
    Ss1 = Str(i1)
    Ss1 = Format(ss1 , " 0.0")
    
    I2 = I2 * 10
    I2 = I2 / 16
    If I2 > 0 Then Cls
    Ss2 = Str(i2)
    Ss2 = Format(ss2 , " 0.0")
    Cls
    Locate 1 , 1
    Lcd Time$ ; "    ";
    If Pinb.2 = 0 Then Lcd "Rcvr" Else Lcd "    "
    Locate 2 , 1
    Lcd Date$
    Locate 2 , 17                                               'Pozycja wy?wietlania nazwy i temperatury (1.1 -> 1 linia 1 kolumna, 2.10 -> 2 linia 10 kolumna itd)
    Lcd "ZEW:" ;
    Locate 2 , 23
    Lcd Ss1 ; Chr(0) ;
    Locate 1 , 17
    Lcd "WEW:" ;
    Locate 1 , 23
    Lcd Ss2 ; Chr(0) ;
    Locate 2 , 1
    Lcd Date$
    End If
    ' klawisz 1
    ' klawisz 2
    ' klawisz 3
    Loop
    Sectic:
       Set Flaga1
       Return
    
       End

    Nie pozbyłem się jeszcze uciążliwego mrugnięcia co sekundę - wiem ,że to przez komendę CLS, ale jej nie mogę się pozbyć - czy można coś z tym zrobić ?
    Może da się zmodyfikować czas resetu wyświetlacza, lub niech zmienia tylko te wartości które uległy zmianie.
    Termometr momentami się nie wyrabia i na 1s pokazuje jakąś dziwną temperaturę .
    Jak podzielić godzinę i datę na pojedyńcze wartości do edytowania za pomocą klawiszy Mode ,Up i Down i warunków IF - może ktoś ma pomysł. Jak to jest z zapamiętaniem przez procesor tej modyfikacji, żeby nie było tak ,że zwiększe np. godzine o 1 za pomocą klawisza - a zegarek w pamięci będzie miał o 1 mniej i zwiększona godzina będzie na ekranie przez 2 godziny (mam nadzieje ,że ktoś zrozumiał o co mi chodzi ) .
    Pozdrawiam wszystkich.
    P.S. Cała robota posuwa się etapami , później będę chciał dodać to podświetlenie , i myśle jeszcze o zew kwarcu ew. innym generatorze czasu ,żeby zegarek nie wariował przy braku synchronizacji z dcf i nie skakał nagle o parę godzin ,dni czy lat jak teraz.
  • #10 7688689
    leon1313
    Poziom 15  
    CLS służy do czyszczenia całego LCD - metoda prosta i skuteczna, ale nie najlepsza. Lepiej jest sformatować wyświetlany teks, aby miał stałą długość i "podmieniać" to, co się zmieniło ( użyć rozsądnie Locate).
    Spróbuj usunąć to CLS z pętli DO...LOOP, powinno być ok ( choć nie wiem, jak się zachowa wyświetlanie temperatury
REKLAMA