Bascom - Sterowanie wyjściami z impulsatora?


Witam. Jak sterować wyjściami impulsatora w taki sposób by kręcąc w prawo załączony był potrc.1 a w lewo portc.2 . W momencie braku ruchu mają być porty wyłączone. Nie mam pomysłu jak to zrealizować ;-(

Impulsator:
If Pind.4 = 1 Then
Incr Enkoder
Gosub Wyc
End If
 
If Pind.4 = 0 Then
Decr Enkoder
Gosub Wyc1
End If
Return
 
Wyc:
????? Portc.1
Return
 
    Wyc1:
???? Portc.2
Return




Portret użytkownika EDC

Obsługa Enkoderów jest

Obsługa Enkoderów jest przybliżona tu na stronie.
Podprogram zwraca wartość która może mieć wynik ujemny dlatego nalezy zadeklarować zmienną typu Integer (w przykładzie jest to Rezultat). Do oceny potrzebuje jeszcze zmiennej typu Byte (tu nazywa się Tryb). I1 i I2 to wyprowadzenia kontrolera do których podłaczony jest enkoder.

Impulsator:
  Rezultat = 0
 Select Case Tryb
  Case 0:
   If I1 = 1 And I2 = 1 Then Incr Tryb
  Case 1:
   If I1 = 1 And I2 = 0 Then
    Rezultat = 1
    Incr Tryb
   End If
   If I1 = 0 And I2 = 1 Then
    Rezultat = -1
    Incr Tryb
   End If
  Case 2:
   If I1 = 0 And I2 = 0 Then Incr Tryb
  Case 3:
   If I1 = 1 And I2 = 0 Then
    Rezultat = -1
    Tryb = 0
   End If
   If I1 = 0 And I2 = 1 Then
    Rezultat = 1
    Tryb = 0
   End If
 End Select
Return

W pętli głównej Twojego programu wpisujesz skok do tego podprogramu, a potem analizujesz zwróconą wartość zmiennej Rezultat.

Do
Gosub Impulsator
 
If Rezultat = 1 Then Set portc.1 else Reset portc.1
If rezultat = -1 Then Set portc.2 else Reset portc.2
 
Loop


Mozesz wszystko spiąć razem w podprogramie Impulsator Byleby skok do niego dokonywał się cyklicznie tak by przy braku kręcenia zmienna Rezultat przybrała wartość = 0 (wtedy porty się wyłącza).
Można to zrobić inaczej, ale to już powinno Cie jakoś naprowadzić.
Ps. Jeśli dasz warunek If Rezultat <> 0 Then.. to będziesz miał reakcję na jakiekolwiek poruszenia enkodera co możesz wykorzystać osobno np. do uruchomienia podświetlania, lub jakiegoś innego "wybudzenia"

-

BARTek
Moja strona

Portret użytkownika Mirix

Będzie mały problem , bo

Będzie mały problem , bo enkoder obsługiwany jest przerwaniem INT1 i nie wiem czy tak to się uda wykonać. Sprawdzę kod w praktyce i zobaczę . A może jest jakiś inny sposób, by w czasie obrotu w lewo lub w prawo ustawiane było odpowiednie wyjście w stan załaczenia.

Portret użytkownika EDC

Może tak :)

Config Int1 = Falling
Const Debouncetime = 1
Dim Encounter As Integer, Encounter_old As Integer
Set Portd.4
On Int0 Getencoder
 
Encounter = 0
 
Enable Interrupts
Enable Int0
 
Do
If Encounter <> Encounter_old then
 If Encounter < Encounter_old then
    Encounter_old = Encounter
    Set Portc.1
  end if
 If Encounter > Encounter_old then
    Encounter_old = Encounter
    Set Portc.2
   end if
Else
   Reset Portc.1
   Reset Portc.2
 End if
Loop
 
Getencoder:
  Waitms Debouncetime
  If Portd.7 = 0 Then
    If Portd.4 = 0 Then Incr Encounter Else Decr Encounter
  End If
  Gifr = 64
Return
 
End

Może tak, nie testowałem w praktyce. Parametr Gifr : General Interrupt Flag Register(można poczytać tutaj.. W przerwaniu, jeszcze raz sprawdza czy Port który jest też wejściem przerwania jest w stanie niskim, niby niepotrzebne ale podobno przydaje się w kiepskich enkoderach, wywal na próbę i napisz jak działa bo jestem ciekawy :D
Za decyzję ustawienia portów jak widać odpowiada porównanie poprzedniej wartości zmiennej Encounter. Jesli nie ma różnicy porty sa resetowane w kółko. Możesz też ustawiać porty już w przerwaniu a resetowac w głównej pętli po powrocie, możesz resetować po powrocie z jakimś opóźnieniem ..jeśli obrotów miałoby być więcej niż pomieści Integer to trzeba by pomyśleć o obsłudze przepełnienia. Nie napisałeś co to ma robić :) Czujnik czy manipulator do menu..

-

BARTek
Moja strona

Portret użytkownika EDC

4 warianty obsługi enkodera w Bascom

Witam. Do nowego projektu potrzebny mi będzie enkoder i wpadłem na pomysł by przetestować naraz znane mi procedury obslugi. Przy okazji porównam wady i zalety oraz długość kodów.

Enkoder cały czas podlączony jest do tych samych pinów. Zmieniam cały czas tą samą zmienną w tym samym miejscu wyświetlacza.

Na pierwszy ogień poszlo użycie zewnętrznego przerwania. Działa bardzo dobrze jeśli podłaczy się kondensatorki filtrujące (podłączyłem kupione przez pomyłke 22nF, chciałem kupić 22pF :D ) Bez kondensatorków wyników można sie wystraszyć. Z kondensatorkami jak ręką odjał i działa super. Krótki kod..

$regfile = "m8def.dat"
$crystal = 8000000
 
Cursor Off Noblink
Cls
 
 Encoder_a Alias Pind.2
 Portd.2 = 1
 Portd.3 = 1
 Config Int1 = Falling
 On Int1 Encoder_isr
 Enable Int1
 
' pomiedzy wyjscia enkodera a mase podłączone kondensatory 22nF
 
  Enable Interrupts
 
 Dim Encoder_turn_left As Byte , Encoder_turn_right As Byte
 Dim Zmienna As Word
 
 Lcd "Licznik:"
 
'*********** START PĘTLI *********************
 Do
 
 'encoder turns left
If 0 < Encoder_turn_left Then
    Decr Encoder_turn_left
    'tutaj Twój kod -
 
  Decr Zmienna
  Locate 1 , 10 : Lcd Zmienna ; "     "
End If
 
If 0 < Encoder_turn_right Then
    Decr Encoder_turn_right
    'tutaj Twój kod +
 
  Incr Zmienna
  Locate 1 , 10 : Lcd Zmienna ; "     "
End If
 
Loop
End
'**********************************************
 
 
'*********** Przerwanie z wyjscia B enkodera **
Encoder_isr:
 
If Encoder_a = 0 Then
   Incr Encoder_turn_right
 Else
   Incr Encoder_turn_left
End If
 
Return
 
'Działa dobrze ale wymaga pinu przerwania zewnetrznego

Jako drugie przetestowałem instrukcje Encoder wbudowana w Bascom. Wymaga by piny enkodra nalezały do tego samego portu. Działa kiepsko, niestabilnie, czasem zmniejsza wartość zamiast zwiększać...

$regfile = "m8def.dat"
$crystal = 8000000
 
Cursor Off Noblink
Cls
 
Portd = 255
 
' pomiedzy wyjscia enkodera a mase podłączone kondensatory 22nF
 
Dim Enc As Byte , Zmienna As Word
 
 Lcd "Licznik:"
 
Do
'Dowolnosc pinow w obrebie jednego portu
 
Enc = Encoder(pind.2 , Pind.3 , Zmniejsz , Zwieksz , 0)
 
Loop
End
 
Zmniejsz:
Decr Zmienna
Locate 1 , 10 : Lcd Zmienna ; "     "
Waitms 50
Return
 
Zwieksz:
Incr Zmienna
Locate 1 , 10 : Lcd Zmienna ; "     "
Waitms 50
Return
 
'Działa himerycznie i bez precyzji.

Trzeci to trochę okrojony na potrzeby testów (bo w oryginale obsługuje tez przycisk enkodera z rozpoznaniem długości przyciśnięcia) sposób z wykorzystaniem Timera. Działa zawsze i ze wszystkim, pewnie nawet i pod wodą :D Funkcja w kazdym miejscu programu zapytana o stan enkodera zwraca wartość.
Ilość linii kodu może zniechęcać ale zapewniam że różnice pomiedzy kodami to odpowiednio 11%, 10%, 17% i dla ostatniego 13% flasha wliczając cały czas obsługę LCD więc prosze patrzeć na różnice. Przerwanie Timera w programie może słuzyć do odmierzania czasu dla reszty układu..

$regfile = "m8def.dat"
$crystal = 8000000
 
Cursor Off Noblink
Cls
 
Const Atmega328 = 0
 
#if Atmega328 = 1
Config Timer2 = Timer , Async = Off , Prescale = 256 , Compare_a = Disconnect , Compare_b = Disconnect , Clear Timer = 1
Enable Compare2a : On Compare2a Timer2_4ms : Compare2a = 124
#else
Config Timer2 = Timer , Prescale = 256 , Compare = Disconnect , Clear Timer = 1
Enable Compare2 : On Compare2 Timer2_4ms : Compare2 = 124
#endif
 
'---------------------------- enkoder -----------------------------
Config Pind.2 = Input : Set Portd.2                         'piny enkodera
Config Pind.3 = Input : Set Portd.3                         'piny enkodera
 
Enc_b Alias Pind.2
Enc_a Alias Pind.3
 
Dim Lngfreq As Integer
Dim Bytincr As Byte
Dim Bytenc_old As Byte
Dim Bytenc_new As Byte
 
Dim Enc_timer As Word , Enc_flag As Byte
 
Const Lngstep = 1
 
Const Enc_prev = 1
Const Enc_next = 3
 
Dim Stan_enc As Byte
 
Dim Zmienna As Word
 
Declare Function Sprawdz_encoder() As Byte
'******************************************************************
Enable Interrupts
 
Lcd "Licznik:"
 
Do
  Stan_enc = Sprawdz_encoder()
 
If Stan_enc = Enc_next Then
  Incr Zmienna
  Locate 1 , 10 : Lcd Zmienna ; "     "
End If
 
If Stan_enc = Enc_prev Then
  Decr Zmienna
  Locate 1 , 10 : Lcd Zmienna ; "     "
End If
 
 Stan_enc = 0
 
Loop
End
'************************ Przerwanie Timera ***********************
Timer2_4ms:
 
 Bytenc_new.0 = Enc_a
 Bytenc_new.1 = Enc_b
 
   If Bytenc_new <> Bytenc_old Then
      If Bytenc_new = &B00000011 And Bytenc_old = &B00000010 Then Bytincr = 2
      If Bytenc_new = &B00000011 And Bytenc_old = &B00000001 Then Bytincr = 1
      'If Bytenc_new = &B00000000 And Bytenc_old = &B00000001 Then Bytincr = 2
      'If Bytenc_new = &B00000000 And Bytenc_old = &B00000010 Then Bytincr = 1
     Bytenc_old = Bytenc_new
   End If
 
   If Enc_timer <> 0 Then Decr Enc_timer
Return
 
 
 
'************************* Funkcja enkodera ***********************
Function Sprawdz_encoder() As Byte
          Sprawdz_encoder = 0
 
   ' encoder
 Disable Timer2                                             'Stop Timer0 for display
 
    Select Case Bytincr                                     'Set/show TRX freq.
        Case 2                                              'Encoder incremented
            Lngfreq = Lngfreq + Lngstep
            If Enc_flag = 0 Then Enc_timer = 150            ' 4 * 150 = 600 ms
            Enc_flag = 1
        Case 1                                              'Encoder decremented
            Lngfreq = Lngfreq - Lngstep
            If Enc_flag = 0 Then Enc_timer = 150            ' 4 * 150 = 600 ms
            Enc_flag = 1
    End Select
 
    If Bytincr > 0 Then                                     'Freq. was changed
        Bytincr = 0                                         'Reset increment flag
    End If
 
    If Lngfreq <= -4 Then                                   ' jeżeli 4 inpulsy
        Sprawdz_encoder = Enc_prev
        Lngfreq = 0
        Enc_flag = 0
    End If
 
    If Lngfreq => 4 Then                                    ' jeżeli 4 inpulsy
        Sprawdz_encoder = Enc_next
        Lngfreq = 0
        Enc_flag = 0
    End If
 
    If Enc_timer = 0 And Enc_flag = 1 Then
        Lngfreq = 0
        Enc_flag = 0
    End If
 
    Enable Timer2                                           ' Restart Timer0
 
End Function

Teraz pora na czarnego konia tych zawodów. Obsługa by Mirley :D
Działa nadzwyczaj dobrze :) do zwykłych regulacji idealny jeśli nie ma się wolnego zewnętrznego przerwania.
Zapomniałem dodac że enkoder na którym testuję kosztował 2zł80gr. :D

$regfile = "m8def.dat"
$crystal = 8000000
 
Cursor Off Noblink
Cls
 
Portd = 255
 
Dim In1 As Bit , In2 As Bit
Dim Tryb As Byte , Rezultat As Integer
Dim Zmienna As Word
 
Enable Interrupts
 
 Lcd "Licznik:"
 
Do
 
  Gosub Impulsator
 
If Rezultat <> 0 Then
  Zmienna = Zmienna + Rezultat
  Locate 1 , 10 : Lcd Zmienna ; "     "
   Rezultat = 0
End If
 
Loop
End
 
'-------------- sub enkodera 1 -----------
Impulsator:
 In1 = Pind.3
 In2 = Pind.2
 Rezultat = 0
 Select Case Tryb
  Case 0:
   If In1 = 1 And In2 = 1 Then Incr Tryb                    'jezeli dwa rozwarte
  Case 1:
   If In1 = 1 And In2 = 0 Then Tryb = 2
   If In1 = 0 And In2 = 1 Then Tryb = 3
  Case 2:
   If In1 = 0 And In2 = 1 Then
     Rezultat = 1
     Tryb = 0
   End If
  Case 3:
   If In1 = 1 And In2 = 0 Then
     Rezultat = -1
     Tryb = 0
   End If
 End Select
 Waitus 100
Return
 
' Działa baaardzo przyzwoicie :)
 
 
'------------ sub enkodera 2 ------------
'Impulsator:
' In1 = Pind.3
' In2 = Pind.2
' Rezultat = 0
' Select Case Tryb
'  Case 0:
'   If In1 = 1 And In2 = 1 Then Incr Tryb    'jezeli dwa rozwarte
'  Case 1:
'   If In1 = 1 And In2 = 0 Then
'    Rezultat = 1
'    Incr Tryb
'   End If
'   If In1 = 0 And In2 = 1 Then
'    Rezultat = -1
'    Incr Tryb
'   End If
'  Case 2:
'   If In1 = 0 And In2 = 0 Then Incr Tryb
'  Case 3:
'   If In1 = 1 And In2 = 0 Then
'    Rezultat = -1
'    Tryb = 0
'   End If
'   If In1 = 0 And In2 = 1 Then
'    Rezultat = 1
'    Tryb = 0
'   End If
' End Select
'Return
 
' Ten często zwiększa wartośc o 2
 
'********** ŻEBY ODKOMENTOWAĆ lub ZAKOMENTOWAĆ BLOK KODU ZAZNACZ GO I UŻYJ CTRL + M **************

Wszystkie można sobie samemu sprawdzić. Jesli ma ktoś jakiś sprawdzony sposób obsługi to chętnie przetestuję :)

-

BARTek
Moja strona

Portret użytkownika EDC

Sejf jak z filmów o gangu Olsena :D

Haha to nie żart! :D
Ten sejf da się otworzyć jak przyłożysz ucho albo stetoskop jak Olsen.
Działa tak. Gdy kręcisz pokrętłem sejfu ten cichutko tyka. Dzwięk to prawdziwy dzwięk z zegarka przekonwertowany w postać binarna i zapisany w eepromie procesora. Dzwięk odtwarzany jest za posrednictwem dwóch pinów procesora i kondensatora. Ja podłączyłem do tego jedną słuchawkę.

Jak w prawdziwym sejfie trzeba najpierw pokrecić w prawo i ustawić Code(1) potem w lewo i ustawić Code(2). Ostatecznie znów w prawo i ustawić Code(3). Jesli jesteś pewien kodu, naciska się przycisk enkodera i drzwi się otwierają. Jesli gdziekolwiek sie pomylisz kosztuje Cię to czas zdefiniowany w programie jako Safetime.
Okazuje się jednak że kodu nie musisz znać. Jesli naciśniesz na 3 sekundy przycisk enkodera to uaktywni sie "Olsen Mode" :D
W trybie Olsena można usłyszeć malusieńki dodatkowy "tyk" gdy kod cyfry sie zgadza :D Wtedy trzeba juz kręcić w druga stronę.
Lcd jest tylko do celów szkoleniowych dla włamywaczy :D i gdy u góry w programie wpisze się Lcd_on_board = 0 to nie będzie on w ogóle skompilowany i kod jest dużo mniejszy. Można dopisac sobie procedurę zmiany kodu, której nie potrzebowałem. Kod jest w eepromie.

'------------------------------------------------------------------
'            The real Olsen`s gang Safe from Franc Jager :D
'              Sound "tick" is produced when encoder turn.
'             In Olsen mode additional "tick" will be heared.
'Special thanks for  Evert Dekker for knowledge sharing.
' Sound pattern is in eeprom and played via two R and C
'                    BARTek EDC
'------------------------------------------------------------------
$regfile = "attiny2313a.dat"
$crystal = 12000000
$hwstack = 32
$swstack = 8
$framesize = 16
 
Const Lcd_on_board = 1
'NOTE THAT LCD IS FOR TRAINING ONLY :D
#if Lcd_on_board = 1
Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
Config Lcd = 16 * 2
Cursor Off Noblink
Cls
#endif
'Voice pin`s connect together via 10kOhm resistor, then via 100nF to ground. This is audio output.
'headphone or piezo sound good :D
'Sound is realy *.wav "tick" conwerted to BIN file
Config Portd.4 = Output
Config Portd.5 = Output
 
Vp1 Alias Portd.4                                           'Voice pin 1
Vp2 Alias Portd.5                                           'Voice pin 2
Rygiel Alias Portb.0                                        'lock
Encoder_sw Alias Pind.6                                     'enkoder switch
Encoder_a Alias Pind.2
Portd.3 = 1
Portd.2 = 1
Portd.6 = 1
Portb.0 = 1
Config Int1 = Falling
Enable Int1 : On Int1 Encoder_isr
 
'*** Timer0 Config for 10ms Interrupt CTC Mode ***
Config Timer0 = Timer , Prescale = 1024 , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1
Enable Compare0a : On Compare0a Int_10ms : Compare0a = 116
 
Config Timer1 = Timer , Prescale = 1 , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1
Enable Compare1a : On Compare1a Timer1_int : Compare1a = 272       'Crystal/44100 sample rate
Stop Timer1
 
Dim Bytetodo As Byte , Outbyte As Byte
Dim Bitcount As Byte , N As Byte , S As Byte
Dim Tick As Byte , Code(4) As Byte , Tick_flag As Byte
Dim 1s_flag As Byte , Tryb As Byte , Sounds As Byte
Dim Divider As Byte , Divider2 As Byte , Safe As Byte
Dim Encoder_turn_left As Byte , Encoder_turn_right As Byte
 
Const Safetime = 8
Const Opentime = 3
Safe = Safetime
 
For N = 1 To 4
Readeeprom Code(n) , N
Next N
 
Enable Interrupts
 
Do
'-------------- encoder ------------
If 0 < Encoder_turn_left Then
    Decr Encoder_turn_left
    Incr Tick
     Select Case Tryb
      Case 1
       Tryb = 0
       Safe = Safetime
      Case 3
       Tryb = 0
       Safe = Safetime
     End Select
End If
 
If 0 < Encoder_turn_right Then
    Decr Encoder_turn_right
    Incr Tick
     Select Case Tryb
      Case 2
       Tryb = 0
       Safe = Safetime
      Case 4
       Tryb = 0
       Safe = Safetime
      End Select
End If
'-----------------------------------
Select Case Tryb
 
  Case 1
   If Tick = Code(tryb) Then
    Tryb = 2
    If Sounds = 1 Then Gosub Play_sound
    Tick = 0
    End If
    If Encoder_sw = 0 Then Sounds = 1
  Case 2
   If Tick = Code(tryb) Then
    Tryb = 3
    If Sounds = 1 Then Gosub Play_sound
    Tick = 0
    End If
  Case 3
   If Tick = Code(tryb) Then
    Tryb = 4
    If Sounds = 1 Then Gosub Play_sound
    Tick = 0
    End If
  Case 4
   If Encoder_sw = 0 Then
   #if Lcd_on_board = 1
    Locate 2 , 1 : Lcd "Open"
   #endif
    Reset Rygiel
    Safe = 2
    Tryb = 1
    Sounds = 0
   End If
 
 End Select
'------------------ 1s -------------
If 1s_flag = 1 Then
   1s_flag = 0
 
 If Safe > 0 Then Decr Safe
 
 If Safe = 0 Then
   If Tryb = 0 Then
    Tryb = 1
    Tick = 0
    Sounds = 0
   Else
   #if Lcd_on_board = 1
    Locate 2 , 1 : Lcd "Safe"
   #endif
    Set Rygiel
   End If
 End If
 
 If Encoder_sw = 0 Then Incr S Else S = 0                   'If pressed 3 sec
 If S = 3 Then Sounds = 1                                   '*********** OLSEN MODE *************
End If
'-----------------------------------
If Tick_flag = 1 Then
   Tick_flag = 0
   Gosub Play_sound
End If
Loop
End
 
'-----------------------------------
Encoder_isr:
 Tick_flag = 1
  If Encoder_a = 0 Then
   Incr Encoder_turn_right
 Else
   Incr Encoder_turn_left
 End If
 
Return
 
'-----------------------------------
Play_sound:
 
N = 11
Bytetodo = 112
Start Timer1
Do
If Bitcount = 7 Then
 Readeeprom Outbyte , N
 Incr N
 Decr Bytetodo
 Bitcount = 0
End If
Loop Until Bytetodo = 0
Stop Timer1
Vp2 = 0 : Vp1 = 0
 
Return
'-----------------------------------------------
Timer1_int:
 
Vp2 = Vp1
If Bitcount > 0 Then Shift Outbyte , Right , 1
Vp1 = Outbyte.0
Incr Bitcount
 
Return
'-----------------------------------------------
Int_10ms:
Incr Divider
 If Divider = 100 Then
    Divider = 0
    1s_flag = 1
 End If
#if Lcd_on_board = 1
Incr Divider2
If Divider2 = 10 Then
Locate 1 , 1 : Lcd Tick ; " " ; Tryb ; " " ; Safe
Divider2 = 0
End If
#endif
Return
'******************* EEPROM CONTENT ***** CODE IS 8-5-6 ***********************************
'00000000 00 08 05 06 00 00 00 00 00 00 00 00 6E 55 55 75 02 7F 0E 1E ............nUUu...
'00000014 3E 78 7C F0 C0 E8 87 0F FC 38 E0 F7 81 07 0F 1F 1C 86 8F 07 >x|...ç..8..ü....aA.
'00000028 0F 0E FF 02 1F 1F 0A 7C 7E 38 38 F0 7A 54 F4 70 F0 E9 E0 C3 .......|~88.zT.p....
'0000003C 83 E3 CB 92 52 5B A9 55 F4 42 F5 92 AA 55 93 56 4B AA B5 AA â..AR[.U.B.A?UôVK?.?
'00000050 AA 52 55 55 B2 B5 54 55 4D 95 D5 4A AA 4D AD AA 54 55 55 55 ?RUU..TUMo.J?M!?TUUU
'00000064 55 55 55 B5 52 55 55 55 55 55 A5 A5 A5 55 55 55 55 55 55 55 UUU.RUUUUUNNNUUUUUUU
'00000078 55 55 AA                                                    UU?
'******************************************************************************************

Taka umiejętnościa otwierania sejfów można błysnąć przed towarzystwem :D ..
Co do odtwarzania dzwięku..okazuje się, że jeśli w swoim projekcie masz nieuzywana prawie pamięć Eeprom to możesz pokusić sie o dodanie dzwięku do niego. Zastąpić jakiś piszczek ladnym jinglem. Plik w formacie wav konwertuje ten program do bin.

Pamięci jest trochę potrzebne ale jeśli masz wolna to dlaczego nie?
Pierwotnie to czytało z zewnętrznych pamięci I2c, przerobiłem sobie do tego pomysłu i w wiekszych prockach nie takie rzeczy można będzie grać :D
W dobie pamięci flash to żadne odkrycie ale może niepotrzebna własnie komuś ich obsługa, ma plac w eepromie..

Pozdrawiam.

-

BARTek
Moja strona

Portret użytkownika kaktus

moje dywagacje z impulsatorem ;-)

Opisałem tutaj
ideologia inna ale sprawa identyczna ;-D

-

"Cierpliwym być musisz, by wiedzę zgłębiać tajemną, gdyż ciemna strona mocy niszczącą i silną jest.".

Portret użytkownika EDC

Enkodery obrotowe c.d.

W międzyczasie połączyłem kilka pomysłów. Jeden taki, że stan pinów sprowadzony jest do wartości najmłodszych bitów. Pozbywamy się instrukcji And.

$regfile = "m328pdef.dat"                                   'register file for ATmega328p
$crystal = 8000000                                          '8MHz crystal
 
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portc.0
Config Lcd = 20x4
Cursor Off Noblink                                          'nowy sposób zapisu
Cls
 
Portd = 255
 
Dim Tryb As Byte , Rezultat As Integer
Dim Zmienna As Word
Dim Enc As Byte
 
 Lcd "Licznik:"
 
Do
 
  Gosub Impulsator
 
If Rezultat <> 0 Then
  Zmienna = Zmienna + Rezultat
  Locate 1 , 10 : Lcd Zmienna ; "     "
   Rezultat = 0
End If
 
Loop
End
 
'--- sub enkodera 1 ---
Impulsator:
 Enc.0 = Pind.2
 Enc.1 = Pind.3
 Rezultat = 0
 Select Case Tryb
  Case 0:
   If Enc = 3 Then Incr Tryb                                'jezeli dwa rozwarte
  Case 1:
   If Enc = 2 Then Tryb = 2
   If Enc = 1 Then Tryb = 3
  Case 2:
   If Enc = 1 Then
     Rezultat = 1
     Tryb = 0
   End If
  Case 3:
   If Enc = 2 Then
     Rezultat = -1
     Tryb = 0
   End If
 End Select
 Waitus 100
Return

Drugi to ciekawostka oparta na przerwaniu PCINT
$regfile = "m328pdef.dat"                                   'register file for ATmega328p
$crystal = 8000000                                          '8MHz crystal
 
Config Lcdpin = Pin , Db4 = PORTB.2 , Db5 = PORTB.3 , Db6 = PORTB.4 , Db7 = PORTB.5 , E = PORTB.0 , Rs = PORTC.0
Config Lcd = 20x4
Cursor Off Noblink                                          'nowy sposób zapisu
Cls
 
' config for encoder
PORTD.2 = 1
PORTD.3 = 1
Encoder_a Alias PIND.2
Encoder_b Alias PIND.3 'pin który generuje przerwanie
 
PCMSK2 = &B00001000
Enable PCINT2 : On PCINT2 Encoder_isr
 
Dim Encoder_turn_left As Byte , Encoder_turn_right As Byte
'-------------------------------------------
Dim Zmienna As Word
Enable Interrupts
 
Lcd "Licznik:"
 
Do
 
 'encoder turns left
If 0 < Encoder_turn_left Then
    Decr Encoder_turn_left
    'tutaj Twój kod -
 
  Decr Zmienna
  Locate 1 , 10 : Lcd Zmienna ; "     "
End If
 
If 0 < Encoder_turn_right Then
    Decr Encoder_turn_right
    'tutaj Twój kod +
 
  Incr Zmienna
  Locate 1 , 10 : Lcd Zmienna ; "     "
End If
 
Loop
End
 
'tutaj obsługa przerwania zewnetrznego z enkodera
Encoder_isr:
If Encoder_b = 0 Then 'dodatkowy warunek
If Encoder_a = 0 Then
   Incr Encoder_turn_right
 Else
   Incr Encoder_turn_left
 End If
 End If
Return

Obydwa opisałem u siebie na stronie i pozwoliłem sobie podlinkować Mirleya i Kaktusa stronę.

-

BARTek
Moja strona