Menu Bascom


Witam Wszystkich Forumowiczów.

Układ składa się z wyświetlacza LCD, Atmega8, DS18B20, 3 x switch (S1, S2, S3).
Co chcę osiągnąć: po naciśnięciu przycisku S3 chciałbym wejść w menu gdzie ustawię sobie parametry temperatury za pomocą S1 i S2. Po ponownym naciśnięciu S3 wejdę do ustawiania parametrów innego menu gdzie sobie ustawienie temperaturę odpowiedzialną za coś innego. Po raz trzeci gdy nacisnę S3 wyjdę z ustawień.
Czytałem o komendach Select Case ale nie mogę rozgryźć jak to rozwiązać :(

Poniżej umieszczam swój obecny kod gdzie po naciśnięciu S3 wchodzę do dodatkowej pętli i tam ustawiam swoje parametry ale nie wiem jak dodać dodatkowe ustawienie.

Proszę o jakąś podpowiedź, przykład jak mogę to rozwiązać? Z góry dziękuję :)

'$sim
$regfile = "m8def.dat"
$crystal = 8000000
 
'*******************************************************************************
 
Config Lcd = 16 * 2
Config Lcdpin = Pin , Rs = Portc.5 , E = Portc.4 , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0
Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
 
'*******************************************************************************
 
Config Portb.1 = Input
Portb.1 = 1
Config Portb.2 = Input
Portb.2 = 1
Config Portb.3 = Input
Portb.3 = 1
Config Portb.4 = Output
Portb.4 = 0
Config Portb.5 = Output
Portb.5 = 0
Config Portd.6 = Output
Portd.6 = 1
Config 1wire = Portb.0
 
'*******************************************************************************
 
Dim Liczba As Single
Dim Eliczba As Eram Single At 2
Dim Buzz As Single
Dim Hist As Single
Dim Lsb As Byte
Dim Msb As Byte
Dim T As Single
Dim Tekst As String * 4
Dim Tmin As Single
 
Led Alias Portb.4
Przek Alias Portb.5
Buzzer Alias Portd.6
 
'*******************************************************************************
 
Buzz = 30
Hist = 5
 
 
Cls
Cursor Off
 
Lcd "   Termostat    "
Lowerline
Lcd "  do pieca C.O. "
Wait 2
 
Cls
 
Do
 
'****************** Program sterownika *****************************************
 
Tmin = Liczba - Hist
 
Readeeprom Liczba , Eliczba
 
If T > Liczba Then
             Przek = 1
                Led = 1
End If
 
 
If T < Tmin Then
            Przek = 0
               Led = 0
End If
 
 
If T > Buzz Then
            Buzzer = 0
End If
 
 
If T < Buzz Then
            Buzzer = 1
End If
 
 
If Pinb.3 = 0 Then
 
      Waitms 500
      Do
 
      Cls
      Locate 1 , 1
      Lcd "  GRANICA TEMP "
      Locate 2 , 1
      Lcd "USTAW: " ; Liczba ; Chr(0) ; "C"
      Waitms 100
 
      If Pinb.1 = 0 Then
               Incr Liczba
      End If
      Waitms 200
 
 
      If Pinb.2 = 0 Then
               Decr Liczba
      End If
 
 
      If Liczba > 80 Then Liczba = 80
      If Liczba < 20 Then Liczba = 20
 
If Pinb.3 = 0 Then
      Writeeeprom Liczba , Eliczba
      Waitms 100
      Exit Do
End If
 
      Loop
 
End If
 
 
'****************** Odczyt temperatury *****************************************
 
1wreset
 
   1wwrite &HCC
   1wwrite &H44
   Waitms 750
 
 1wreset
 
   1wwrite &HCC
   1wwrite &HBE
 
   Lsb = 1wread()
   Msb = 1wread()
 
'   T = Msb * 256
   T = Msb
   Shift T , Left , 8
   T = T + Lsb
  ' T = T / 16
   Shift T , Right , 4
 
 
   Tekst = Fusing(t , "#.#")
 
 
'*******************************************************************************
 
   Cls
   Locate 1 , 1
   Lcd "TEMP: " ; Tekst ; Chr(0) ; "C"
   Locate 2 , 1
   Lcd "NAST: " ; Liczba ; Chr(0) ; "C"
   Waitms 100
 
Loop
 
End




Portret użytkownika mirley

Re: Menu

trzeba sobie zrobić zmienną poz_ust, która będzie numerowała ustawienia. Jesli poz_ust =0 to exit do, natomiast kliknięcia S3 robią incr poz_ust, aż do momentu gdy skończą się ustawienia. Jeśli mamy 2 parametry do ustawienia to dajemy:

If Pinb.3 = 0 Then
  incr poz_ust
  if poz_ust = 3 then poz_ust = 0
End if
if poz_ust = 0 then
 'zapisywanie do eeprom
 Exit do
End if

W momencie pierwszego kliknięcia na S3 ustawiamy poz_ust = 1, a do menu ma wchodzić jesli poz_ust > 0

Dla przycisków S1 i S2 tworzy się instrukcje case:

Select case poz_ust
  case 1:
    incr liczba_1
  case 2: 
    incr liczba_2
end select

i powinno już działać. To wszystko jest tak ogólnie napisane, normalnie program powinien byc tak napisany aby nie było w nim ani jednej instrukcji waitms, wait itp. Od tego są timery

-

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 matrix

Re: Menu

To ja Ci pokażę ciekawy sposób na zagnieżdżanie menu w menu. Wyświetlanie podmenu jest zależne od tego czy pozycja wyżej została wybrana na tak czy na nie.

Zrób sobie wybór na select case i jak wkleisz ten mój kod to zobaczysz jakie można mieć fajnie złożone menu.
Nadmienię że jest to kawałek menu do sterownika bramy wjazdowej na full wypasie, który powoli piszę i projektuję.

Dim Czy_foto1 As Byte
Dim Fototest1 As Byte
 
 
Deflcdchar 0 , 32 , 4 , 2 , 31 , 2 , 4 , 32 , 32            'strzałka w prawo - 0
Deflcdchar 1 , 2 , 4 , 14 , 17 , 17 , 17 , 14 , 32          'litera ó - 1
Deflcdchar 2 , 32 , 8 , 10 , 12 , 8 , 25 , 6 , 32           'literka ł - 2
Deflcdchar 3 , 2 , 4 , 14 , 16 , 16 , 17 , 14 , 32          'literka ć - 3
Deflcdchar 4 , 32 , 2 , 4 , 14 , 16 , 14 , 1 , 30           'literka ś - 4
Deflcdchar 5 , 32 , 2 , 4 , 15 , 2 , 4 , 15 , 32            'literka ź - 5
Deflcdchar 6 , 32 , 2 , 4 , 22 , 25 , 17 , 17 , 32          'literka ń - 6
Deflcdchar 7 , 32 , 14 , 1 , 15 , 17 , 15 , 4 , 2           'literka ą - 7
 
Cursor Off Noblink
Cls
 
 
pozycja_menu = 1
 
Do
 
 '*** jeśli menu główne będzie miało tylko dwie pozycje to
 '*** zamiast poniższych dwóch warunków z instrukcjami INCR oraz DECR
 '*** można zastąpić jedną instrukcją
 '*** if w_gore = 0 or w_dol = 0 then toggle pozycja_menu
 
 if w_gore = 0 then                          'przycsik w górę (down)
   incr pozycja_menu
   waitms 100
 end if
 
 if w_dol = 0 then                           'przycisk w dół (up)
    decr pozycja_menu
    waitms 100
 end if
 
 if pozycja_menu > 2 then pozycja_menu = 2
 if pozycja_menu < 1 then pozycja_menu = 1
 
 select case pozycja_menu
       case 1:
          home
          lcd"Menu 1          "
          gosub menu_1
       case 2:
          home
          lcd"Menu 2          "
          gosub menu_2
 end select
loop
end
 
 
menu_1:
    'coś do robienia
return
 
menu_2:
  Gosub Wyswietl_tak_nie                          'skocz do podprogramu wyświetlania w dolnej linii napisu NIE     TAK
    Do
        If W_gore = 0 Or W_dol = 0 Then          'jeśli nacisnę w górę lub w dół to
            Toggle Czy_foto1                      'zmień wartość zmiennej na przeciwną czyli 0<=>255
            Waitms 200
        End If
 
        If Czy_foto1 = 0 Then                      'jeśli zmienna wyboru wł/wył foto1 = 0 czyli foto 1 wyłączone
           Gosub Wyswietl_strzalke_nie              'wyświetl strzałkę na pozycji 2,1 a na pozycji 2,10 puste pole
          Else
           Gosub Wyswietl_strzalke_tak              'w przeciwnym razie na pozycji 2,1 puste pole a na 2,10 strzałkę
        End If
 
        If Wykonaj = 0 And Czy_foto1 = 0 Then          'jeśli foto1 wyłączone i nacisnę przycisk OK to
           Locate 2 , 1                                 'znajduje pozycję 2,1
           Lcd "Foto 1 wy" ; Chr(2) ; ".     "         'wyświetla napis Foto 1 wył
           Fototest1 = 0                              'wyłącza fototest dla foto 1
           Exit Do                                     'i wychodzi każe opuścić pętlę
        End If
        If Wykonaj = 0 And Czy_foto1 = 255 Then            'jeśli nacisnąłem OK i fototest włączony
           Locate 2 , 1                                     'znajduję pozycję 2,1
           Lcd "Foto 1 w" ; Chr(2) ; ".     "               'wyświetlam Foto 1 wł.
           Exit Do                                          'każę wyjść z pętli
        End If
    Loop
    Gosub Czekacz                                           'podprogram zawiera waitms 800
    Gosub Czyszczenie_drugiej_linii                         'podprogram wpisuje 16 pustych znaków w drugiej linii
 
    If Czy_foto1 = 255 Then                                 'jeśli wcześniej włączone zostało foto 1 to
       Home
       Lcd "Fototest foto 1 "                               'wyświetl w pierwszej linii napis Fotottest foto 1
       Gosub Wyswietl_tak_nie                               'podprogram wyświetla w drugiej linii wyrazy NIE oraz TAK
         Do
           If W_gore = 0 Or W_dol = 0 Then                  'jeśli nacisnąłem przycisk UP lub DOWN to
              Toggle Fototest1                              'zmień wartość zmiennej fototest na przeciwny
              Waitms 200                                    'czekaj 200 ms
           End If
           If Fototest1 = 0 Then                            'jeśli wartość zmiennej fototest1 = 0 czyli fototest wyłączony
               Gosub Wyswietl_strzalke_nie                  'podprogram wywietla strzałkę na pozycji 2,1
              Else
               Gosub Wyswietl_strzalke_tak                  'w przeciwnym razie na pozycji 2,10
           End If
           If Wykonaj = 0 And Fototest1 = 0 Then            'jeśli nacisnięto OK i wybrano wyłączony fototest 1 to
              Locate 2 , 1
              Lcd "  Fototest wy" ; Chr(2) ; "  "           'wyświetl w dolnej linii że fototest 1 wyłączony
              Exit Do                                       'wyjdź z pętli
           End If
           If Wykonaj = 0 And Fototest1 = 255 Then          'jeśli naciśnięto OK i fototest włączony to
              Locate 2 , 1
              Lcd "  Fototest w" ; Chr(2) ; "   "           'wyświetl napis że włączony
              Exit Do                                       'wyjdż z pętli
           End If
         Loop
    End If
    Gosub Czekacz                                           'podprogram zawiera waitms 800
    Gosub Czyszczenie_drugiej_linii                         'podprogram wpisuje w drugiej linii 16 pustych znaków
Return
 
Wyswietl_tak_nie:
   Locate 2 , 1
   Lcd "  Nie      Tak  "
Return
 
Czyszczenie_drugiej_linii:
  'Waitms 800
  Locate 2 , 1
  Lcd "                "
Return
 
Wyswietl_strzalke_nie:
  Locate 2 , 1
  Lcd Chr(0)
  Locate 2 , 10
  Lcd " "
Return
 
Wyswietl_strzalke_tak:
  Locate 2 , 1
  Lcd " "
  Locate 2 , 10
  Lcd Chr(0)
Return
 
Czekacz:
  Waitms 800
Return

Portret użytkownika Chester

Menu

Dziękuję za odpowiedź ale mam pytanie dodatkowe:

Ten kawałek kodu umieszczam w pętli tak?

If Pinb.3 = 0 Then                       'jeżeli pinb.3 jest zero to
  incr poz_ust                           'dodaj 1 do "poz_ust"
  if poz_ust = 3 then poz_ust = 0        'jeżeli poz_ust jest 3 to tak jakby wychodzi z menu bo 
                                         'potrzebuję tylko 2 podmenu  
End if
if poz_ust = 0 then                      'jeżeli poz_ust znowu będzie 0 to wychodzi z menu jednocześnie 
                                         'zapisując ustawienia w eepprom 
 'zapisywanie do eeprom
 Exit do                                 'po co tutaj jest to "Exit do" ??
End if

Czy opcję select case mam wrzucić do pętli głównej?
Czy mogę to rozwiązać to w ten sposób jak przykład poniżej?

Select case
case 1:
If Pinb.1 = 0 Then
               Incr Liczba
      End If
      Waitms 200
 
 
      If Pinb.2 = 0 Then
               Decr Liczba
      End If
 
 
      If Liczba > 80 Then Liczba = 80
      If Liczba < 20 Then Liczba = 20
 
case 2:
If Pinb.1 = 0 Then
               Incr Buzz
      End If
      Waitms 200
 
 
      If Pinb.2 = 0 Then
               Decr Buzz
      End If
 
 
      If Buzz > 100 Then Buzz = 100
      If Buzz < 60 Then Buzz = 60
End select

Czy lepszym rozwiązaniem będzie:

Select case
  case 1: gosub temp 
  case 2: gosub buzz
End select
 
Temp:
If Pinb.1 = 0 Then
               Incr Liczba
      End If
      Waitms 200
 
 
      If Pinb.2 = 0 Then
               Decr Liczba
      End If
 
 
      If Liczba > 80 Then Liczba = 80
      If Liczba < 20 Then Liczba = 20
End sub
 
Buzz:
If Pinb.1 = 0 Then
               Incr Buzz
      End If
      Waitms 200
 
 
      If Pinb.2 = 0 Then
               Decr Buzz
      End If
 
 
      If Buzz > 100 Then Buzz = 100
      If Buzz < 60 Then Buzz = 60
End sub

Czy to menu działa jeszcze w inny trzeci sposób czyli w case 1 i 2 ustawiam że S1 to będzie dodawać 1 natomiast S2 będzie odejmować 1 a pozycje i wybór zmieniam w tej dodatkowej zmiennej poz_ust??

Z góry dziękuje za pomoc.

Kolego matrix dziękuje za kod jak rozgryzę dokładnie o co chodzi w tym select case to na pewno wykorzystam i Twoj pomysł :)

Pozdrawiam

Portret użytkownika matrix

Re: Menu

Nie wiem co chesz osiągnąć, ale pewnie masz jakiś cel pisząc to tak a nie inaczej.
Pisząc menu na select case działanie wygląda następująco:

1  do
2   if nacisniety_przycisk = 0 then incr pozycja_menu   'jeśli nacisniesz przycisk to zwiększ wartość zmiennej pozycja_menu
3   select case pozycja_menu
4         case 1:
5           'coś do wykonania
6         case 2:
7           'coś do wykonania
8         case 3:
9           'coś do wykonania
10   end select
11 loop
12 end

1 - początek pętli
2 - procesor sprawdza czy naciśnięto przycisk
3 - instrukcja sprawdza ile wynosi zmienna pozycja_menu
4 - jeśli zmienna pozycja_menu wynosi 1 to wykonane będzie to co w linii 5
5 - instrukcje do wykonania
6 - jeśli zmienna pozycja_menu wynosi 2 to wykonane będzie to co w linii 7
7 - instrukcje do wykonania
8 - jeśli zmienna pozycja_menu wynosi 3 to wykonane będzie to co w linii 9
9 - instrukcje do wykonania
10- koniec sprawdzania ile wynosi zmienna pozycja_menu
11- wróć na początek
12- koniec

Kolejno procesor sprawdza czy naciśnięto przycisk i przechodzi do następnej linii. Teraz instrukcja select case sprawdza ile wynosi zmienna pozycja_menu. Jeśli wynosi 1, 2 lub 3, lub też tyle ile wpisałeś w którejś linii select case to wykonuje to co jest umieszczone w danym select, linia po linii aż wykona wszystko i natrafi na następne case.

Portret użytkownika Chester

Menu

Napisałem taki programik i jest problem. Po naciśnięciu przycisku S3 wyświetlacz na zmianę pokazuję wszystko co się powinno wyświetlać w case 1 oraz podczas pracy termostatu.

'$sim
$regfile = "m8def.dat"
$crystal = 8000000
 
'*******************************************************************************
 
Config Lcd = 16 * 2
Config Lcdpin = Pin , Rs = Portc.5 , E = Portc.4 , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0
Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
 
'*******************************************************************************
 
Config Portb.1 = Input
Portb.1 = 1
Config Portb.2 = Input
Portb.2 = 1
Config Portb.3 = Input
Portb.3 = 1
Config Portb.4 = Output
Portb.4 = 0
Config Portb.5 = Output
Portb.5 = 0
Config Portd.6 = Output
Portd.6 = 1
Config 1wire = Portb.0
 
'*******************************************************************************
 
Dim Liczba As Single
Dim Eliczba As Eram Single At 2
Dim Buzz As Single
Dim Ebuzz As Eram Single At 8
Dim Hist As Single
Dim Lsb As Byte
Dim Msb As Byte
Dim T As Single
Dim Tekst As String * 4
Dim Tmin As Single
Dim Menu As Byte
 
Led Alias Portb.4
Przek Alias Portb.5
Buzzer Alias Portd.6
 
'*******************************************************************************
 
Hist = 5
 
 
Cls
Cursor Off
 
Lcd "   Termostat    "
Lowerline
Lcd "  do pieca C.O. "
Wait 2
 
Cls
 
Do
 
'****************** Program sterownika *****************************************
 
Tmin = Liczba - Hist
 
Readeeprom Liczba , Eliczba
Readeeprom Buzz , Ebuzz
 
If T > Liczba Then
             Przek = 1
                Led = 1
End If
 
 
If T < Tmin Then
            Przek = 0
               Led = 0
End If
 
 
If T > Buzz Then
            Buzzer = 0
End If
 
 
If T < Buzz Then
            Buzzer = 1
End If
 
 
If Pinb.3 = 0 Then
      Incr Menu
      If Menu = 3 Then Menu = 0
End If
 
      Waitms 200
 
   Select Case Menu
 
      Case 1:
 
         Cls
         Locate 1 , 1
         Lcd "  GRANICA TEMP "
         Locate 2 , 1
         Lcd "USTAW: " ; Liczba ; Chr(0) ; "C"
         Waitms 100
 
         If Pinb.1 = 0 Then
                  Incr Liczba
         End If
         Waitms 200
 
 
         If Pinb.2 = 0 Then
                  Decr Liczba
         End If
 
 
         If Liczba > 80 Then Liczba = 80
         If Liczba < 20 Then Liczba = 20
 
 
      Case 2:
 
         Cls
         Locate 1 , 1
         Lcd "     ALARM!     "
         Locate 2 , 1
         Lcd "USTAW: " ; Buzz ; Chr(0) ; "C"
         Waitms 100
 
         If Pinb.1 = 0 Then
                  Incr Buzz
         End If
         Waitms 200
 
 
         If Pinb.2 = 0 Then
                  Decr Buzz
         End If
 
 
         If Buzz > 100 Then Buzz = 100
         If Buzz < 60 Then Buzz = 60
 
   End Select
 
 
If Menu = 0 Then
      Writeeeprom Liczba , Eliczba
      Writeeeprom Buzz , Ebuzz
      Waitms 100
 
End If
 
 
'****************** Odczyt temperatury *****************************************
 
1wreset
 
   1wwrite &HCC
   1wwrite &H44
   Waitms 750
 
 1wreset
 
   1wwrite &HCC
   1wwrite &HBE
 
   Lsb = 1wread()
   Msb = 1wread()
 
'   T = Msb * 256
   T = Msb
   Shift T , Left , 8
   T = T + Lsb
  ' T = T / 16
   Shift T , Right , 4
 
 
   Tekst = Fusing(t , "#.#")
 
 
'*******************************************************************************
 
   Cls
   Locate 1 , 1
   Lcd "TEMP: " ; Tekst ; Chr(0) ; "C"
   Locate 2 , 1
   Lcd "NAST: " ; Liczba ; Chr(0) ; "C"
   Waitms 100
 
Loop
 
End

Co chciałem osiągnąć: po naciśnięciu przycisku S3 chce wejść w ustawienia temperatury granicznej. Po ponownym naciśnięciu S3 przechodzę do ustawień alarmu. Po kolejnym naciśnięciu S3 zapisuję ustawienia i wychodzę do normalnej pracy termostatu. Parametry zmieniam za pomocą S1 i S2.

Czy przy takim moim programie nie mam włączonego ciągłego zapisywania ustawień w procesorze?

Portret użytkownika matrix

Re: Menu

Za każdym razem kiedy zmienna menu przyjmuje wartość 0 to masz ciągłe zapisywanie do eepromu. Zmień ten kawałek:

         If Buzz > 100 Then Buzz = 100
         If Buzz < 60 Then Buzz = 60
 
   End Select
 
 
If Menu = 0 Then
      Writeeeprom Liczba , Eliczba
      Writeeeprom Buzz , Ebuzz
      Waitms 100
 
End If
 
 
'****************** Odczyt temperatury *****************************************
 
1wreset
 
   1wwrite &HCC
   1wwrite &H44
   Waitms 750

Na taki kawałek:

         If Buzz > 100 Then Buzz = 100
         If Buzz < 60 Then Buzz = 60
 
   End Select
 
 
If Menu = 0 Then
      Writeeeprom Liczba , Eliczba
      Writeeeprom Buzz , Ebuzz
      Menu = 1                                              'tutaj dodałem xzwiększenie menu do wartości 1
      Waitms 100
 
End If
 
 
'****************** Odczyt temperatury *****************************************
 
1wreset
 
   1wwrite &HCC
   1wwrite &H44
   Waitms 750

Wtedy gdy wartość menu zmieni się na 0 zapisze Ci ustawienia, zwiększy wartość menu do 1 i już będzie wykonywało się to co w select case pod wartością 1.

Taka drobna rada. Nie czyść za każdym razem wyświetlacza komendą cls, bo będziesz miał zauważalne migotanie wyświetlacza. Lepszym sposobem jest takie napisanie programu żeby tylko nadpisywać poszczególne partie lcd.

Portret użytkownika Chester

Menu

Dalej jest problem :( po włączeniu zasilania ekrany przeskakują pomiędzy tą częścią programu:

Case 1:
 
         Cls
         Locate 1 , 1
         Lcd "  GRANICA TEMP "
         Locate 2 , 1
         Lcd "USTAW: " ; Liczba ; Chr(0) ; "C"
         Waitms 100
 
         If Pinb.1 = 0 Then
                  Incr Liczba
         End If
         Waitms 200
 
 
         If Pinb.2 = 0 Then
                  Decr Liczba
         End If
 
 
         If Liczba > 80 Then Liczba = 80
         If Liczba < 20 Then Liczba = 20

a ta częścią programu:

 Cls
   Locate 1 , 1
   Lcd "TEMP: " ; Tekst ; Chr(0) ; "C"
   Locate 2 , 1
   Lcd "NAST: " ; Liczba ; Chr(0) ; "C"
   Waitms 100

dlaczego tak się dzieje? nie mogę nic ustawić , żadnych parametrów :( kurcze nie rozumiem tego select case :(

Portret użytkownika matrix

Pomyśl trochę. Dlatego że

Pomyśl trochę. Dlatego że to:

Cls
   Locate 1 , 1
   Lcd "TEMP: " ; Tekst ; Chr(0) ; "C"
   Locate 2 , 1
   Lcd "NAST: " ; Liczba ; Chr(0) ; "C"
   Waitms 100

masz poza wszelkim select case. W ogóle masz strasznie źle napisany ten program. Wysypie Ci się to.
Sam select case napisz tak:

Select Case Menu
 
 
      Case 1:
 
         Cls
         Locate 1 , 1
         Lcd "TEMP: " ; Tekst ; Chr(0) ; "C"
         Locate 2 , 1
         Lcd "NAST: " ; Liczba ; Chr(0) ; "C"
         Waitms 100
 
 
 
      Case 2:
 
         Cls
         Locate 1 , 1
         Lcd "  GRANICA TEMP "
         Locate 2 , 1
         Lcd "USTAW: " ; Liczba ; Chr(0) ; "C"
         Waitms 100
 
         If Pinb.1 = 0 Then
                  Incr Liczba
         End If
         Waitms 200
 
 
         If Pinb.2 = 0 Then
                  Decr Liczba
         End If
 
 
         If Liczba > 80 Then Liczba = 80
         If Liczba < 20 Then Liczba = 20
 
 
      Case 3:
 
         Cls
         Locate 1 , 1
         Lcd "     ALARM!     "
         Locate 2 , 1
         Lcd "USTAW: " ; Buzz ; Chr(0) ; "C"
         Waitms 100
 
         If Pinb.1 = 0 Then
                  Incr Buzz
         End If
         Waitms 200
 
 
         If Pinb.2 = 0 Then
                  Decr Buzz
         End If
 
 
         If Buzz > 100 Then Buzz = 100
         If Buzz < 60 Then Buzz = 60
 
   End Select

Portret użytkownika Chester

Menu

Zmieniłem swój program na taki:

'$sim
$regfile = "m8def.dat"
$crystal = 8000000
 
'*******************************************************************************
 
Config Lcd = 16 * 2
Config Lcdpin = Pin , Rs = Portd.0 , E = Portc.4 , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0
Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
 
'*******************************************************************************
 
Config Portb.1 = Input
Portb.1 = 1
Config Portb.2 = Input
Portb.2 = 1
Config Portb.3 = Input
Portb.3 = 1
Config Portb.4 = Output
Portb.4 = 0
Config Portb.5 = Output
Portb.5 = 0
Config Portd.6 = Output
Portd.6 = 1
Config 1wire = Portb.0
 
'*******************************************************************************
 
Dim Liczba As Single
Dim Eliczba As Eram Single At 2
Dim Buzz As Single
Dim Ebuzz As Eram Single At 8
Dim Hist As Single
Dim Lsb As Byte
Dim Msb As Byte
Dim T As Single
Dim Tekst As String * 4
Dim Tmin As Single
Dim Menu As Byte
 
Led Alias Portb.4
Przek Alias Portb.5
Buzzer Alias Portd.6
 
'*******************************************************************************
 
Hist = 5
Menu = 1
 
 
Cls
Cursor Off
 
Lcd "   Termostat    "
Lowerline
Lcd "  do pieca C.O. "
Wait 2
 
Cls
 
Do
 
'****************** Program sterownika *****************************************
 
Tmin = Liczba - Hist
 
Readeeprom Liczba , Eliczba
Readeeprom Buzz , Ebuzz
 
If T > Liczba Then
             Przek = 1
                Led = 1
End If
 
 
If T < Tmin Then
            Przek = 0
               Led = 0
End If
 
 
If T > Buzz Then
            Buzzer = 0
End If
 
 
If T < Buzz Then
            Buzzer = 1
End If
 
 
If Pinb.3 = 0 Then
      Incr Menu
      If Menu = 4 Then Menu = 0
      If Menu = 0 Then
      Writeeeprom Liczba , Eliczba
      Writeeeprom Buzz , Ebuzz
      Menu = 1
      Waitms 100
 
End If
 
 
End If
 
 
      Waitms 200
 
 
   Select Case Menu
 
 
      Case 1:
 
         Cls
         Locate 1 , 1
         Lcd "TEMP: " ; Tekst ; Chr(0) ; "C"
         Locate 2 , 1
         Lcd "NAST: " ; Liczba ; Chr(0) ; "C"
         Waitms 100
 
'****************** Odczyt temperatury *****************************************
 
1wreset
 
   1wwrite &HCC
   1wwrite &H44
   Waitms 750
 
 1wreset
 
   1wwrite &HCC
   1wwrite &HBE
 
   Lsb = 1wread()
   Msb = 1wread()
 
'   T = Msb * 256
   T = Msb
   Shift T , Left , 8
   T = T + Lsb
  ' T = T / 16
   Shift T , Right , 4
 
 
   Tekst = Fusing(t , "#.#")
 
 
      Case 2:
 
         Cls
         Locate 1 , 1
         Lcd "  GRANICA TEMP "
         Locate 2 , 1
         Lcd "USTAW: " ; Liczba ; Chr(0) ; "C"
         Waitms 100
 
         If Pinb.1 = 0 Then
                  Incr Liczba
         End If
         Waitms 200
 
 
         If Pinb.2 = 0 Then
                  Decr Liczba
         End If
 
 
         If Liczba > 80 Then Liczba = 80
         If Liczba < 20 Then Liczba = 20
 
 
      Case 3:
 
         Cls
         Locate 1 , 1
         Lcd "     ALARM!     "
         Locate 2 , 1
         Lcd "USTAW: " ; Buzz ; Chr(0) ; "C"
         Waitms 100
 
         If Pinb.1 = 0 Then
                  Incr Buzz
         End If
         Waitms 200
 
 
         If Pinb.2 = 0 Then
                  Decr Buzz
         End If
 
 
         If Buzz > 100 Then Buzz = 100
         If Buzz < 60 Then Buzz = 60
 
   End Select
 
 
'*******************************************************************************
 
Loop
 
End

Po włączeniu zasilania program wchodzi od razu do Case:1. Czy w tym case 1 muszę umieścić ten kawałek kodu?:

Tmin = Liczba - Hist
 
Readeeprom Liczba , Eliczba
Readeeprom Buzz , Ebuzz
 
If T > Liczba Then
             Przek = 1
                Led = 1
End If
 
 
If T < Tmin Then
            Przek = 0
               Led = 0
End If
 
 
If T > Buzz Then
            Buzzer = 0
End If
 
 
If T < Buzz Then
            Buzzer = 1
End If

Teraz menu wyświetla się w takiej kolejności jak chcę ale jest problem z ustawieniem parametrów ponieważ naciskając S1 i S2 nie zmienia się nic na wyświetlaczu temperatura cały czas jest 0'C. Jak to rozwiązać?

Portret użytkownika matrix

Re: Menu

Więc wywal ustawianie poza selct case.
Wszelkie ustawienia rób poza select case a tylko wyświetlanie tego co Cię interesuje w danym momencie zrób wewnątrz.

Portret użytkownika Chester

Menu

Spróbuję tak zrobić ale nie wiem czy to zadziała ponieważ musiałem wrzucić pomiar temperatury do case 1 bo nie wykonywało pomiarów cały czas była wyświetlana jedna temperatura nawet po podgrzaniu czujnika.

Kolego matrix to nic nie daje :( jak program może wiedzieć kiedy ustawiam zmienną Liczba albo Buzz jak wszystko jest w jednej pętli i sterowane tymi samymi przyciskami? Nie rozumiem tego :(

Portret użytkownika matrix

Najpierw pomyślunek

Żeby coś dobrze napisać to najpierw trzeba wszystko przemyśleć. Opracować jakiś konspekt, blokowy schemat działania całego programu.

Napisz to od nowa tylko zrób tak.

Zastanów się czy musisz pobierać temperaturę na bieżąco? Jeśli tak to czy kilkaset razy na sekundę czy wystarczy Ci raz na sekundę lub rzadziej?
Napisz to przerwanie a w nim odczyt temperatury.
Pętla do...loop ma zawierać obsługę klawiszy oraz select case gdzie będzie wyświetlane to co ma być wyświetlane.
Podziel cały program na małe podprogramy. Na przykład napisz podprogram zapisu danych do pamięci eeprom.

W tej chwili jak dla mnie to masz groch z kapustą.

Napisz dokładnie co i kiedy chcesz regulować. Napiszę Ci ogólny zarys co gdzie masz umieścić.

Portret użytkownika matrix

Re: Menu

do
   'umówmy się że przycisk w górę to up
   'przycisk w dół to down
   'a zatwierdź to ok
   'tu napisz co ma być wyświetlane ale nie używaj polecenia cls
   'napisz to na locate
 
   if ok = 0 then
      waitms 100
      gosub menu
   end if
 
loop
end
 
menu:
           'tu napisz co ma być wyświetlane w pierwszej pozycji menu
           'ale też to co będzie stałe na wyświetlaczu
 
           do
              'tu wpisujesz locate dana pozycja i zmienna do wyświetlenia
             if up = 0 then
                incr cos_tam   'zmienna którą chcesz zwiększać
                waitms 100
             end if
             if down = 0 then
                decr cos_tam   'zmienna którą chcesz zmniejszać
                waitms 100
             end if
             if ok = 0 then
                waitms 150
                exit do
             end if
           loop
 
           'tu napisz co ma być wyświetlane w drugiej pozycji menu
           'ale też to co będzie stałe na wyświetlaczu
           do
              'tu wpisujesz locate dana pozycja i zmienna do wyświetlenia
             if up = 0 then
                incr cos_tam   'zmienna którą chcesz zwiększać
                waitms 100
             end if
             if down = 0 then
                decr cos_tam   'zmienna którą chcesz zmniejszać
                waitms 100
             end if
             if ok = 0 then
                gosub zapis_danych
                waitms 150
                exit do
             end if
    loop
return
 
zapis_danych:
 
   'tu wpisz zapis danych do eepromu
 
return

Portret użytkownika Chester

Menu

Dziękuję za pomoc :) ciekawe rozwiązanie z tymi pętlami w podprogramie. Sporo programów które przeglądałem nie miało tam pętli dlatego nie wiedziałem że tak to można stosować :) kolejna lekcja programowania. Napisałem program według wskazówek i powstało takie coś:

'$sim
$regfile = "m8def.dat"
$crystal = 8000000
 
'*******************************************************************************
 
Config Lcd = 16 * 2
Config Lcdpin = Pin , Rs = Portc.5 , E = Portc.4 , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0
Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
 
'*******************************************************************************
 
Config Portb.1 = Input
Portb.1 = 1
Config Portb.2 = Input
Portb.2 = 1
Config Portb.3 = Input
Portb.3 = 1
Config Portb.4 = Output
Portb.4 = 0
Config Portb.5 = Output
Portb.5 = 0
Config Portd.6 = Output
Portd.6 = 1
Config 1wire = Portb.0
 
'*******************************************************************************
 
Dim Liczba As Single
Dim Eliczba As Eram Single At 2
Dim Buzz As Single
Dim Ebuzz As Eram Single At 8
Dim Hist As Single
Dim Lsb As Byte
Dim Msb As Byte
Dim T As Single
Dim Tekst As String * 4
Dim Tmin As Single
 
Led Alias Portb.4
Przek Alias Portb.5
Buzzer Alias Portd.6
 
Declare Sub Menu
Declare Sub Zapis
 
'*******************************************************************************
 
Hist = 5
 
 
Cls
Cursor Off
 
Lcd "   Termostat    "
Lowerline
Lcd "  do pieca C.O. "
Wait 2
 
Cls
 
Do
 
'****************** Program sterownika *****************************************
 
         Locate 1 , 1
         Lcd "TEMP: " ; Tekst ; Chr(0) ; "C"
         Locate 2 , 1
         Lcd "NAST: " ; Liczba ; Chr(0) ; "C"
         Waitms 100
 
Tmin = Liczba - Hist
 
Readeeprom Liczba , Eliczba
Readeeprom Buzz , Ebuzz
 
If T > Liczba Then
             Przek = 1
                Led = 1
End If
 
 
If T < Tmin Then
            Przek = 0
               Led = 0
End If
 
 
If T > Buzz Then
            Buzzer = 0
End If
 
 
If T < Buzz Then
            Buzzer = 1
End If
 
'****************** Odczyt temperatury *****************************************
 
1wreset
 
   1wwrite &HCC
   1wwrite &H44
   Waitms 750
 
 1wreset
 
   1wwrite &HCC
   1wwrite &HBE
 
   Lsb = 1wread()
   Msb = 1wread()
 
  'T = Msb * 256
   T = Msb
   Shift T , Left , 8
   T = T + Lsb
  'T = T / 16
   Shift T , Right , 4
 
   Tekst = Fusing(t , "#.#")
 
'*******************************************************************************
 
If Pinb.3 = 0 Then
      Waitms 200
      Gosub Menu
End If
 
Loop
 
End
 
'****************** Ustawienie MENU  *******************************************
 
Menu:
 
         Locate 1 , 1
         Lcd "  GRANICA TEMP "
         Locate 2 , 1
         Lcd "USTAW: " ; Liczba ; Chr(0) ; "C"
         Waitms 200
 
     Do
 
         Locate 2 , 1
         Lcd "USTAW: " ; Liczba ; Chr(0) ; "C"
 
     If Pinb.1 = 0 Then
         Incr Liczba
         Waitms 200
     End If
 
     If Pinb.2 = 0 Then
         Decr Liczba
         Waitms 200
     End If
 
     If Liczba > 80 Then Liczba = 80
     If Liczba < 20 Then Liczba = 20
 
     If Pinb.3 = 0 Then
          Waitms 200
          Exit Do
     End If
 
     Loop
 
 
         Locate 1 , 1
         Lcd "     ALARM!     "
         Locate 2 , 1
         Lcd "USTAW: " ; Buzz ; Chr(0) ; "C"
         Waitms 200
 
     Do
 
         Locate 2 , 1
         Lcd "USTAW: " ; Buzz ; Chr(0) ; "C"
 
     If Pinb.1 = 0 Then
         Incr Buzz
         Waitms 200
     End If
 
     If Pinb.2 = 0 Then
         Decr Buzz
         Waitms 200
     End If
 
     If Buzz > 100 Then Buzz = 100
     If Buzz < 30 Then Buzz = 30
 
 
     If Pinb.3 = 0 Then
          Gosub Zapis
          Waitms 200
          Exit Do
     End If
 
     Loop
 
Return
 
'****************** Zapis danych ***********************************************
 
Zapis:
 
     Writeeeprom Liczba , Eliczba
     Writeeeprom Buzz , Ebuzz
     Cls
Return
 
'*******************************************************************************

Problem jaki zauważyłem to że gdy chce nacisnąć S3 czyli "ok" muszę albo dłużej przytrzymać albo kilka razy nacisnąć nie zawsze wchodzi w podprogram :( Czy musze użyć funkcji "Debounce"?

Portret użytkownika matrix

Poeksperymentuj z długościami

Poeksperymentuj z długościami instrukcji wait. Ja zwykle ich nie stosuję jeśli mam gdzieś tam użyte timery. Jeśli nie mam timerów lub jeśli timery są aktualnie wyłączone to korzystam z wait do woli. Poza tym staram się unikać wait.

Jeśli użyjesz debounce to wait przy naciskaniu przycisków już nie będzie Ci potrzebne. I ostatnia moja uwaga odnośnie takiego fragmentu:

Locate 1 , 1
         Lcd "     ALARM!     "
         Locate 2 , 1
         Lcd "USTAW: " ; Buzz ; Chr(0) ; "C"
         Waitms 200
 
     Do
 
         Locate 2 , 1
         Lcd "USTAW: " ; Buzz ; Chr(0) ; "C"

Jeśli przed pętlą wyświetliłeś napis USTAW i jego ustawienia to nie wpisuj tego ponownie. Po to wpisujesz przed pętlą do...loop to co się nie zmienia żeby nie powtarzać tego w pętli i żeby niepotrzebnie nie odświeżać lcd.
Jeśli przed pętlą napisałeś:

Locate 1 , 1
         Lcd "     ALARM!     "
         Locate 2 , 1
         Lcd "USTAW:          "    'w tej linii masz dokladnie 16 znaków
         Waitms 200

To po wejściu do pętli nie powtarzaj tego tylko napisz:

Do
 
         Locate 2 , 8               'tu znajdujesz miejsce po słowie ustaw
         Lcd  Buzz ; Chr(0); "C"    'i wpisujesz to co uległo lub aktualnie ulega zmianie

W ten sposób nadpisujesz tylko te pola które trzeba zmienić a nie wszystkie.

Portret użytkownika Chester

Menu

Dzięki wielkie za pomoc i za wskazówki :) na pewno coś pokombinuję :)

Portret użytkownika gosc

rozklad liczby 16 bitowe na 8

Witam
Dzieki tej stronce udalo mi sie uruchomic pamiec.
Teraz mam inny problem.
Mam zmienna np 1030,chialbym ja zapisac do pamieci.
Oczywiscie nie zmiesci sie w jednem adresie, wiec musz eto rozbic na dwa.
Czy moge prosic i jakis przyklad, jak to wrzucic w pamiec i odzczywac, a potem skleic w jedno?

Mam problem z rozbiciem takiej liczby na dwie 8 bitowe i zapis juz jest prosty, ale odczyt i zlozenie ponowne..nie wiem jak.
Oczywiscie bascom.
Pozdrawiam

Portret użytkownika mirley

Re: zapis EEPROM


Do zapisu dzielisz liczbę na dwa bajty:

Dim Liczba as Word
Dim Lbyte as Byte
Dim Hbyte as Byte
 
Liczba=1030
 
Lbyte = Liczba 'zapisuje tylko młodszą część
Liczba=Liczba/256 'dzielenie lub przesuwanie w prawo o 8 bitów
Hbyte=Liczba
 
'zapis Lbyte i Hbyte

Do odczytu:

Masz odczytane Hbyte i Lbyte, zatem:

Liczba =256*Hbyte
Liczba=Liczba+Lbyte

-

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.