Enkoder w Xmega

Rodzina procesorów bogatszych w wiele nowych rozwiązań i dlatego warto po nie sięgnąć.
Awatar użytkownika
Jacek
Posty: 384
Rejestracja: 25 kwie 2016, 19:14

Enkoder w Xmega

Post autor: Jacek » 27 wrz 2020, 22:48

Witam - wiem że wszyscy są zajęci ale jak ustawić system zdarzeń aby xmega odczytywała i zliczała impulsy w lewo i w prawo mogę prosić o wyjaśnienie?
pozdrawiam Jacek.
Press
Posty: 65
Rejestracja: 21 sty 2018, 23:08

Re: Xmega sprzętowa obsługa enkodera -to takie proste

Post autor: Press » 01 paź 2020, 11:32

Nie bardzo rozumiem.
Dawno się tym bawiłem, ale działa to mniej więcej tak.
Sprzętowo wykrywany jest ruch i w zależności od kierunku obrotu licznik sprzętowy jest zwiększany lub zmniejszany.
W programie porównujesz wartość licznika z wartością zapamiętaną wcześniej i z tej różnicy wychodzi o ile impulsów i w jakim kierunku został wykonany obrót. Jeśli nie chcesz sprawdzać licznika w interwałach, to ustaw przerwanie na jednym lub obu pinach od enkodera.
Awatar użytkownika
Jacek
Posty: 384
Rejestracja: 25 kwie 2016, 19:14

Re: Xmega sprzętowa obsługa enkodera -to takie proste

Post autor: Jacek » 10 paź 2020, 12:20

Witam - tak tylko ja nie wiem jak to ustawić w xmedze jeżeli mogę prosić o jakiś przykład byłbym zobowiązany.
pozdrawiam Jacek.
Awatar użytkownika
niveasoft
Posty: 1213
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Xmega sprzętowa obsługa enkodera -to takie proste

Post autor: niveasoft » 12 paź 2020, 17:00

To można, jak zawsze, rozwiązać na wiele sposobów.
Problemem jest to, że ten szesnastobitowy timer, jak kręcisz w lewo to przeskoczy z 0 na 65535.
Nie wiem ile kroków potrzebujesz tam w tokarce. Gdyby wystarczyło 32768 to mógłbyś po starcie Xmegi wpisać do Timera taka wartość. Wtedy timer będzie w lewo zjeżdżał do zera a w prawo liczył w górę do 65535. Potem proste porównanie poprzedniego odczytu i wiesz co się dzieje.

Poniżej masz trochę inne rozwiązanie. Przy przejściu przez zero sprawdza czy następny odczyt to 1->prawo czy 65535->lewo. Tu jednak można zgubić jakiś impuls jak w programie będziesz miał więcej kodu, ale ustawia zmienną Steps od -32767 do +32768. Jeśli więc widzisz np. -5 to silnik powinien zrobić pięć kroków w lewo i za każdym razem dodać jeden krok. Widzisz +5 to robisz pięć kroków w prawo za każdym razem odejmując od zmiennej Steps jeden. Silnik zawsze ma pilnować by Steps=0

Sprawdź bo nie bardzo mam czas to wszystko połączyć. Może trzeba pomyśleć nad innym rozwiązaniem...jeszcze nie wiem.
  1.     '***********************************************************************
  2.     $regfile = "xm128a3udef.dat"
  3.     $crystal = 32000000
  4.     $hwstack = 64
  5.     $swstack = 64
  6.     $framesize = 64
  7.  
  8.     'Enable The Osc
  9.     Config Osc = Enabled , 32mhzosc = Enabled
  10.  
  11.     ' ***************** SYSTEM CLOCK CONFIG ********************************
  12.     '                INTERNAL 32MHz NO PRESCALE
  13.     '
  14.     Config Osc = Disabled , 32mhzosc = Enabled , 32khzosc = Enabled
  15.     Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
  16.     '
  17.     'ENABLING AUTOMATIC OSCILLATOR CALIBRATION
  18.     Osc_dfllctrl.0 = 1
  19.     Dfllrc32m_ctrl.0 = 1
  20.     '
  21.     '***********************************************************************
  22.     Config Priority = Static , Vector = Application , Lo = Enabled       'Enable Lo Level Interrupts
  23.     '***********************************************************************
  24.     '*******************Xmega 128A3U***********************
  25.     '* UART *********** TX pin  *  RX pin                 *
  26.     '* ****************************************************
  27.     '* COM1 - UART_C0 * PORTC.3 * PORTC.2                 *
  28.     '******************************************************
  29.     '* COM2 - UART_C1 * PORTC.7 * PORTC.6                 *
  30.     '******************************************************
  31.     '* COM3 - UART_D0 * PORTD.3 * PORTD.2                 *
  32.     '******************************************************
  33.     '* COM4 - UART_D1 * PORTD.7 * PORTD.6                 *
  34.     '******************************************************
  35.     '* COM5 - UART_E0 * PORTE.3 * PORTE.2                 *
  36.     '******************************************************
  37.     '* COM6 - UART_E1 * PORTE.7 * PORTE.6                 *
  38.     '******************************************************
  39.     '* COM7 - UART_F0 * PORTF.3 * PORTF.2                 *
  40.     '******************************************************
  41.     '* COM8 - UART_F1 * PORTF.7 * PORTF.6                 *
  42.     '******************************************************
  43.  
  44.     '***********************************************************************
  45.     Dim Buart_channel As Byte                               '0 = COM1 ...... 7 = COM8
  46.     Config Com3 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8       'COM3 - UART_D0 PORTD.3 PORTD.2
  47.     Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8       'COM1 - UART_C0 PORTC.3 PORTC.2
  48.     Buart_channel = 2
  49.     'Print #buart_channel , "This use COM3"                  'print current Uart
  50.     'Print #buart_channel , "MCU Rev. = " ; Mcu_revid        'version of the MCU
  51.     Print #buart_channel , ""
  52.     Print #buart_channel , "Started  "
  53.  
  54.     '***********************************************************************
  55.      Dim Encoder_tmp As Word , Encoder_prev As Word         'zmienna dla enkodera
  56.      Dim Steps As Integer
  57.      Enable Interrupts                                      'włacz przerwania globalne
  58.     '***********************************************************************
  59.     'config pinA.2 = input                                       'index pin of the encoder
  60.     Config Pina.1 = Input                                   'enkoder B
  61.     Config Pina.0 = Input                                   'enkoder A
  62.     'Config Xpin = PinA.2 , Outpull = pullup , Sense = low_level
  63.     Config Xpin = Porta.1 , Outpull = Pullup , Sense = Low_level       'enable Pull up and reaction on low level
  64.     Config Xpin = Porta.0 , Outpull = Pullup , Sense = Low_level
  65.     'konfigurujemy system zdarzeń
  66.  
  67.     Config Event_system = Dummy , Mux0 = Porta.0 , Qd0 = Enabled , Digflt0 = 4
  68.     'konfiguracja systemu zdarzeń multiplexer kanał 0 , portA.0, obsługa enkodera QDO właczona, filtr  cyfrowy 8
  69.  
  70.     'gdy używamy idndexu musimy dodać QDIO=enabled
  71.     'config Event_system = Dummy , Mux0 = portA.0 , QD0 = enabled , QDI0 = enabled , Digflt0 = 8
  72.  
  73.  
  74.     '***********************************************************************
  75.     Config Tcd0 = Normal , Prescale = E0 , Event_source = E0 , Event_action = Qdec
  76.  
  77.     'konfiguracja timera TCD0 normal= bez generowania sygnałów, preskaler =e0, zródło zdarzenia=podajemy zródło czyli event system
  78.     'kanał 0 , event action =czyli reakcja na zdarzenie QDEC właczenie obsługi enkodera
  79.     '***********************************************************************
  80.  
  81.     Do
  82.  
  83.        Encoder_tmp = Tcd0_cnt
  84.  
  85.        If Encoder_prev <> Encoder_tmp Then                  'jesli zawartosc timera TCD0 jest różna od naszej zmiennej to
  86.  
  87.              Select Case Encoder_prev
  88.                Case 0
  89.                 If Encoder_tmp = 1 Then Incr Steps Else Decr Steps
  90.                Case Else
  91.                 Select Case Encoder_tmp
  92.                  Case Is < Encoder_prev : Decr Steps
  93.                  Case Is > Encoder_prev : Incr Steps
  94.                 End Select
  95.               End Select
  96.  
  97.         Encoder_prev = Encoder_tmp
  98.           Print #buart_channel , Steps                      'wyśli przez port szeregowy 2 (zmienna buart=2)
  99.        End If
  100.  
  101.       'na ekranie termianla zobaczymy liczbe impulsów policzonych przez nasz timer.
  102.       'na jeden przeskok enkodera przypadaja 4 impulsy
  103.  
  104.  
  105.        'to możesz robić z inną częstotliwością
  106.  
  107.        If 50ms = 1 Then
  108.         50ms = 0
  109.  
  110.           If Motor_step_pin = 1 Then
  111.            Reset Motor_step_pin
  112.           Else
  113.  
  114.              Select Case Steps
  115.               Case Is < 0
  116.                Incr Steps
  117.                'Call Ustaw_kierunek_l
  118.                Set Motor_step_pin
  119.               Case Is > 0
  120.                Decr Steps
  121.                'Call Ustaw_kierunek_r
  122.                Set Motor_step_pin
  123.              End Select
  124.  
  125.           End If
  126.  
  127.        End If
  128.  
  129.     Loop
  130.  
  131.     End                                                     'end program
Pikczu
Posty: 389
Rejestracja: 17 sie 2015, 13:46
Lokalizacja: Dublin, Ireland
Kontakt:

Re: Xmega sprzętowa obsługa enkodera -to takie proste

Post autor: Pikczu » 12 paź 2020, 19:43

Od tego jest bit kierunku o nazwie DIR o który Jacek enigmatycznie pytał w innym wątku i dostał odwiedź
viewtopic.php?f=18&t=354#p2883
Zmieniając bit będzie zawsze liczyło w w wybranym kierunku niezależenie od prawdziwego kierunku obrotu.
Awatar użytkownika
niveasoft
Posty: 1213
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Xmega sprzętowa obsługa enkodera -to takie proste

Post autor: niveasoft » 12 paź 2020, 20:59

Tak, ale co to wniesie do sprawy? Ten bit jest chyba tylko po to żeby nie trzeba było zamieniać miejscami wyjść enkodera A i B.
To ja mam informować Megę tym bitem, że będę kręcił w lewo czy ona ma to wyczaić sama? :D

Osobiście to bym w przerwaniu ustawiał zmienną Steps a w obsłudze jakiegoś Timera te Steps odejmował i rozpędzał/hamował rampę.
Pikczu
Posty: 389
Rejestracja: 17 sie 2015, 13:46
Lokalizacja: Dublin, Ireland
Kontakt:

Re: Xmega sprzętowa obsługa enkodera -to takie proste

Post autor: Pikczu » 12 paź 2020, 21:13

XMega sama ustawia ten bit ale można go zmienić ręcznie.
Z tego co zrozumiałem Jackowi chodzi o to żeby mu zawsze liczyło w górę nie zależnie czy kreci w lewo czy prawo.
Awatar użytkownika
Jacek
Posty: 384
Rejestracja: 25 kwie 2016, 19:14

Re: Xmega sprzętowa obsługa enkodera -to takie proste

Post autor: Jacek » 12 paź 2020, 21:30

Witam - dziękuje Bartku za procedure działa tak jak powinno - zmieniłem 50ms na 10ms silnik kręci raz w lewo raz w prawo co prawda wolno ale kręci wolniej jak ja kręcę enkoderem ale to już duży postęp. Paweł jak wiesz nie umiem tak jak Ty, Bartek pisać programów i procedur - bez waszej pomocy po prostu cały projekt trafi do kosza i o tym nie raz rozmawialiśmy tak że jestem bardzo wdzięczny za to co do tej pory dla mnie zrobiliście chciałbym aby w trybie ręcznym silnik tak nadążał za enkoderem jak na tym filmie https://www.youtube.com/watch?v=To7S_rLIJwk&t=115s
zobacz od 5:08.
pozdrawiam Jacek.
Awatar użytkownika
niveasoft
Posty: 1213
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Xmega sprzętowa obsługa enkodera -to takie proste

Post autor: niveasoft » 12 paź 2020, 21:37

Tak się tym dzisiaj zająłem bo widziałem Twój post na MCS :D
Może zmień ten Timer z 10ms na 1ms a potem sobie programowo 10ms zrobisz jak potrzebujesz np. do jakichś przycisków.
Timerów tam masz dużo. Możesz ustawić jakiś drugi żeby liczył, na przykład, 1ms
Mam u siebie taki malutki driver A48coś tam i silniki NEMA45 i jakieś inne. Może go jutro podłączę i machniemy rampę :P
Trzeba też chyba dodać Stop no i może przeniosę niektóre posty do Twojego tematu, żeby tu Pawłowi nie bruździć :D
Awatar użytkownika
Jacek
Posty: 384
Rejestracja: 25 kwie 2016, 19:14

Re: Xmega sprzętowa obsługa enkodera -to takie proste

Post autor: Jacek » 12 paź 2020, 22:03

Witam - PEŁEN SUKCES silnik kreci jak szalony jak kręcę enkoderem - nagram film jeszcze dzisiaj.
pozdrawiam Jacek.
ODPOWIEDZ