Skocz do zawartości

Algorytm do obsługi serw (Config Servos)


Wojtek

Pomocna odpowiedź

Ponieważ mój ostatni temat zboczył trochę z tematu to dla zagadnienia algorytmu do obsługi serw stworzyłem odrębny. Na podstawie fragmentów programu udostępnionych mi przez KD93 stworzyłem swój program do obsługi serwomechanizmów tym razem z funkcją config servos.

Oto i on:

'STEROWNIK 5 SERWOMECHANIZMÓW NA ATTINY2313 I KWARCU 1MHZ
Dim Pomoc As Word                                         'zmienna do inteligentnego przycisku
Dim Blok1i As Bit                                         'bity blokujące
Dim Blok1d As Bit
Dim Blok2i As Bit
Dim Blok2d As Bit
Dim Blok3i As Bit
Dim Blok3d As Bit
Dim Blok4i As Bit
Dim Blok4d As Bit
Dim Blok5i As Bit
Dim Blok5d As Bit

Config Portb = &B11100000                                 'konfiguracja wejść i wyjść
      Portb = &B11100000                                 'stany spoczynkowe
Config Portd = &B1111111                                  'konfiguracja wejść i wyjść
      Portd = &B1111111                                  'stany spoczynkowe
Config Servos = 6 ,Servo1 = Portb.0, Servo2 = Portb.1 ,   'przypisuję piny do serw
Servo3 = Portb.2 ,Servo4 = Portb.3, Servo5 = Portb.4,
Reload = 10                                               'co kolwiek to znaczy wpisuję tu 10
Enable Interrupts                                         'globalne odblokowanie przerwań

Servo(1) = 150                                            'ustawienie serw w pozycji neutralnej
Servo(2) = 150
Servo(3) = 150
Servo(4) = 150
Servo(5) = 150
Pomoc = 0                                                 'wyzeruję zmienną pomoc
Blok1i = 1                                                'ustawię bity blokujące na 1 czym umożliwię 
Blok1d = 1                                                'powiększanie i zmniejszanie
Blok2i = 1                                                'zmiennych servo(n)
Blok2d = 1
Blok3i = 1
Blok3d = 1
Blok4i = 1
Blok4d = 1
Blok5i = 1
Blok5d = 1

Do                                                        'rozpoczynam pętle główną
Incr Pomoc                                                'zwiększam zmienną pomoc zgodnie z częstotliwością kwarcu
 If Pomoc = 1000 Then                                   '1us * 1tys = 1ms 
                                                                     'ale jeszcze czas na obsłużnie pozostałych
                                                               'linijek programu więc będzie ok. 25ms
 Pomoc = 0                                               'wyzeruję pomoc
 Gosub Przyciski                                         'przejdę do podprogramu przycisk
 End If


If Servo(1) = 200 Then                                    'jeżeli pierwsze serwo znajdzie się w pozycji skrajnej w górę to
Blok1i = 0                                                'zablokuj dalsze powiększanie zmiennej servo(1)
Else                                                      'w przeciwnym razie:
Blok1i = 1                                                'odblokuj dalsze powiększanie zmiennej servo(1)
End If

If Servo(1) = 100 Then                                      'jeżeli pierwsze serwo znajdzie się w pozycji skrajnej w dół to
Blok1d = 0                                                'zablokuj dalsze zmniejszanie zmiennej servo(1)
Else                                                      'w przeciwnym razie
Blok1d = 1                                                'odblokuj dalsze zmniejszanie zmiennej servo(1)
End If


If Servo(2) = 200 Then                                    'analogicznie dla pozostałych serw
Blok2i = 0
Else
Blok2i = 1
End If

If Servo(2) = 100 Then 
Blok2d = 0
Else
Blok2d = 1
End If

If Servo(3) = 200 Then 
Blok3i = 0
Else
Blok3i = 1
End If

If Servo(3) = 100 Then 
Blok3d = 0
Else
Blok3d = 1
End If

If Servo(4) = 200 Then 
Blok4i = 0
Else
Blok4i = 1
End If

If Servo(4) = 100 Then 
Blok4d = 0
Else
Blok4d = 1
End If

If Servo(5) = 200 Then 
Blok5i = 0
Else
Blok5i = 1
End If

If Servo(5) = 100 Then 
Blok5d = 0
Else
Blok5d = 1
End If

Loop                                                      'koniec pętli programu głównego
End                                                       'koniec programu głównego

Przyciski:
If Pind.0 = 0 And Blok1i = 1 Then Incr Servo(1)           'jeżeli przycisk 0 zostanie wciśnięty i Zmienna Blok1i będzie równa 1 to zwiększ
If Pind.1 = 0 And Blok1d = 1 Then Decr Servo(1)           'wartość zmiennej Servo(1)
If Pind.2 = 0 And Blok2i = 1 Then Incr Servo(2)
If Pind.3 = 0 And Blok2d = 1 Then Decr Servo(2)           'analogicznie dla pozostałych przycisków
If Pind.4 = 0 And Blok3i = 1 Then Incr Servo(3)
If Pind.5 = 0 And Blok3d = 1 Then Decr Servo(3)
If Pind.6 = 0 And Blok4i = 1 Then Incr Servo(4)
If Pinb.7 = 0 And Blok4d = 1 Then Decr Servo(4)
If Pinb.5 = 0 And Blok5i = 1 Then Incr Servo(5)
If Pinb.6 = 0 And Blok5d = 1 Then Decr Servo(5)
Return                                                     'wróć programu głównego

Program napisany jest dla kwarcu 1Mhz, ale łatwo mogę to zmienić. Do procka ma być podpiętych 5 serw plus po 2 przyciski na każde serwo.Teraz chciałbym przedstawić jego działanie:

1. W programie głównym znajduje się około 26 linijek kodu. Mam kwarc 1Mhz więc zwiększanie zmienneje Pomoc będzie przypadało gdzieś raz na 25us. (ten parametr nie musi być dokładny gdyż decyduje tylko jak szybko będzie poruszać się serwo gdy będe naciskał przycisk)

2. Gdy osiągnie ona wartość 1000 (czyli po ok. 25ms) przejdzie do podprogramu przycisk.

3. Jeśli zmienne z serii blok będą ustawione na 1 i będzie wciśnięty przycisk. To wówczas zostanie zmieniona wartość zmiennej z serii servo. Stosując takie rozwiązanie chiałem osiągnąć efekt tzw. inteligentnego przycisku czyli przy jego trzymaniu automatycznie zmienna servo będzie zmieniać się co 25ms.

4.Jednocześnie dodałem trochę kodu w programie głównym. Znajdują się tam procedury oparte na poleceniu if. W skrócie ma to za zadanie zablokować dalsze powiększanie zmiennej servo gdyby przyjeła ona wartość maksymalną lub zapobiega dalszemu zmniejszaniu zmiennej gdyby przyjeła wartość minimalną.

I teraz moje pytania:

Czy powyższy program będzie działał prawidłowo?

O co chodzi z taką niechęcią skierowaną w kierunku polecenia config servos? KD93 sterował przecież tym poleceniem aż 13 serw. Natomiast spotkałem się ze stwierdzeniem ,że używając tych poleceń cały manipulator będzie "trząsł mi się jak galareta"?

Czy to prawda ,że z obsługą 6 serw procesor poradzi sobie na taktowaniu 1Mhz. Bo jeśli i tak muszę mieszać w tych fusebitach to już użyję 16Mhz?

Link do komentarza
Share on other sites

Ustaw rezystory podciągające do przycisków, przydała by się jakaś eliminacja drgań styków, opóźnienie albo instrukcja Debounce. Ustaw już przynajmniej te 8MHz wewnętrzny, matrix bodajże pisał kiedyś że obsługiwał na takim taktowaniu 5 serw.

Link do komentarza
Share on other sites

A jaką przewagę miałby zewnętrzny kwarc 8Mhz niż wewnętrzny 8Mhz? No bo jak i tak muszę gmerać w tych fusach to już nieproblem przestawić się na zewnętrzny.

Po co rezystory podciągające?Z innych projektów wiem że działa bez nich. Poza tym ten attiny2313 będzie sterowany z pinów innego attiny2313 odpowiedzialnego za odbiór sygnału radiowego ,więc nie będzie problemu z nieustalonymi stanami na wejściach uC.

W tym wypadku nie ma też problemu z drganiem styków. Polecenie Debounce wykorzystuje polecenie waitms ,które zatrzymuje działanie programu i obsługa serw w chwili naciskania przycisku poszłaby w krzaki. Poza tym program napisany jest tak że odblokowuje możliwość naciśnięcia przycisku tylko raz na ok.25ms.

Link do komentarza
Share on other sites

Jak sterujesz z innego attiny2313 to oczywiście nie musisz, ale w opisie listingu masz napisane przyciski (nie wiem po co robisz to na 2 prockach). Właśnie chodzi o to, że chyba łatwiej włączyć wewnętrzny 8MHz który znajduje się kilka linijek pod tym 1MHz i się po opisie zorientujesz szybko który to, niż zmieniać na 8MHz zewnętrzny i podłączać go. Jak już ustawisz zewnętrzny to najlepiej 16MHz. Nie wydaje mi się żeby była tak znacząca różnica pomiędzy 8MHz wew i zew, to nie jest zegarek.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Chyba w Bascom AVR. Pogoogluj, ja tak się uczyłem ustawiać fuse bity. Pamiętaj tylko, ze przełączając na kwarc zewnętrzny musisz mieć go podłączony prawidłowo przy zmianie.

Link do komentarza
Share on other sites

KD93 W Avr Studio ,bo używam programatora USB ,którego Bascom-Avr nie obsłujuje. Z Bascom-Avr generuję plik *HEX, ,a bezpośredni kontakt z prockiem ma tylko AVR Studio ,którym wgrywam hexa.

A jak miałeś ustawiony parametr Reload przy konfiguracji serw. Bo wiem tylko ,że parametr ten określa przerwę między sygnałami serw (ale w jakich jednostkach?).

Link do komentarza
Share on other sites

A możesz podać parametry czasowe serw którymi chcesz sterować, bo jak mieszczą w granicy do 1,6ms (max wychylenie) to da się spokojnie na jednym Timerze zrobić 11 serw.

A jak miałeś ustawiony parametr Reload przy konfiguracji serw.

Widzę ciężko poczytać HELPA w którym pisze:

Uwaga! Instrukcja konfiguruje także przerwania licznika TIMER0, dlatego też używanie tego licznika nie jest możliwe.

Dla przykładu instrukcja:

Config Servos = 2 , Servo1 = Portb.0 , Servo2 = Portb.1 , Reload = 10

spowoduje że:

· procedura przerwania będzie wywoływana co 10 µs i taka będzie podstawowa jednostka czasu - rozdzielczość,
· zostanie utworzona tablica nazwana SERVO() składająca się z dwóch komórek: SERVO(1) i SERVO(2).

Ustawiając odpowiednią wartość w jednej z komórek, kontrololujemy czas - w jednostkach określonych parametrem RELOAD - podawania stanu wysokiego na skojarzonej końcówce. Po upływie tego czasu końcówka zmieni swój stan na niski. Taka zmiana stanu - impulsy - powtarza się, a czas czas pomiędzy kolejnymi narastającymi zboczami wynosi około 20ms.

RELOAD jest w mikrosekundach, jeżeli ustawisz go na 10us, to jest to podstawa do obliczania czasu trwania impulsu. jeżeli teraz do tablicy SERVO wstawisz liczbę 100, to czas trwania impulsu to 10x100 = 1000us czyli 1 ms.

  • Lubię! 1
Link do komentarza
Share on other sites

BlackJack Czyli jeśli ustawię RELOAD na 10 to wartości odpowiadające skrajnym pozycją serwa będą oscylować gdzieś w granicach 100 i 200, bo 100 * 10us = 1ms i 200 * 10us = 2ms ?

A ten program to w końcu jest dobrze napisany , bo nie mogę na razie go przetestować ,gdyż procki są dopiero zamówione?

Link do komentarza
Share on other sites

Wg. opisu z HELPA tak powinno być. Natomiast tu może tkwić pewna pułapka, ponieważ standardowo czas powtarzania impulsów wynosi ok 20ms, to jeżeli MAX czas trwania impulsu dla jednego serwa wynosi 2ms, to maksymalna ilość serw wynosi 20/2 czyli 10szt. Inaczej nie zmieszczą się w 20ms ramce. Jednak wiele będzie zależeć od parametrów serw, czyli jakich impulsów wymagają. Konkretnie chodzi o czas impulsu do wychylenia MAX. jeżeli wynosi 2ms, to powinno dać się 10 serv obsłużyć, ale jak by był = 1,5ms to już da się ich uciągnąć 13.

Link do komentarza
Share on other sites

jeżeli teraz do tablicy SERVO wstawisz liczbę 100, to czas trwania impulsu to 10x100 = 1000us czyli 1 ms.

Co biorąc pod uwagę zachowanie serw i dokładność tej instrukcji nie sprawdza się w praktyce.

Link do komentarza
Share on other sites

Tak naprawdę to należało by funkcje Config Servo wziąźć pod lupę i rozebrać ją na części pierwsze, aby zobaczyć co naprawdę robi Reload. Ogólnie równie dobrze można by samemu napisać takową funkcję, filozofii wielkiej w tym nie ma

Natomiast BASCOM ma to do siebie ze niektóre funkcje są pisane pod konkretny zegar CPU, a nawet model procesora.

Link do komentarza
Share on other sites

Kupując rezonator kwarcowy znalazłem w ich parametrach pojemność albo przedział pojemności kondensatorów ,które mogą z nim współpracować, ale w mojej płytce testowej kondenstaory są wlutowane na stałe i mają inną pojemność niż mieć powinny (różnica 3pF). A więc muszę programować na płytce stykowej? Trochę mnie to martwi. Słyszałem ,że błędne podłączenie zasilania "mogłoby skończyć się źle" ,ale dla uC ,komputera czy programatora (wydaje mi się ,że dla uC)?

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.