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

Bascom, przyciski-błąd w rozumowaniu

janbernat 12 Sty 2010 22:07 4359 33
  • #1 7526964
    janbernat
    Poziom 38  
    Zrobiłem taki programik:
    
    'Program do sterowania małych silników krokowych za pomocą ATMega8 i układu L6219 lub LB1845
    'sterowanie ćwierćrokowe, zasilanie 30V
    'set i reset zastosowałem w celach poglądowych- można- a nawet należy zastąpić to np.PortB=&B00001100 itp.
    
    $regfile "m8def.dat"
    $crystal = 4915200
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db7 = Portc.0 , Db6 = Portc.1 , Db5 = Portc.2 , Db4 = Portc.3 , E = Portc.4 , Rs = Portc.5
    Ddrb = &HFF
    sei
    
    Config Timer0 = Timer , Prescale = 8       ' teraz da ok. 0.417us- ale może skrócić
    Enable Ovf0
    On Ovf0 Step_delay
    Config Pind.2 = Input
    Set Portd.2
    Config Pind.4 = Output
    Dim Kier As Byte
    Dim Temp0 As Byte
    Dim Opoznienie_odczytu As Byte
    
    
    Ph1 Alias Portb.0   'kierunek przepływu prądu w uzwojeniu Ph1
    Ph2 Alias Portb.1   'kierunek przepływu prądu w uzwojeniu Ph2
    I01 Alias Portb.2   'napięcie dostarczane do uzwojeń- 1 , 2/3 lub 1/3 Imax
    I11 Alias Portb.3
    I02 Alias Portb.4
    I12 Alias Portb.5
    
    Set I01             ' na początek ustawiamy mały prąd
    Set I11
    Set I02
    Set I12
    
    Dim Next_step As Byte
    Next_step = 0
    Dim Flaga As Byte
    Flaga = 0
    'Dim Liczba_krokow As Byte    'to może służyć do zaprogramowania rampy- później
    'Liczba_krokow = 0
    Kier = 0
    Cls
    Cursor Off
    Locate 1 , 1
    Lcd "ustal kierunek "
    
    
    
    Do
    
       If Flaga = 1 Then       'gdy jest przerwanie od Timer0- co 237us
         If Pind.2 = 0 Then       'i jest wciśnięty przycisk PIND.2
             Incr Opoznienie_odczytu       'no bo przycisk ma drgania dłużej niż 237us- niech zwiększy
                                            'to sprawdzanie powtórne do 17ms
    
             If Opoznienie_odczytu >= 70 Then       'dajmy mu na wygaszenie drgań 17ms
    
                If Temp0 = 0 Then       ' i jest zezwolenie na zmianę stanu
                   Gosub Ustawianie
                   Temp0 = 1       ' zablokuj zezwolenie na zmianę stanu
                End If
    
                Opoznienie_odczytu = 0       'Jak już ustawił kierunek to pozwolimy mu liczyć od początku-
                                              'po powtórnym naciśnięciu PIND.2
              End If
    
          Else
             Temp0 = 0  'zezwalaj na zmiany
          End If
    
          If Kier = 1 Then
             Gosub Kier_prawo
          End If
    
          If Kier = 2 Or Kier = 0 Then
             Gosub Kier_stop
          End If
    
          If Kier = 3 Then
             Gosub Kier_lewo
          End If
    
          Flaga = 0
          Toggle Portd.4       'to jest tylko do pomiaru
    
       End If
    
    Loop
    End
    
    
    Step_delay:
       Timer0 = 110     'no to skracamy- ten silnik się jeszcze kręci- ale na jakimś innym moze to trzeba zmienić
                         'tu jest ok.237us obliczone a 248us zmierzone- procesor jednak coś wolno liczy
       Flaga = 1
          Incr Next_step
             If Next_step >= 16 Then
                Next_step = 0
          End If
    
    Return
    
    
    Ustawianie:
    
          Select Case Kier
             Case 0
               Locate 1 , 1
               Lcd "kierunek- lewo " ; Kier
             Case 1
               Locate 1 , 1
               Lcd "kierunek- stop " ; Kier
             Case 2
               Locate 1 , 1
               Lcd "kierunek- praw " ; Kier
             Case 3
               Locate 1 , 1
               Lcd "kierunek- stop " ; Kier
    
           End Select
    
        Incr Kier
         If Kier >= 4 Then
           Kier = 0
         End If
    
    Return
    
    
    Kier_prawo:
       'Incr Liczba_krokow
    
        Select Case Next_step
    
             Case 0
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Set I02
             Case 1
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
             Case 2
                Reset Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
             Case 3
                Reset Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 4
                Set Ph1 : Set I11 : Set I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 5
                Set Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 6
                Set Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
             Case 7
                Set Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
             Case 8
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Set I02
             Case 9
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
             Case 10
                Set Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
             Case 11
                Set Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
             Case 12
                Reset Ph1 : Set I11 : Set I01 : Set Ph2 : Reset I12 : Reset I02
             Case 13
                Reset Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
             Case 14
                Reset Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
             Case 15
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
    
    
          End Select
    
    Return
    
    Kier_lewo:
      'Incr Liczba_krokow
    
          Select Case Next_step
    
             Case 0
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Set I02
             Case 1
                Reset Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
             Case 2
                Reset Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
             Case 3
                Reset Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
             Case 4
                Set Ph1 : Set I11 : Set I01 : Set Ph2 : Reset I12 : Reset I02
             Case 5
                Set Ph1 : Set I11 : Reset I01 : Set Ph2 : Reset I12 : Reset I02
             Case 6
                Set Ph1 : Reset I11 : Set I01 : Set Ph2 : Reset I12 : Set I02
             Case 7
                Set Ph1 : Reset I11 : Reset I01 : Set Ph2 : Set I12 : Reset I02
             Case 8
                Set Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Set I02
             Case 9
                Set Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
             Case 10
                Set Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
             Case 11
                Set Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 12
                Reset Ph1 : Set I11 : Set I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 13
                Reset Ph1 : Set I11 : Reset I01 : Reset Ph2 : Reset I12 : Reset I02
             Case 14
                Reset Ph1 : Reset I11 : Set I01 : Reset Ph2 : Reset I12 : Set I02
             Case 15
                Reset Ph1 : Reset I11 : Reset I01 : Reset Ph2 : Set I12 : Reset I02
    
    
          End Select
    
    Return
    
    Kier_stop:          'stop ma zachować aktualne położenie wirnika
    
    Return
    

    No i w zasadzie działa.
    Ale przycisk działa nie zawsze pewnie- czasem trzeba dwa razy nacisnąć a czasem przeskakuje.
    Podejrzewam że coś sknociłem- ale nie wiem co.
    Może ktoś znajdzie?
  • Pomocny post
    #2 7527084
    Konto nie istnieje
    Poziom 1  
  • #3 7527319
    janbernat
    Poziom 38  
    No dobrze- działa dużo lepiej- może nawet zupełnie dobrze.
    Przycisk już chyba zrównałem z płytką.
    Ale gdzie był mój błąd w rozumowaniu?
  • Pomocny post
    #4 7527362
    Konto nie istnieje
    Poziom 1  
  • #5 7527410
    janbernat
    Poziom 38  
    No tak podejrzewałem- co będzie jak przycisk puszczę wcześniej.
    Jak dawałem np. Opoznienie_odczytu =20 to było pewniej.
    Ale powiedz mi czy Twoje rozwiązanie jest "łataniem" moich pomysłów czy należy to zrobić inaczej?
  • Pomocny post
    #6 7527445
    Konto nie istnieje
    Poziom 1  
  • #7 7528070
    marco47
    Poziom 41  
    Kolego janbernat

    Kod wykrywający naciśnięcie przycisku
    If Pind.2 = 0 Then                              'jeśli przyciśnięty switch_0
     M1 = 1                                           'ustaw bit pomocniczy
      If M1 = 1 And M2 = 0 Then                       'jeśli nadal wciśnięty
          '  COŚ DO ZROBIENIA .......
    
                If Temp0 = 0 Then       ' i jest zezwolenie na zmianę stanu
                   Gosub Ustawianie
                   Temp0 = 1       ' zablokuj zezwolenie na zmianę stanu
                End If 
    
              M2 = 1                                  'zablokuj dalsze zmiany do czasu 
                                                      'zwolnienia switch_0
           Else
            M1 = 0 : M2 = 0                  'kasuj bity pomocnicze
         End If
       End If
  • #8 7528581
    Konto nie istnieje
    Poziom 1  
  • #9 7530695
    marco47
    Poziom 41  
    Czy ty napewno zrozumiałeś ten kod ,bo chyba żle rozumujesz .
    Przecież napisałem
    ' COŚ DO ZROBIENIA .......
    A wkleiłem część twojego kodu byś zobaczył że w tym miejscu możesz robić co chcesz .
    To w takim razie czysty kod wykrywania naciśniętego przycisku przy naciskaniu .

    If Pind.2 = 0 Then                              'jeśli przyciśnięty switch_0
     M1 = 1                                           'ustaw bit pomocniczy
      If M1 = 1 And M2 = 0 Then                       'jeśli nadal wciśnięty
          '  COŚ DO ZROBIENIA .......
    
              M2 = 1                                  'zablokuj dalsze zmiany do czasu
                                                      'zwolnienia switch_0
           Else
            M1 = 0 : M2 = 0                  'kasuj bity pomocnicze
         End If
       End If


    Wystarczy zmienić kolejność zmiennych by zadziałał na puszczenie przycisku
  • #10 7530881
    Konto nie istnieje
    Poziom 1  
  • #12 7531122
    Konto nie istnieje
    Poziom 1  
  • #13 7531340
    marco47
    Poziom 41  
    W moich programach ten typ kodu działa , tylko przyciski mam podłączone do jednej lini ADC (klawiatura rezystorowa). Mniejsza ilość połączeń i teoretycznie można podłączyć do 1023 przycisków.
  • #14 7531462
    Konto nie istnieje
    Poziom 1  
  • #15 7531544
    marco47
    Poziom 41  
    Napisałem że teoretycznie 1023 , w rzeczywistości testowałem z dobrym skutkiem do 100 przycisków a używam max 20 . Rezystory nie muszą być dobrane dokładnie takie jak wychodzą z wyliczeń . Różnicę ustawiam programowo.
  • #16 7531669
    Konto nie istnieje
    Poziom 1  
  • #17 7531781
    marco47
    Poziom 41  
    Nie stosuję w programach naciskania dwóch (lub więcej) przycisków naraz . Jeżeli występuje taka konieczność (bezpieczeństwo użytkownika) to przydzielam drugą linię ADC lub zwykłe wejście procka .
  • #18 7531812
    Konto nie istnieje
    Poziom 1  
  • #19 7531839
    janbernat
    Poziom 38  
    Cały czas są to wariacje na temat przerzutnika T.
    To co podał marco47- to jest prawie tak jak z książki P. Góreckiego- kod C009e do ściągnięcia ze strony EdW.
    Z tym że jest tam waitms5 a ten fragment jest wykonywany co 4 przejścia- czyli co 20ms.
    I tylko wtedy to może działać- a marco47 nic o tym nie wspomina.
    Ja też zacząłem od programowego przerzutnika (i z tej samej książki)- ale w moim wypadku cykl jest określony przez częstotliwość impulsów sterujących silnikiem- dla tego silnika jest 237us a dla innego może być inny.
    Dlatego wprowadziłem "Opoznienie_odczytu" aby móc inkrementować to do 15-30ms- bo wtedy powtórne sprawdzanie stanu pinu dopiero ma sens.
    Poprawka podana przez atom1477 sprawia że przycisk chodzi tak że nie jestem w stanie go "oszukać"- może za wolne mam palce.
    Atom napisał: "Jest to łatanie, ale już powinno działać."
    No i działa- dzięki wielkie.
    Ale nie wiem czy jest to optymalne.
    Jak będę miał "moce przerobowe" to spróbuję zrobić to w kilku wersjach.
    P.S.
    Zwłaszcza że ten L6219 i ten przycisk jest zrobiony "przy okazji" nieco innego projektu z którym dopiero się namęczę.
    A ten program może mi oszczędzi pytań "dlaczego silnik krokowy się nie kręci"
  • Pomocny post
    #20 7531895
    Konto nie istnieje
    Poziom 1  
  • #21 7531937
    janbernat
    Poziom 38  
    Apage Satanas!!!
    A jak wsadzę pustą pętlę to jak silnik (w zasadzie L6219) ma dostawać impulsy co 237us?
  • #22 7532157
    marco47
    Poziom 41  
    Sprawdzałem w realu że naciśnięcie dwóch lub więcej przycisków w moim programie wykona tylko kod przycisku naciśniętego jako pierwszy, a reszta jest blokowana do czasu puszczenia tego przycisku . Więc nie ma możliwości wykonania złego kodu (działania).
    Mała część kodu dla przycisku dwu funkcyjnego
    Naciśnięcie wykonuje włącz/wyłącz urządzenia a przytrzymanie przejście do innego menu
    '*********************  Globalny licznik opóznienia  ******************         0.014ms
      If Przycisk < 10 Then Incr Licz_opoznienie      'zwiększ licznik opóznienia
           If Licz_opoznienie > 400 Then Licz_opoznienie = 0       'ustaw licznik opóznienia
    
    
    '***********************  Przyciski ON_OFF  ************************************
    '-----------------  Wyłącznik Zasilacza +35V / Generator   ---------------------
    
    If Przycisk = 7 Then                              'jeśli przyciśnięty switch_7
      M1 = 1                                          'ustaw bit pomocniczy
       If M1 = 1 And M2 = 0 And Licz_opoznienie = 0 Then       'jeśli wystąpi warunek
          Toggle Menu_1                               'zmień bit kolejności menu
           If Menu_1 = 0 Then Menu = 0                'przypisanie kolejności do menu Zsilacz
            If Menu_1 = 1 Then Menu = 1               'przypisanie kolejności do menu Generator
              Menu_2 = 1
               M2 = 1                                 'zablokuj dalsze zmiany do czasu zwolnienia switch_7
           End If
       Else
         If M1 = 1 And M2 = 0 Then                    'jeśli wciśnięty
          If Menu = 0 Then Toggle Portb.4             'zmień stan wyjścia na przeciwny
           M1 = 0                                     'zeruj bit pomocniczy
       End If
    End If
    ..........
    ..........
    ..........
    '-------------------------------------------------------------------------------
    If Przycisk = 10 Then                             'jeśli nie naciśnięto przycisku
       Licz_opoznienie = 0                            'zerowanie globalnego licznika opóznienia
        M1 = 0 : M2 = 0                               'zeruj bity pomocnicze
         N1 = 0 : N2 = 0                              'zeruj bity pomocnicze
          L1 = 0 : L2 = 0                             'zeruj bity pomocniczy
    
           If Lut_ustaw = 1 Then Incr Licznik_ustaw   'jesli ustawiano temperaturę zwiększ licznik
            If Licznik_ustaw > 4000 Then              'po 5 sekundach
             Licznik_ustaw = 0                        'zeruj licznik
              Lut_ustaw = 0                           'przełącz na wyświetlanie temp. mierzonej
           End If
    '---------------------   Przycisk akustyczny   ---------------------------------
           Else
            N1 = 1                                    'ustaw bit pomocniczy
             If N1 = 1 And N2 = 0 Then                'jeśli nadal wciśnięty
              Toggle Portb.6                          'włącz sygnał przycisków
               Incr Sygnal                            'zwiększ licznik jasności wyświetlaczy
                 If Sygnal = 30 Then
                   Sygnal = 0                         'jezeli licznik 4 to zeruj
                    Portb.6 = 0                       'wyłącz sygnał  przycisków
                     N2 = 1                           'zablokuj dalsze zmiany do czasu zwolnienia przycisku
        End If
       End If
      End If
  • #23 7532251
    Konto nie istnieje
    Poziom 1  
  • #24 7532323
    marco47
    Poziom 41  
    Typowy schemat jak u Ciebie . Wyżej odpowiedziałem dlaczego nie ma złego działania przycisków.
  • #25 7532369
    Konto nie istnieje
    Poziom 1  
  • #26 7532438
    marco47
    Poziom 41  
    To są Twoje dywagacje teoretyczne . Jeżeli pętla programu śmiga np.1000 razy na sekundę to jak naciśnięcie dwóch przycisków spowoduje błąd . Zawsze któryś wykrywany jest jako pierwszy.
  • #27 7532456
    Konto nie istnieje
    Poziom 1  
  • #28 7532546
    marco47
    Poziom 41  
    Podałem przykład teoretyczny z szybkością pętli.
    Przecież wartości możesz wyliczyć Sam . Przycisków jest np. 10 a zakres ADC 1023 . Wartości rezystancji z dowolnego szeregu , jednak lepiej z małych wartości rezystancji .
  • #29 7532596
    Konto nie istnieje
    Poziom 1  
  • #30 7532624
    marco47
    Poziom 41  
    Dalej nie rozumiem co chcesz udowodnić . Przecież napisałem że program działa bez zakłóceń mimo naciskania dwóch lub więcej przycisków . Zawsze wykona kod pierwszego przycisku którego wykryje.
    Zresztą cały czas testuję na bieżąco na testerku

    Bascom, przyciski-błąd w rozumowaniu
REKLAMA