Skocz do zawartości

Zwiększenie dokładnosci pomiarów ADC, większa precyzja potencjometru.


Rayu85

Pomocna odpowiedź

Witam, buduję ramię robota, i jestem na etapie programowania sterowania.

W tej chwili korzystam z joysticka kupionego w botlandzie.

Serwo cyfrowe PowerHD LF-20MG standard.

Zasada działania standardowa:

1) odczytujemy wartość z potencjometru na wejściu ADC

2) Mapujemy ją w zakresie 0-180 (zakres pracy serwa)

załączam fragment kodu:

x = analogRead(A0);
x = map(x, 0, 1023, 0, 180);
servo_1.write(x);

Wszystko działa ale robot jest strasznie "narwany" jego ruchy są bardzo szybkie, agresywne, przez co mało precyzyjne i trudne do wykonywania.

Dodam, że serwa nie drżą, nie wykonują samowolnych ruchów itd.

Po prostu delikatnym wychyleniem drążka ramię wykonuje bardzo duży ruch.

Obserwując wskazania na monitorze zauważam, że wykonując ruch joystickiem dosłownie o 1-2mm zmienia się położenie serwa aż o ok 20-30 stopni.

Chciałbym jakoś dopracować tą płynność ruchów.

Pierwsza myśl jaka mi przychodzi to większy zakres niż 0-1023 ale z tego co wyczytałem z Andurio Uno nie uzyskamy więcej bo przetworniki ADC są 10 bitowe.

Czy istnieje jakaś metoda upłynniania ruchów takiego robota na etapie programowania?

Może istnieje jakiś algorytm który sztucznie zwiększa ten zakres 0-1023?

Z góry dziękuję za pomoc:)

Link do komentarza
Share on other sites

Nie wiem czy moja rada będzie Ci odpowiadać, ale miałem do czynienia z różnymi urządzeniami zrobotyzowanymi i CNC i tam zauważyłem pewną prawidłowość. Sterowanie ręczne ZAWSZE jest wykonywane jako sterowanie prędkością ruchu danej osi. Może dobrze byłoby pójść w tym kierunku? Bo w tym przypadku, który opisujesz faktycznie mapowanie całego zakresu serwa na potencjometr nigdy nie będzie precyzyjne ani łagodne.

Link do komentarza
Share on other sites

Jak masz możliwość wyrzucenia wyników do komputera i tam obserwowania to zacznij od tego i sprawdź przy jakim wychyleniu jakie masz wartości ADC.

Możliwe, że ten joystick tak łapie i tyle - wtedy sugerowałbym pomyśleć o innym joysticku -, ale najlepiej pokaż też schemat jego podłączenia.

Jedno co możesz zrobić programowo to pomyśleć o nieliniowej zmianie wychylenia serwa w zależności od wartości ADC.

Optymalnie byłoby zrobić tablicę 1024 wartości przeliczaną na wychylenie serwa, ale w uproszczeniu możesz to zrobić w ten sposób:

(kodu nie sprawdzałem, arduino nie znam)

   x = analogRead(A0);
   if (x<200) x = map(x, 0, 200, 0, 60);
   else if (x>820) x = map(x, 820, 1023, 120, 180);
   else x = map(x, 200, 820, 60, 120);
   servo_1.write(x);
Link do komentarza
Share on other sites

Po co chcesz zwiększać zakres ADC powyżej 0-1023, skoro sam go brutalnie funkcją map zmniejszasz do 0-180? Przecież map() działa na liczbach całkowitych i zaokrągla wynik. Dużo lepszą rozdzielczość dostaniesz, jeśli użyjesz funkcji writeMicroseconds() zamiast write(), ona daje ci większą rozdzielczość niż 1 stopień.

Po drugie, zastanów się, czy chcesz cały obrót potencjometru mapować na cały zakres 180° ruchu serwa. Nie wiem gdzie to serwo masz zamontowane, ale być może rozsądny zakres jego ruchu jest mniejszy, bardziej w okolicach 90°.

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

Wasze sugestie są interesujące i przetestuje jaki dadzą rezultat.

deshipu mam pytanie, bo piszesz że funkcja map ogranicza do liczb całkowitych więc zakładam ze sugerujesz aby z niej zrezygnować.

Ale dane odczytane z ADC muszę w jakiś sposób i tak "przetłumaczyć" na zakres od 0-180 (przyjmując pełen zakres - choć przyznaję rację że nie potrzebuję pełnego zakresu więc pewnie go odrobinę okroję). Jaka funkcja w takim razie mapuje na liczby niecałkowite?

Czy naprawdę serwo jest w stanie osiągnąć dokładność do dziesiątych stopnia?

Serwo jest cyfrowe i nie jest to najtańsze z dostępnych a mam wrażenie że dokładność jest w granicy 5 stopni.

W każdym razie sterując nim z konsoli podając wartość np.70 a następnie 72 stopnie nie widzę żeby w ogóle się przemieszczało. Dopiero po podaniu wartości większej o 5 widzę minimalny ruch.

Choć może to wynikać z tego że ruch jest tak minimalny że praktycznie niewidoczny.

Natomiast co do schematu podłączenia joysticka to chyba najprościej jak się da więc nie będę rysować nawet, GND i zasilanie 5V do pinów w andurio piny VRX oraz VRY do A0 oraz A1 w andurio.

Link do komentarza
Share on other sites

Niestety tutaj wszystko rozbija się o jakość joya. Te maluchy sprzedawane na kawałku płytki mają kiepską mechanikę a to - przy bardzo krótkiej ścieżce potencjometru - daje słabo powtarzalne wyniki. Co gorsza, rzeczywiście "obsługiwany" przez potencjometry zakres ruchu w obu płaszczyznach jest zwykle jakieś 2x krótszy niż możliwe wychylenie sticka do oporu. Po zamontowaniu go w obudowie i obsłudze kciukiem taki krótki ruch wystarcza, ale gdy urządzenie jest "luzem" to obie osie są bardzo czułe. Nawet położenie neutralne raczej nigdy nie jest (512, 512) i zmienia się o kilka jednostek w zależności od tego z której strony joy wracał do zera.

Najlepszym pomysłem jest to co zaproponował Kolega DonQuijote88 a więc program w którym joystick odpowiada za prędkość serwa a nie za jego bezwzględne położenie. Wtedy sama pozycja serwa jest całką prędkości i jako taka jest z definicji uśredniona. Wygładzane są więc wszelkie dziwne wyskoki joysticka, pomiarów lub naszej ręki.

Wystarczy, że zrobisz sobie zmienną "pozycja_serwa" i będziesz w kółko do niej dodawał co stały odcinek czasu (np. co 100ms) zmienną "krok". Jeśli teraz wielkość (i znak) kroku uzależnisz wprost od pozycji joysticka, masz regulację prędkości 🙂 Zmienna "krok" musi oczywiście zmieniać się od wartości ujemnych do dodatnich, bo prędkość serwa także ma dwa kierunki. Nie zapomnij o sprawdzaniu wartości granicznych zmiennej "pozycja_serwa" żeby biednemu silniczkowi nie ukręcić trybów. Warto też zrobić jakąś strefę nieczułości wokół pozycji neutralnej (np. +/- 5 lub 10 jednostek ADC), żeby puszczając joystick mieć pewność, że krok (czyli prędkość serwa) jest wtedy = 0.

Serwa także mają "strefę martwą" (dead zone) wokół aktualnego położenia, z której nie ruszą się jeśli wysterowanie PPM nie wyjdzie poza nią. To zabezpiecza przed ciągłymi, mikroskopijnymi ruchami zużywającymi silnik, potencjometr, tryby i prąd a wynikającymi choćby z niedokładności pomiarów przychodzących impulsów sterujących.

Link do komentarza
Share on other sites

Pomysł z joystickiem sterującym prędkością faktycznie wydaje się być dość prostym i dobrym rozwiązaniem.

Postaram się napisać wersję obsługi prędkością, klasyczną ale o większej rozdzielczości oraz wykorzystać nieliniową zmianę wychylenia, zobaczymy która metoda da najlepszy rezultat.

marek1707 niestety co do joysticka muszę przyznać Ci rację, mi też się rzuciło w oczy od razu że joystick na osiąga maksymalną wartość sporo przed końcem wychylenia.

Link do komentarza
Share on other sites

Wasze sugestie są interesujące i przetestuje jaki dadzą rezultat.

deshipu mam pytanie, bo piszesz że funkcja map ogranicza do liczb całkowitych więc zakładam ze sugerujesz aby z niej zrezygnować.

Ale dane odczytane z ADC muszę w jakiś sposób i tak "przetłumaczyć" na zakres od 0-180 (przyjmując pełen zakres - choć przyznaję rację że nie potrzebuję pełnego zakresu więc pewnie go odrobinę okroję). Jaka funkcja w takim razie mapuje na liczby niecałkowite?

Czy naprawdę serwo jest w stanie osiągnąć dokładność do dziesiątych stopnia?

Serwo jest cyfrowe i nie jest to najtańsze z dostępnych a mam wrażenie że dokładność jest w granicy 5 stopni.

W każdym razie sterując nim z konsoli podając wartość np.70 a następnie 72 stopnie nie widzę żeby w ogóle się przemieszczało. Dopiero po podaniu wartości większej o 5 widzę minimalny ruch.

Choć może to wynikać z tego że ruch jest tak minimalny że praktycznie niewidoczny.

Natomiast co do schematu podłączenia joysticka to chyba najprościej jak się da więc nie będę rysować nawet, GND i zasilanie 5V do pinów w andurio piny VRX oraz VRY do A0 oraz A1 w andurio.

Rozdzielczość serw analogowych nie jest w zasadzie ograniczona -- tam jest w środku prosty komparator, który porównuje sygnał, który mu dajesz, do sygnału, jaki sobie generuje z pozycji potencjometru. Cyfrowe serwa symulują to samo i robią to z dość dużą rozdzielczośćią -- na pewno większą niż 5°. To co widzisz, to efekt działania martwej strefy (dead band), która zapobiega ciągłemu drżeniu serwa -- poruszy się dopiero wtedy, gdy sygnał odbiegnie od aktualnej pozycji wystarczająco mocno. Co nie znaczy, że pozycji końcowej nie możesz mu zadać bardzo dokładnie.

Co do rezygnowania z funkcji map(), to gdzie ja coś takiego napisałem? Może przeczytaj jeszcze raz, a potem jeszcze przeczytaj dokumentację do funkcji write() i writeMicroseconds(). Spokojnie powinieneś uzyskać rozdzielczość sygnału PWM podawanego do serwa co najmniej w okolicach 4µs, to to się przekłada na jakieś pół stopnia.

Link do komentarza
Share on other sites

Co do rezygnowania z funkcji map(), to gdzie ja coś takiego napisałem?

nie napisałeś tego ale ja też tego nie twierdzę 🙂 Tak jak napisałem zakładałem, że to miałeś na myśli ale pomyliłem się.

Z martwą strefą i braku ruchu przy małych zmianach wiem już o co chodzi, i dlaczego się tak dzieje:) czy raczej dlaczego nic się nie dzieje 🙂

Myślę, że podsunęliście mi kilka ciekawych rozwiązań i wyjaśniliście niejasności. Teraz czas na odrobinę pracy i zobaczymy jakie da to efekty:)

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.