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

[atmega8][bascom]Problem z obsługą impulsatora

morswin89 09 Lut 2010 15:03 4703 9
  • #1 09 Lut 2010 15:03
    morswin89
    Poziom 23  

    Kod pochodzi z EP 4/2005
    Problem polega na zmianie wyświetlanej wartości tylko z 1 na 2 przy kręceniu w jedną stronę.


    Code:
    $regfile = "m8def.dat"
    
    $crystal = 16000000

    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 Portd = Input
    Dim Licz As Byte
    Dim Stan_enk As Byte
    S Alias Pind.0
    Portd = 255

    Cursor Off

    Cls

    Lcd "Wartosc: " ; Licz
    Lowerline
    Lcd "przycisk : OFF"

    Do
    Debounce S , 0 , Obs_s , Sub
    Stan_enk = Encoder(pind.1 , Pind.2 , Lewo , Prawo , 0)
    Waitms 100
    Loop
    End

    Lewo:
    Decr Licz
    Locate 1 , 10
    Lcd Licz
    Lcd " "
    Return

    Prawo:
    Incr Licz
    Locate 1 , 10
    Lcd Licz
    Lcd " "
    Return

    Obs_s:
    Locate 2 , 11
    Lcd " ON "
    Bitwait S , Set
    Locate 2 , 11
    Lcd " OFF"
    Return

    0 9
  • #2 09 Lut 2010 16:58
    Paweł Es.
    Pomocny dla użytkowników

    Dodaj warunki po inkrementacji i dekrementacji

    Przy zwiększaniu

    Code:
    IF LICZ > 2 THEN Licz=2


    Przy zmniejszaniu

    Code:
    IF LICZ < 1 THEN Licz=1


    Tylko zmienna licz nie będzie typu integer, by nie było problemów przy sprawdzaniu warunku jeżeli Licz przypadkiem zejdzie poniżej zera.

    0
  • #3 09 Lut 2010 18:28
    morswin89
    Poziom 23  

    Chyba się źle zrozumieliśmy teraz mam tak, że nie mogę ustawić innej wartości jak 1 i 2 a powinno się zmieniać od 0 do 255 bo taki jest zakres zmiennej bitowej.

    0
  • #5 10 Lut 2010 17:04
    Paweł Es.
    Pomocny dla użytkowników

    Problemem przy programowej obsłudze koderów przyrostowych jest to, że układ działa poprawnie jeżeli program przechwytuje kolejne (wszystkie) stany kodera. Jeżeli program krąży w pętli to działa asynchronicznie w stosunku do zmian wejść i dekoder głupieje, bo dostaje niepoprawne następstwa stanów i jeżeli obsługuje je w sposób uproszczony to efekt jest zupełnie przypadkowy. Dodatkowy problem to drgania styków kodera przy zmianach stanów danego styku. Zamiast jednokrotnego przejścia w danej części cyklu zmian mamy przypadkowy ciąg impulsów na danym kanale kodera.

    Jeżeli zastosujemy obsługę w przerwaniach to teoretycznie jesteśmy w stanie wyłapać wszystkie zmiany na stykach kodera choć też trzeba zastosować pewne zabiegi filtracyjne by wyeliminować fałszywe sekwencje stanów.

    Można też zastosować pewne rozwiązania układowe pomiędzy koderem a m-psorem upraszczające dekodowanie programowe ruchów kodera.

    [atmega8][bascom]Problem z obsługą impulsatora

    Działanie układu pokazują poniższe przebiegi:

    [atmega8][bascom]Problem z obsługą impulsatora

    Przebieg A jest generowany przez S1, a przebieg B przez S2. Czarne strzałki oznaczają chwile próbkowania stanu styku S2 a czerwone to zgłaszane przerwania.

    Na narastającym zboczu S1 zapisywany jest stan styku S2. Jeżeli kręcimy w prawo to przy narastającym zboczu A na wejściu B jest stan wysoki co zostaje zapisane w przerzutniku kierunku. Na opadającym zboczu S1 zgłaszane jest przerwanie do procesora, który odczytuje stan przerzutnika kierunku i odpowiednio zwiększa lub zmniejsza odpowiednią zmienną. Należy pamiętać by po zgłoszeniu przerwania zablokować je na np. 15 ms aby uniknąć wielokrotnych przerwań związanych z odbiciami na stykach. Można też zastosować filtrację analogową pomiędzy stykiem S1 i wejściem INT0 procesora (można np. wykorzystać drugi przerzutnik układu 4013 jako układ monostabilny, tak jak to pokazano na schemacie, jeżeli wykorzystamy ten układ to przerwania zgłaszamy na narastającym zboczu sygnału IMPULSY (zielona końcówka).

    Jeżeli kręcimy w lewo to przy narastającym zboczu A na wejściu B jest stan niski co zostaje zapisane w przerzutniku kierunku. Na opadającym zboczu S1 zgłaszane jest przerwanie do procesora, który odczytuje stan przerzutnika kierunku i odpowiednio zwiększa lub zmniejsza odpowiednią zmienną.

    0
  • #7 26 Sie 2010 00:14
    Pit91
    Poziom 9  

    Witam,

    Nie chciałem zaczynać nowego tematu o impulsatorze, więc się podpinam;)
    więc potrzebuję program do obsługi impulsatora, musi zliczać szybko impulsy, oraz działać poprawnie prawo(dodać impulsy)-lewo(odjąć impulsy).
    Po przeszukaniu wszystkiego co możliwe, po przestudiowaniu wszystkich programów dowiedziałem się że najszybciej działa na przerwaniach.
    W Bascomie już troche pisze, jednak jeszcze nie jest najlepiej z moimi programami.
    Czy mógłby mi ktoś pomóc znaleźć błąd w programie? Lub naprowadzić jak to naprawić?
    Jak kręcę impulsatorem w prawo, poprawnie odejmuje, jednak przy kręceniu w lewo też odejmuje. Po próbach ze zamianą miejscami INT0 i INT1, wyszło na to że INT1 nie odczytuje poprawie sygnału z impulsatora. Nie mam już pomysłu co może być powodem.
    Oto mój program:

    Code:


    '******* procek *******
    $regfile = "m8def.dat"
    $crystal = 8000000

    '******* lcd *******

    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

    '****Konfiguracja portów****
    Config Pind.2 = Input
    Config Pind.3 = Input
    Set Portd.2
    Set Portd.3

    '****Konfigurowanie INTx ****
    Config Int1 = Falling
    Config Int0 = Falling
       On Int0 Lewo
       On Int1 Prawo
       Enable Int0
       Enable Int1
    Enable Interrupts


    '****Konfiguracja zmiennych****
    Dim E As Byte
    Dim Flagal As Bit
    Dim Flagap As Bit
    E = 99
    Flagal = 0
    Flagap = 0

    '****Obsługa wyświetlacza****

    Wys:
    Cls
    Locate 1 , 1
    Lcd E
    Return


    '****Program zliczający impulsy enkodera****

    Lewo:
    Disable Int1
    Disable Int0
    Do

    If Pind.2 = 1 And Pind.3 = 0 Then
       Do
       If Pind.2 = 0 Then
          Exit Do
       End If
       Loop

       Do
       If Pind.3 = 1 And Pind.2 = 1 Then
          Exit Do
       End If
       Loop
       Gosub Wys
       Decr E
       Flagal = 1
       Gosub Wys
       If E = 0 Then
          E = 98
       End If

    End If
       If Flagal = 1 Then
          Exit Do
       End If
    Loop
    Flagal = 0
    Enable Int1
    Enable Int0
    Return

    Prawo:
    Disable Int0
    Disable Int1
    Do

    If Pind.2 = 0 And Pind.3 = 1 Then
       Do
       If Pind.3 = 0 Then
          Exit Do
       End If
       Loop

       Do
       If Pind.3 = 1 And Pind.2 = 1 Then
          Exit Do
       End If
       Loop
       Gosub Wys
       Incr E
       Flagap = 1
       Gosub Wys
       If E = 99 Then
          E = 1
       End If

    End If
       If Flagap = 1 Then
          Exit Do
       End If

    Loop
    Flagap = 0
    Enable Int0
    Enable Int1

    Return


    Wiele rozwiązań próbowałem, jednak wszystkie zawiodły. Jest to najszybciej działająca wersja programu, jednak z tym błędnym odliczaniem impulsów.

    Proszę o pomoc.
    Pozdrawiam;)

    0
  • #8 22 Lut 2014 23:25
    gaspaccio
    Poziom 16  

    Przepraszam że odkrywam wykopaliska, ale postanowiłem przetestować układ zaproponowany przez kolegę Paweł Es.. Idea jest słuszna, ale się nie sprawdza. Do testu wykorzystałem impulsator z myszki i klon analizatora USBee. Jak się okazało impulsator jest tak słabej jakości że wprowadza ogromne drgania styków, dwa górne przebiegi pokazuję co dzieje się na stykach, w rezultacie zarówno przerzutnik działający jako wykrycie kierunku jak i ten w układzie monostabilnym wyzwalają się nie tylko przy zboczach narastających ale również „opadających”. Pierwszy taki przypadek jest zaznaczony kółeczkiem, niby zbocze opadające a wyzwolenie nasąpiło.

    Przebiegi od góry to: A, B, kierunek, impulsy.

    Sytuację diametralnie poprawia dodanie kondensatorów równolegle do przycisków, ale mimo to od czasu do czasu, na clock trafia fałszywe zbocze narastające.
    [atmega8][bascom]Problem z obsługą impulsatora

    0
  • #9 24 Lut 2014 14:24
    Paweł Es.
    Pomocny dla użytkowników

    On się nie wyzwala na zboczu opadającym tylko tam jest jeszcze impuls, tyle, że bardzo wąski i ten analizator go nie "zobaczył"

    11111101000000

    Z własnych późniejszych prac a raczej "mąk" z obsługą koderów przyrostowych, to pomagało dodanie prostych układów RC na stykach co radykalnie wycinało te śmiecie impulsowe przy przełączeniach:


    [atmega8][bascom]Problem z obsługą impulsatora



    Edytuj

    Inwertery na schemacie muszą być z wejście Schmitta (np. 40106, ewentualnie 4093 (Nand-y z wejściem Schmitta).

    Kondensatory C1 i C2 trzeba dobrać do konkretnego typu kodera.
    Z wyjść inwerterów można popędzić ten układ co podałem wcześniej, który powinien teraz być odporniejszy.

    0
  • #10 27 Lut 2014 21:55
    gaspaccio
    Poziom 16  

    Witam, analizator zobaczył tylko ja specjalnie to zwęziłem żeby było widać zarys całego przebiegu,.
    Teraz tez już wiem, że pomysł stosowania przerzutnika D jest raczej bezcelowy. Bo i tak w programie trzeba sprawdzać stan na pinie kierunku.
    Oczywiście najlepszym rozwiązaniem jest zastosowanie bramek z histerezą. Jest jednak jeszcze druga kwestia, a mianowicie jak chcemy dekodować impulsy, co dwa skoki czy co jeden. Jeżeli co dwa to wystarczy 1 timer. Jeżeli co jeden skok to albo procesor który ma przerwanie z możliwości wyzwalania dwoma zboczami, albo wykorzystać dwa przerwania. Jedno wyzwalać zboczem opadającym a drugie rosnącym.
    Zrobiłem to jeszcze inaczej. Ponieważ i tak używany jakiegoś dodatkowego układu, dodałem na wejście XOR na bramkach NAND z wejściem Schmitta po to żeby znaleźć oba zbocza i wyzwalać tym impulsem przerwanie bez żadnych śmieci. Wynik jest zadowalający, enkoder nie gubi się i liczy oczywiście co krok (próbowałem do około 100 impulsów na sekundę, kilka impulsów przeskoczył , ale raczej za sprawą enkodera bo na przebiegach widać miejscami dziwne stany) oczywiście nie tracimy zbędnie drugiego timera. Cała obsługa jest w przerwaniu, opóźnienia dodałem bo po pierwsze są tam kondensatory a te porty nie czytują stanu za Schmittem. Na analizatorze widać około 60uS przesunięcia między przebiegami na pinie enkodera i wyjściu wyzwalającym. Jeżeli kondensator będzie większy niż 15n to trzeba odpowiednio dobrać opóźnienia.
    Zaznaczę że używałem bardzo miernej jakości enkodera z chińskiej myszki komputerowa, więc na pewno nie jest on przystosowany do 100 impulsów na sekundę.


    [atmega8][bascom]Problem z obsługą impulsatora



    Edytuj

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0