Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Inteligentny termostat - zapraszam do wspólnej twórczości

26 Mar 2007 09:28 9888 36
  • Moderator Projektowanie
    Witajcie bracia i siostry !

    Od pewnego czasu zafascynowałem się mikrokontrolerami, obkupiłem się w literaturę i podzespoły. Przeczytałem całą księgę Marcina Wiązani "Programowanie mikrokontrolerów w języku BASCOM", zbudowałem prawie wszystkie przykładowe konstrukcje z tej książki ;-)
    Czas najwyższy na budowę czegoś praktycznego, bo żona patrzy na mnie z politowaniem i nie rozumie dlaczego siedzę kilka godzin nad jakimiś tam płytkami po czym z radością oświadczam "kochanie, dioda miga !!" ;-) (dopiero termometr cyfrowy spowodował że popatrzyła dłuższą chwile...).

    Postanowiłem zbudować taki bystry termostat który mam zamiar użyć w domu do sterowania bojlerem, a w pracy grzejnikiem elektrycznym - tak więc zamysł i konstrukcja będzie taka sama.

    Założenia projektu:

    - urządzenie musi być banalne w obsłudze
    - termostat jak sama nazwa wskazuje musi utrzymywać zadaną temperaturę
    - inteligentny termostat musi dodatkowo robić to w określonych godzinach w określone dni
    - musi być możliwość ustalenia że np. od poniedziałku do piątku temperatura w bojlerze powinna mieć np. 50 stopni i to na godzinę 6:30 rano, po pracy warto wziąć prysznic więc około 19-tej też powinno być ciepło ;-). W weekendy przydałoby się zapewnić stały dopływ ciepłej wody.

    Konstrukcja będzie oparta na:

    - BASCOMie
    - Atmega8
    - termometr DS1820
    - wyświetlacz LCD 16x2
    - prosta klawiatura (przód,tył,akceptuj) lub... tylko nie wiem jeszcze jak to zrobić - pokrętło (kręce w lewo, prawo, wciskam dla akceptacji)

    tyle wiem, proszę o sugestie :

    - zegar czasu rzeczywistego czy programowo w Atmega ?
    - jak zapamiętać nastawy ? EEPROM ?
    - jak podtrzymać zasilanie ?
    - włączać grzałkę triakiem czy przekaźnikiem ?

    Mam nadzieję że szanowne grono przyczyni się do zbudowania urządzenia, ja ze swej strony mogę zapewnić fotoreportaż z postępów prac, oczywiście udostępnić kod oraz... przetestować to w ekstremalnych warunkach. Mam żonę blondynę, więc jeśli docelowo zaprogramuje ona nasz termostat to będzie lepszy test niż norma CE :D

    Na początek wrzucam zarys schematu oraz rzut oka na "warsztat"

    Pozdrawiam i zachęcam do zabawy.

    Inteligentny termostat - zapraszam do wspólnej twórczości

    Inteligentny termostat - zapraszam do wspólnej twórczości

    Inteligentny termostat - zapraszam do wspólnej twórczości
  • Poziom 34  
    Witam.
    Niewiele mogę pomóc w programowaniu ale trzeba zacząc od założeń - może takie:

    http://ssl.allegro.pl/item178397604_avr_atmega8_jako_termostat_cyfrowy_od_ss_f_vat.html
    w najgorszym wypadku można skorzystać z takiej oferty i adaptować do potrzeb:
    http://ssl.allegro.pl/item178424793_swiat_mikroprocesorow_cyfrowy_termometr.html
    Moderowany przez And!:


    Aukcje z allegro już dawno nieaktualne,
    właśnie dlatego zgodnie z regulaminem nie ma sensu podawać linków
    do materiałów krótkotrwałych.

  • Poziom 34  
    może jest zapisywane w eepromie?
    trzeba poszukać ne edw.com.pl robili podobne rzeczy jako sterowniki do akwarium może zamieścili źródła
  • Poziom 36  
    Kuniarz napisał:
    no w eepromie to bankowo, tylko pytanie - jak z poziomu Bascom'a zapisać coś w eepromie procesora ? Czy musi być do tego użyty zewnętrzny eeprom ?


    Z helpu BASCOM

    Code:
    Dim Store As Eram Byte , B As Byte
    
    B = 10                                                      'assign value to b
    Store = B                                                   'value is stored in EPROM !
    B = Store                                                   'get the value back


    proponuję też obejrzeć rozkaz writeeeprom
  • Moderator Projektowanie
    stronka ciekawa, dziękuję, ale opisany tam zegar... zeruje się po zaniku prądu. W przypadku termostatu jest to niedopuszczalne, za dużo roboty z powtórnym ustawieniem wszystkich czasów i temperatur...
    Szperając po Elektrodzie znalazłem też wiele postów na temat RTC DS1307, póki co zamówiłem jedne i drugie i mam nadzieję za 2 dni coś już wlutować i walczyć z tematem.
  • Poziom 23  
    Mnie się wydaje, że taki termostat to na tyle mało pracochłonne, że nie ma sensu korzystać z zewnętrznego RTC.
    Wystarczy ustawić Timer i co jakiś czas zliczać te upływające sekundy / minuty / godziny

    Pamiętaj, żeby twój termostat miał pętlę histerezy, w celu uniknięcia przełączania się przy wahaniach temperatury.

    A jeśli chodzi o sterowanie, to takie pokrętło obrotowe, nazywa się enkoder.
    Działa zazwyczaj tak, że, na 2 wyjściach po przekręceniu zmieniają się stany z 0 na 1 i na odwrót, z tym, że nie jednocześnie. Jeden z nich następuje wcześniej po tym można poznać kierunek obrotu.

    Zachęcam też do spróbowania języka C pod te mikrokontrolery. Nic w tym bardziej skomplikowanego, czasami trzeba troszkę więcej samemu zrobić, ale za to oszczędność kodu wszystko wynagradza.
    Pozdrawiam
  • Moderator Projektowanie
    Mad Bekon napisał:
    Mnie się wydaje, że taki termostat to na tyle mało pracochłonne, że nie ma sensu korzystać z zewnętrznego RTC.
    Wystarczy ustawić Timer i co jakiś czas zliczać te upływające sekundy / minuty / godziny

    Pamiętaj, żeby twój termostat miał pętlę histerezy, w celu uniknięcia przełączania się przy wahaniach temperatury.

    A jeśli chodzi o sterowanie, to takie pokrętło obrotowe, nazywa się enkoder.
    Działa zazwyczaj tak, że, na 2 wyjściach po przekręceniu zmieniają się stany z 0 na 1 i na odwrót, z tym, że nie jednocześnie. Jeden z nich następuje wcześniej po tym można poznać kierunek obrotu.

    Zachęcam też do spróbowania języka C pod te mikrokontrolery. Nic w tym bardziej skomplikowanego, czasami trzeba troszkę więcej samemu zrobić, ale za to oszczędność kodu wszystko wynagradza.
    Pozdrawiam


    wszystko OK, ale cały czas wracamy do punktu wyjścia - urzadzenie musi mieć bateryjne podtrzymania zegara.
  • Poziom 25  
    Zastosuj PCF8583 tam masz zegar czasu i jednoczesnie dużo wolnej pamięci , gdzie będziesz mógł zapisać nastawy. Jeśli teraz dasz podtrzymanie PCF-a z pastylki 3V to i nastawy zachowają sie w PCF-ie. Nie będziesz wtedy musiał stosować innego eepromu do zapamiętywania nastawów.
  • Poziom 23  
    ale i tak pozostaje problem podtrzymania baterii.
    Po co wkładać dodatkowy układ w układ?
    W Atmegach jest wystarczająco eepromu, żeby trzymać ustawienia. Wsadzić pastylke do podtrzymywania, na jedno wejście zrobić czujnik zasilania z sieci. Jak braknie prądu to niech procek idzie spać i tylko niech czas zlicza. Konsumpcja takiego układu jest bardzo niska.
  • Moderator Projektowanie
    Mad Bekon napisał:
    ale i tak pozostaje problem podtrzymania baterii.
    Po co wkładać dodatkowy układ w układ?
    W Atmegach jest wystarczająco eepromu, żeby trzymać ustawienia. Wsadzić pastylke do podtrzymywania, na jedno wejście zrobić czujnik zasilania z sieci. Jak braknie prądu to niech procesor idzie spać i tylko niech czas zlicza. Konsumpcja takiego układu jest bardzo niska.


    hmmm... mógłbyś rozwinąć myśl i może podeprzeć listingiem/schematem ? brak RTC zmniejszy koszt układu i go uprości (czytaj - mniej pierdół do zakłucania się...)
  • Moderator Projektowanie
    Do układu doszedł właśnie RTC, oto schemat po poprawkach:

    Inteligentny termostat - zapraszam do wspólnej twórczości

    a oto skrypt ktory teoretycznie powinien czytac DS1307 i wyświetlić odczyt na LCD:

    Code:
    $regfile = "m8def.dat"
    
    $crystal = 8000000
    Config 1wire = Portd.1
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Dim Sekundy As Byte
    Dim Minuty As Byte
    Dim Godziny As Byte
    Cursor Off Noblink
    Do
       I2cstart
       I2cwbyte 208
       I2cwbyte 0
       I2cstart
       I2cwbyte 209
       I2crbyte Sekundy , Ack
       I2crbyte Minuty , Ack
       I2crbyte Godziny , Ack
       I2cstop
       Sekundy = Makedec(sekundy)
       Minuty = Makedec(minuty)
       Godziny = Makedec(godziny)
       Lcd Godziny ; ":" ; Minuty ; ":" ; Sekundy
       Waitms 100
    Loop
    End


    podczas kompilacji wywala sie błąd "Unknow Statement [.EQU not found for PORTA:" - błędów jest kilka, zmienia sie ostatni wyraz, po załadowaniu programu na wyswietlaczu śmieci.

    gdzie mam coś nie teges ?
  • Pomocny post
    Poziom 14  
    Witam,

    Problem jest banalny - pomyliłeś transmisję 1-wire z I2C. Brakuje w kodzie konfiguracji magistrali I2C:
    Code:
    Config Sda = Portx.x
    
    Config Scl = Portx.x

    Pozdrawiam
  • Pomocny post
    VIP Zasłużony dla elektroda
    Po odczycie ostatniego bajtu danych - w Twoim wypadku godziny powinieneś wystawić znacznik Nack.
  • Moderator Projektowanie
    Dziękuję za porady, kod po poprawce wygląda tak :

    Code:
    $regfile = "m8def.dat"
    
    $crystal = 8000000
    Config Sda = Portd.0
    Config Scl = Portd.1
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Dim Sekundy As Byte
    Dim Minuty As Byte
    Dim Godziny As Byte
    Cursor Off Noblink
    'Godziny = 10
    'Minuty = 45
    'Sekundy = 10
    'Godziny = Makebcd(godziny)
    'Minuty = Makebcd(minuty)
    'Sekundy = Makebcd(sekundy)
    'I2cstart
    'I2cwbyte 208
    'I2cwbyte 0
    'I2cwbyte Sekundy
    'I2cwbyte Minuty
    'I2cwbyte Godziny
    'I2cstop

    Do
       I2cstart
       I2cwbyte 208
       I2cwbyte 0
       I2cstart
       I2cwbyte 209
       I2crbyte Sekundy , Ack
       I2crbyte Minuty , Ack
       I2crbyte Godziny , Nack
       I2cstop
       Sekundy = Makedec(sekundy)
       Minuty = Makedec(minuty)
       Godziny = Makedec(godziny)
       Cls
       Lcd Godziny ; ":" ; Minuty ; ":" ; Sekundy
       Waitms 100
    Loop
    End


    (wyremowane są komendy zapisu, bez tego zegra nie liczy, ale wystarczy zrobic to jednorazowo)

    Zabieram się zatem za pisanie kodu z opcją ustawiania godziny i daty
  • Moderator Projektowanie
    oook, do schematu doszły trzy przyciski zwierane do masy na liniach PB3-PB5
    poniżej wrzucam kod który pozwala na wyświetlenie daty i czasu oraz zaprogramowanie.
    W celu wejścia w programowanie należy przycisnac na 2 sekundy przycisk

    Nie rozwiązałem jeszcze dwóch problemów:
    - niektóre miesiące mają 30 inne 31 dni (to nie problem...)
    - jak obliczyć który rok jest przestępnym ?

    (tak teraz sobie myślę że programowanie daty należy rozpocząć od roku ;-) )

    Code:
    $regfile = "m8def.dat"
    
    $crystal = 8000000
    Config Sda = Portd.0
    Config Scl = Portd.1
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Pinb.3 = Input
    Config Pinb.4 = Input
    Config Pinb.5 = Input

    Dim Sekundy As Byte
    Dim Minuty As Byte
    Dim Godziny As Byte
    Dim Dzientygodnia As Byte
    Dim Dzien As Byte
    Dim Miesiac As Byte
    Dim Rok As Byte
    Dim Dalej As Byte                                           'zmienna pomocnicza przy programowaniu
    Dim A As Byte                                               'zmienna pomocnicza petli

    Dim N_dzien(99)as Byte                                      'nastawa dnia zdarzenia
    Dim N_godzina(99)as Byte                                    'nastawa godziny
    Dim N_minuty(99)as Byte                                     'nastawa minut zdarzenia
    Dim N_temperatura(99) As Byte                               'jaka ma byc temperatura (jesli zero to wylaczenie)

    Dalej = 0

    Declare Sub Rtc_odczyt
    Declare Sub Rtc_zapis
    Declare Sub Rtc_wyswietl
    Declare Sub Programowanie
    Declare Sub Zerowanie_nastaw

    Cursor Off Noblink

    S_wiecej Alias Pinb.3
    S_mniej Alias Pinb.4
    S_wybierz Alias Pinb.5

    Set Portb.3
    Set Portb.4
    Set Portb.5

    Zerowanie_nastaw

    Do
       If S_wybierz = 0 Then
          Wait 2
             If S_wybierz = 0 Then
                Programowanie
             End If
       End If
       Rtc_odczyt
       Rtc_wyswietl
       Waitms 100
       Loop
    End

    Rtc_odczyt:
       I2cstart
       I2cwbyte 208
       I2cwbyte 0
       I2cstart
       I2cwbyte 209
       I2crbyte Sekundy , Ack
       I2crbyte Minuty , Ack
       I2crbyte Godziny , Ack
       I2crbyte Dzientygodnia , Ack
       I2crbyte Dzien , Ack
       I2crbyte Miesiac , Ack
       I2crbyte Rok , Nack
       I2cstop
       Sekundy = Makedec(sekundy)
       Minuty = Makedec(minuty)
       Godziny = Makedec(godziny)
       Dzientygodnia = Makedec(dzientygodnia)
       Dzien = Makedec(dzien)
       Miesiac = Makedec(miesiac)
       Rok = Makedec(rok)
    Return

    Rtc_zapis:
       Godziny = Makebcd(godziny)
       Minuty = Makebcd(minuty)
       Sekundy = Makebcd(sekundy)
       Dzientygodnia = Makebcd(dzientygodnia)
       Dzien = Makebcd(dzien)
       Miesiac = Makebcd(miesiac)
       Rok = Makebcd(rok)
       I2cstart
       I2cwbyte 208
       I2cwbyte 0
       I2cwbyte Sekundy
       I2cwbyte Minuty
       I2cwbyte Godziny
       I2cwbyte Dzientygodnia
       I2cwbyte Dzien
       I2cwbyte Miesiac
       I2cwbyte Rok
       I2cstop
    Return

    Rtc_wyswietl:

       Cls
       Lcd Godziny ; ":" ; Minuty ; ":" ; Sekundy
       Lowerline
       Lcd Dzien ; "." ; Miesiac ; "." ; Rok ; "dz." ; Dzientygodnia
    Return

    Programowanie:
       Dalej = 0
       Cls
       Lcd "--PROGRAMOWANIE--"
       Do
          Waitms 25
       Loop Until S_wybierz = 1                                 'czekamy na puszczenie "wybierz"

    Do
       Lowerline
       If Godziny < 10 Then
          Lcd "godzina: 0" ; Godziny
       Else
          Lcd "godzina: " ; Godziny
       End If

       If S_wybierz = 0 Then
          Waitms 25
          If S_wybierz = 0 Then
             Dalej = 1
          End If
       End If

       If S_wiecej = 0 Then
          Waitms 25
          If S_wiecej = 0 Then
             Incr Godziny
             If Godziny = 24 Then
                Godziny = 0
             End If
             Waitms 200
          End If
       End If
       If S_mniej = 0 Then
          Waitms 25
          If S_mniej = 0 Then
             Decr Godziny
             If Godziny = -1 Then
                Godziny = 23
             End If
             Waitms 200
          End If
       End If
    Loop Until Dalej = 1
    Dalej = 0
    Cls
    Lcd "--PROGRAMOWANIE--"
    Do
       Waitms 25
    Loop Until S_wybierz = 1

    Do
       Lowerline
       If Minuty < 10 Then
          Lcd "minuty: 0" ; Minuty
       Else
          Lcd "minuty: " ; Minuty
       End If

       If S_wybierz = 0 Then
          Waitms 25
          If S_wybierz = 0 Then
             Dalej = 1
          End If
       End If

       If S_wiecej = 0 Then
          Waitms 25
          If S_wiecej = 0 Then
             Incr Minuty
             If Minuty = 60 Then
                Minuty = 0
             End If
             Waitms 200
          End If
       End If
       If S_mniej = 0 Then
          Waitms 25
          If S_mniej = 0 Then
             Decr Minuty
             If Minuty = -1 Then
                Minuty = 59
             End If
             Waitms 200
          End If
       End If
    Loop Until Dalej = 1
    Dalej = 0

    Cls
    Lcd "--PROGRAMOWANIE--"
    Do
       Waitms 25
    Loop Until S_wybierz = 1

    Do
       Lowerline
       If Rok < 10 Then
          Lcd "rok: 200" ; Rok
       Else
          Lcd "rok: 20" ; Rok
       End If

       If S_wybierz = 0 Then
          Waitms 25
          If S_wybierz = 0 Then
             Dalej = 1
          End If
       End If

       If S_wiecej = 0 Then
          Waitms 25
          If S_wiecej = 0 Then
             Incr Rok
             If Rok = 50 Then
                Rok = 0
             End If
             Waitms 200
          End If
       End If
       If S_mniej = 0 Then
          Waitms 25
          If S_mniej = 0 Then
             Decr Rok
             If Rok = -1 Then
                Rok = 50
             End If
             Waitms 200
          End If
       End If
    Loop Until Dalej = 1
    Dalej = 0

    Cls
    Lcd "--PROGRAMOWANIE--"
    Do
       Waitms 25
    Loop Until S_wybierz = 1

    Do
       Lowerline
       If Miesiac < 10 Then
          Lcd "miesiac: 0" ; Miesiac
       Else
          Lcd "miesiac: " ; Miesiac
       End If

       If S_wybierz = 0 Then
          Waitms 25
          If S_wybierz = 0 Then
             Dalej = 1
          End If
       End If

       If S_wiecej = 0 Then
          Waitms 25
          If S_wiecej = 0 Then
             Incr Miesiac
             If Miesiac = 13 Then
                Miesiac = 1
             End If
             Waitms 200
          End If
       End If
       If S_mniej = 0 Then
          Waitms 25
          If S_mniej = 0 Then
             Decr Miesiac
             If Miesiac = 0 Then
                Miesiac = 12
             End If
             Waitms 200
          End If
       End If
    Loop Until Dalej = 1
    Dalej = 0

    Cls
    Lcd "--PROGRAMOWANIE--"
    Do
       Waitms 25
    Loop Until S_wybierz = 1

    Do
       Lowerline
       If Dzien < 10 Then
          Lcd "dzien: 0" ; Dzien
       Else
          Lcd "dzien: " ; Dzien
       End If

       If S_wybierz = 0 Then
          Waitms 25
          If S_wybierz = 0 Then
             Dalej = 1
          End If
       End If

       If S_wiecej = 0 Then
          Waitms 25
          If S_wiecej = 0 Then
             Incr Dzien
             If Miesiac = 1 Or Miesiac = 3 Or Miesiac = 5 Or Miesiac = 7 Or Miesiac = 8 Or Miesiac = 10 Or Miesiac = 12 Then
                If Dzien = 32 Then
                   Dzien = 1
                End If
             Else
                If Dzien = 31 Then
                      Dzien = 1
                End If
             End If
             Waitms 200
          End If
       End If
       If S_mniej = 0 Then
          Waitms 25
          If S_mniej = 0 Then
             Decr Dzien
             If Miesiac = 1 Or Miesiac = 3 Or Miesiac = 5 Or Miesiac = 7 Or Miesiac = 8 Or Miesiac = 10 Or Miesiac = 12 Then
                If Dzien = 0 Then
                Dzien = 31
                 End If
             Else
                If Dzien = 0 Then
                Dzien = 30
                End If
             End If
             Waitms 200
          End If
       End If
    Loop Until Dalej = 1
    Dalej = 0

    Sekundy = 0
    Rtc_zapis
    Return

    Zerowanie_nastaw:

    For A = 0 To 99
       N_dzien(a) = 0
       N_godzina(a) = 0
       N_minuty(a) = 0
       N_temperatura(a) = 0
    Next A
    Return

    EDIT: poprawiony kod.
  • VIP Zasłużony dla elektroda
    Zapis z noty katalogowej ds1307:
    "The end of the month date is automatically adjusted for months with fewer than 31 days, including corrections for
    leap year. "

    Spooory juz się listing zrobił ;) z ciekawości ile zajmuje?
  • Moderator Projektowanie
    hmmm... jestem juz w domu wiec listingu nie zmierzę... ale faktycznie wygląda okazale :(
    co do DS1307 to faktycznie w samym układzie data pójdzie poprawnie, chodziło mi tylko o programowanie przez użytkownika, gdyż teoretycznie w tej chwili można ustawić 31.02.2007 i zapisać w DS (swoją drogą ciekawe jak sie zachowa :D)
  • Moderator Projektowanie
    poprawiłem kod, w tej chwili rozpoznaje miesiące 30 i 31 dniowe, temat roku przestępnego odpuściłem - układ sam to poprawi...

    ...ale, kurcze pojawił się z rana kolejny problem, mianowicie wyobrażałem sobie że DS1307 w rejestrze DAY zapamiętuje konkretny dzien tygodnia dla danej daty (np. że 30 marca 2007 jest piątek), a tu nici , bo DAY to licznik dni po przejściu godziny przez 0:00 ...
    Ma ktoś pomysł jak obliczyć że np. po ustawieniu daty na 11.10.2007 będzie czwartek (w zmienną "dzientygodnia" wpisać np. 4) ??
    ... teoretycznie przy programowaniu mozna spytać użytkownika o dzień, ale przeca termostat miał być dla blondynek ;-)
  • Poziom 39  
    Kuniarz napisał:
    Dobra, dałem sobie spokój, to jest nie do zrobienia w bascomie...

    Eeeeee..... tam , za szybko sie poddałeś ;)
    Kuniarz napisał:

    Ma ktoś pomysł jak obliczyć że np. po ustawieniu daty na 11.10.2007 będzie czwartek (w zmienną "dzientygodnia" wpisać np. 4) ??

    Wzór jest nieziemsko prosty :D
    dzien_tygodnia=((rok-1)+((rok-1)/4)+kolejny_dzien_roku) MOD 7
    Wynik to: 0-sobota , 1-niedziela, ... ,6-piątek , a kolejny_dzien_roku to np. dziś mamy 91 dzień w tym roku :D

    To tyle ;)

    Piotrek

    EDIT:
    Poprawiłem dzielaenie , bo było /2 , a powinno być /4
  • Poziom 12  
    Jak otrzymać który jest to dzień w roku z daty?
  • Poziom 39  
    LichyiChydy napisał:
    Jak otrzymać który jest to dzień w roku z daty?

    Odpowiedź brzmi : tabela ;)
    Code:

    Tabela:
    Data 0% , 31% , 59% , 90% , 120% , 151% , 181% , 212% , 243% , 273% , 304% , 334%

    Nie zapominamy oczywiście , o uwzględnieniu w obliczeniach , roku przestępnego :D

    Piotrek
  • Poziom 14  
    Zumek - jesteś wielki - jeśli nie największy...
    Podziwiam twoją wiedzę oraz chęć pomocy "malućkim". Dla mnie jesteś "Guru".
    Mam tylko nadzieję , że jeśli kiedykolwiek "wyskoczę" z jakimś błachym problemem , będziesz miał na tyle cierpliwości aby mi pomóc.
    Oby zdrowie i zapał Cię nie opuściły nigdy.
    Pozdrawiam całe forum.
    P.s. Bez poprawki na 1 kwietnia.
  • Moderator Projektowanie
    Oczywiście to że się poddałem było żarcikiem primaaprilisowym ;-)
    Dziękuję za wskazówki odnośnie roku przestępnego itp. póki co ich nie zastosowałem, wrócę do tematu po stworzeniu "rdzenia" programu.
    Mało miałem ostatnio czasu, ale zoptymalizowałem trochę kod dodając procedury. Dodałem w menu opcję wyboru czy programujemy zegar czy już gotowe nastawy termostatu. Wklejam kolejny roboczy kod dla zainteresowanych.
    Spróbuję jutro dokończyć podprogram ustawiania nastaw, zrobię zapis do EEPROM no i pozostanie później w główną pętlę dać sprawdzanie czy godzina wskazuje na jakąś nastawę no i czas podłączyć śjakąś grzałkę ;-)

    Code:
    $regfile = "m8def.dat"
    
    $crystal = 8000000
    Config Sda = Portd.0
    Config Scl = Portd.1
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Pinb.3 = Input
    Config Pinb.4 = Input
    Config Pinb.5 = Input

    Dim Sekundy As Byte
    Dim Minuty As Byte
    Dim Godziny As Byte
    Dim Dzientygodnia As Byte
    Dim Dzien As Byte
    Dim Miesiac As Byte
    Dim Rok As Byte
    Dim Nazwa_dnia(7)as String * 9
    Dim Menu1(2)as String * 16
    Dim Menu As Byte
    Dim Dalej As Byte                                           'zmienna pomocnicza przy programowaniu
    Dim A As Byte                                               'zmienna pomocnicza petli
    Dim Nastawa As Byte                                         'numer nastawy (1-99)


    Dim N_dzien(99) As Byte                                     'nastawa dnia
    Dim N_godzina(99) As Byte
    Dim N_minuty(99) As Byte
    Dim N_temperatura(99) As Byte


    Nazwa_dnia(1) = "poniedz."
    Nazwa_dnia(2) = "wtorek"
    Nazwa_dnia(3) = "sroda"
    Nazwa_dnia(4) = "czwartek"
    Nazwa_dnia(5) = "piatek"
    Nazwa_dnia(6) = "sobota"
    Nazwa_dnia(7) = "niedziela"

    Menu1(1) = "   termostat    "
    Menu1(2) = " data i godzina "
    Menu = 2

    Dalej = 0

    Declare Sub Rtc_odczyt
    Declare Sub Rtc_zapis
    Declare Sub Rtc_wyswietl
    Declare Sub Programowanie
    Declare Sub Zerowanie_nastaw
    Declare Sub Zmiana(zmienna As Byte , Byval Minimum As Integer , Byval Maximum As Byte)


    Cursor Off Noblink

    S_wiecej Alias Pinb.3
    S_mniej Alias Pinb.4
    S_wybierz Alias Pinb.5

    Set Portb.3
    Set Portb.4
    Set Portb.5


    Do
       If S_wybierz = 0 Then
          Wait 2
             If S_wybierz = 0 Then
                Programowanie
             End If
       End If
       Rtc_odczyt
       Rtc_wyswietl
       Waitms 100
       Loop
    End

    Zerowanie_nastaw:
    For A = 0 To 99
       N_dzien(a) = 0
       N_godzina(a) = 0
       N_minuty(a) = 0
       N_temperatura(a) = 0
    Next A
    Return

    Rtc_odczyt:
       I2cstart
       I2cwbyte 208
       I2cwbyte 0
       I2cstart
       I2cwbyte 209
       I2crbyte Sekundy , Ack
       I2crbyte Minuty , Ack
       I2crbyte Godziny , Ack
       I2crbyte Dzientygodnia , Ack
       I2crbyte Dzien , Ack
       I2crbyte Miesiac , Ack
       I2crbyte Rok , Nack
       I2cstop
       Sekundy = Makedec(sekundy)
       Minuty = Makedec(minuty)
       Godziny = Makedec(godziny)
       Dzientygodnia = Makedec(dzientygodnia)
       Dzien = Makedec(dzien)
       Miesiac = Makedec(miesiac)
       Rok = Makedec(rok)
    Return

    Rtc_zapis:
       Godziny = Makebcd(godziny)
       Minuty = Makebcd(minuty)
       Sekundy = Makebcd(sekundy)
       Dzientygodnia = Makebcd(dzientygodnia)
       Dzien = Makebcd(dzien)
       Miesiac = Makebcd(miesiac)
       Rok = Makebcd(rok)
       I2cstart
       I2cwbyte 208
       I2cwbyte 0
       I2cwbyte Sekundy
       I2cwbyte Minuty
       I2cwbyte Godziny
       I2cwbyte Dzientygodnia
       I2cwbyte Dzien
       I2cwbyte Miesiac
       I2cwbyte Rok
       I2cstop
    Return

    Rtc_wyswietl:

       Cls
       Lcd Godziny ; ":" ; Minuty ; ":" ; Sekundy
       Lowerline
       Lcd Dzien ; "." ; Miesiac ; "." ; Rok ; "-" ; Nazwa_dnia(dzientygodnia)
    Return

    Programowanie:
    Dalej = 0
    Cls
    Lcd "--PROGRAMOWANIE--"
    Do
    Loop Until S_wybierz = 1                                    'czekamy na puszczenie "wybierz"
    Do
       Lowerline
       Lcd Menu1(menu)
       Call Zmiana(menu , 1 , 3)
    Loop Until Dalej = 1
    Dalej = 0
    Cls
    Lcd "--PROGRAMOWANIE--"
    If Menu = 1 Then Goto Termostat
    If Menu = 2 Then Goto Czas

    Termostat:
    Waitms 25
    Do
    Loop Until S_wybierz = 1                                    'czekamy na puszczenie "wybierz"
    Nastawa = 1
    Cls
    Lcd "Nastawa dla"
    Do
       Lowerline
       Lcd "dnia : " ; Nazwa_dnia(dzientygodnia) ; "    "
       Call Zmiana(dzientygodnia , 1 , 8)
    Loop Until Dalej = 1
    Dalej = 0
    N_dzien(nastawa) = Dzientygodnia
    Waitms 25
    Do
    Loop Until S_wybierz = 1                                    'czekamy na puszczenie "wybierz"
    Cls
    Lcd "ustaw godzine"
    Do
       Lowerline
       Lcd "wlaczenia: " ; Godziny ; " "
       Call Zmiana(godziny , 0 , 24)
    Loop Until Dalej = 1
    Dalej = 0
    N_godzina(nastawa) = Godziny

    Waitms 25
    Do
    Loop Until S_wybierz = 1                                    'czekamy na puszczenie "wybierz"
    Cls
    Lcd "ustaw minuty"
    Minuty = 0
    Do
       Lowerline
       Lcd "wlaczenia: " ; Minuty ; " "
       Call Zmiana(minuty , 0 , 60)
    Loop Until Dalej = 1
    Dalej = 0
    N_minuty(nastawa) = Minuty
    Waitms 25
    Do
    Loop Until S_wybierz = 1                                    'czekamy na puszczenie "wybierz"
    'temperatura czy wylaczenie ? - dopisac

    A = 20
    Cls
    Lcd "wymagana"
    Do
       Lowerline
       Lcd "temperatura: " ; A ; " "
       Call Zmiana(a , 20 , 91)
    Loop Until Dalej = 1
    Dalej = 0
    N_temperatura(nastawa) = A

    Goto Koniec

    Czas:
    Waitms 25
    Do
    Loop Until S_wybierz = 1                                    'czekamy na puszczenie "wybierz"

    Do
       Lowerline
       Lcd "godzina: " ; Godziny ; " "
       Call Zmiana(godziny , 0 , 24)
    Loop Until Dalej = 1
    Dalej = 0

    Cls
    Lcd "--PROGRAMOWANIE--"
    Do
       Waitms 25
    Loop Until S_wybierz = 1

    Do
       Lowerline
       Lcd "minuty: " ; Minuty ; " "
       Call Zmiana(minuty , 0 , 60)
    Loop Until Dalej = 1
    Dalej = 0

    Cls
    Lcd "--PROGRAMOWANIE--"
    Do
       Waitms 25
    Loop Until S_wybierz = 1

    Do
       Lowerline
       If Rok < 10 Then
          Lcd "rok: 200" ; Rok
       Else
          Lcd "rok: 20" ; Rok
       End If
       Call Zmiana(rok , 0 , 50)
    Loop Until Dalej = 1
    Dalej = 0

    Cls
    Lcd "--PROGRAMOWANIE--"
    Do
       Waitms 25
    Loop Until S_wybierz = 1

    Do
       Lowerline
       Lcd "miesiac: " ; Miesiac ; " "
       Call Zmiana(miesiac , 1 , 13)
    Loop Until Dalej = 1
    Dalej = 0

    Cls
    Lcd "--PROGRAMOWANIE--"
    Do
       Waitms 25
    Loop Until S_wybierz = 1

    Do
       Lowerline
       Lcd "dzien: " ; Dzien ; " "
       If Miesiac = 1 Or Miesiac = 3 Or Miesiac = 5 Or Miesiac = 7 Or Miesiac = 8 Or Miesiac = 10 Or Miesiac = 12 Then
          Call Zmiana(dzien , 1 , 32)
       Else
          Call Zmiana(dzien , 1 , 31)
       End If
    Loop Until Dalej = 1
    Dalej = 0

    Cls
    Lcd "--PROGRAMOWANIE--"
    Do
       Waitms 25
    Loop Until S_wybierz = 1

    Do
       Lowerline
       Lcd "dzien :" ; Nazwa_dnia(dzientygodnia) ; "    "
       Call Zmiana(dzientygodnia , 1 , 8)
    Loop Until Dalej = 1
    Dalej = 0

    Sekundy = 0
    Rtc_zapis

    Koniec:
    Return

    Sub Zmiana(zmienna As Byte , Byval Minimum As Integer , Byval Maximum As Byte)

       If S_wybierz = 0 Then
          Waitms 25
          If S_wybierz = 0 Then
             Dalej = 1
          End If
       End If

       If S_wiecej = 0 Then
          Waitms 25
          If S_wiecej = 0 Then
             Incr Zmienna
             If Zmienna = Maximum Then
                Zmienna = Minimum
             End If
             Waitms 200
          End If
       End If
       If S_mniej = 0 Then
          Waitms 25
          If S_mniej = 0 Then
             If Zmienna = Minimum Then
                Zmienna = Maximum
             End If
             Decr Zmienna
             Waitms 200
          End If
       End If

    End Sub
  • Moderator Projektowanie
    Prace nad projektem trwają nadal, póki co mam zrobione:

    - programowanie daty i godziny (jeszcze bez obliczania roku przestępnego, zwalilem to na RTC sprzetowy ;-) )

    - programowanie 99 nastaw czyli : dzien którego dotyczy nastawa, godzina i minuty, zadana temperatura 30-90 stopni (lub wyłaczenie). Program automatycznie sprawdza która nastawa jest kolejna

    - przegląd nastaw (program sprawdza ile zostało zaprogramowanych i wyswietla tylko ten zakres)

    - kasowanie wszystkich nastaw

    nastawy zapisywane sa w eeprom, tak wiec po zaniku zasilania i ponownym wlaczeniu wszystko ladnie pamieta, zegar podtrzymany bateria wiec rowniez odporny na brak zasilania.

    Aktualnie podchodzę do spraw końcowych, czyli czujnik temperatury (DS18s20 - tu nie spodziewam się problemów) oraz element wykonawczy.

    Mam tutaj pytanie do szanownego grona odnośnie tego ostatniego, mianowicie czy bojler (lub grzejnik) włączać przekaźnikiem czy triakiem ? Jakieś propozycje jednego lub drugiego elementu ?
    Dodam, że nie będzie to praca ciągła i szybko zmienna. Wiadomo że w takim powiedzmy 100l bojlerze temperatura wody ma dużą bezwładność, więc jeśli urządzenie co 5-10 minut zareaguje na zmianę to w zupełności wystarczy.