logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Rozwiązano] Precyzyjny obrót ciągły - silnik krokowy NEMA 17 i DRV8825 na Arduino

futaba 02 Kwi 2020 19:29 1401 7
REKLAMA
  • #1 18582762
    futaba
    Poziom 10  
    Posty: 60
    Ocena: 17
    Dzień dobry wszystkim forumowiczom.
    Potrzebuję porady w temacie sterowania silnika krokowego przez Arduino. Skleiłem taki kawałek kodu (na podstawie znalezionych w sieci przykładów, bo programistą nie jestem):

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Kod ma za zadanie wywołać obrót ciągły sinika krokowego (NEMA 17, 200 kroków, wysterowany poprzez DRV8825 ) z dość precyzyjną prędkością. Chodzi mi o uzyskanie czasu jednego pełnego obrotu 2:57.231 (2 minuty i 57 sekund z haczykiem). Żeby uzyskać maksymalnie płynny obrót driver jest ustawiony na 1/32 kroku, czyli pełny obrót silnika z tego co rozumiem będzie miał 6400 kroków. Wartości 9000 w nawiasach są oczywiście tymczasowe, chciałem po prostu sprawdzić czy silnik ruszy. Ku mojej uciesze ruszył. I teraz najważniejsze pytanie - jak policzyć wartość do wstawienia w nawiasy, żeby silnik faktycznie obracał się tak jak potrzebuję. Wiem, że każda instrukcja w kodzie programu zajmuje jakiś czas procesora i to mnie właśnie zatrzymało. Niestety nie mam oscyloskopu, żeby precyzyjnie mierzyć obroty silnika. Będę bardzo wdzięczny za pomoc.

    Pozdrawiam
    Grzesiek
  • REKLAMA
  • Pomocny post
    #2 18583479
    ekrzychoooo

    Poziom 17  
    Posty: 280
    Pomógł: 24
    Ocena: 73
    Należy to zrobić na przerwaniach.
    Podział 1/32 akurat w tym wypadku nie będzie chyba dobry bo będzie trzeba odmierzać czas z dokładnością 50pikoSekund
    Przy podziale 1/1 to już "tylko" z dokładnością 5uS.
    Szukaj "arduino timer interrupt"
  • REKLAMA
  • Pomocny post
    #3 18583585
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • Pomocny post
    #4 18583779
    rb401
    Poziom 39  
    Posty: 3002
    Pomógł: 750
    Ocena: 984
    futaba napisał:
    I teraz najważniejsze pytanie - jak policzyć wartość do wstawienia w nawiasy, żeby silnik faktycznie obracał się tak jak potrzebuję.


    Obliczenie tego nie jest problemem ale generalnie ta metoda która próbujesz ma jedną wielką wadę.
    To że wyliczenie czasu dotyczy pojedynczego kroku i jakby tu nie kombinować opóźnienia w tej pętli, nawet uwzględniając opóźnienia wykonania instrukcji, istnieje praktycznie pewność że błędy zaokrągleń będą się akumulować i cały obrót wcale nie będzie trwał tyle ile wymagasz.
    Można próbować tak jak proponuje kolega ekrzychoooo, zejść na bardzo "drobnoziarniste" odliczenia czasu na przerwaniach, ale to trudna droga wymagająca wyjścia poza biblioteki Arduino na poziom sprzętowy.

    Ale jest możliwość realizacji odmierzania tych kroków, z użyciem wyłącznie prostych funkcji biblioteki Arduino, gdzie cały obrót, te 6400 kroków wykona się dokładnie w czasie tych 177,231 sekundy (dokładność będzie tylko zależna od dokładności rezonatora kwarcowego na płytce).
    Dokładniej chodzi o funkcję arduinową millis() (lub ewentualnie funkcję micros(), ale ogólnie zasada ta sama), która w sposób o wiele bardziej niezawodny pomaga odmierzać czasy w programie. Filozofię i zalety funkcji millis(), tłumaczy ładnie choćby ta strona:
    https://forbot.pl/blog/kurs-arduino-ii-wielozadaniowosc-opoznienia-z-millis-id18418

    Z tym że tu w Twoim projekcie występuje pewna dodatkowa trudność o czym pisał kolega ekrzychoooo. To że wyliczony z założeń krok silnika trwa 0,02769234375s, czyli nie da się prosto ustalić stałego czasu kroku, bo w istniejących realiach sprzętowych konieczne jest zaokrąglenie, co da nam zakumulowany błąd na czasie całego obrotu.
    Ale ten problem da się łatwo "przeskoczyć", godząc się na pewną nieregularność odstępów między krokami.
    Po prostu przy obliczaniu czasu następnego kroku (porównywanego później z wartością funkcji millis() ), nie używamy stałej wartości tylko liczymy ten czas każdorazowo z proporcji (obliczanej na liczbach całkowitych), która tak szkicowo przedstawię: następny_czas=startowy_czas+ (177231ms*numer_kroku/6400). Tu już widać gołym okiem że krok nr 6400 wykona się precyzyjnie po czasie 177,231s.

    Przykładowo, jeśli by użyć funkcji millis() to kroki wypadną w "pełnych" milisekundach, w postaci ciągu odległych od siebie powiedzmy o 27, 28, 28, 28, 27ms itd. gdzie odchylenie czasowe poszczególnych kroków od teoretycznej ściśle wyliczonej wartości wahało by się nie więcej niż milisekunda. Ale w skali całego obrotu, czy jakieś jego części precyzja była by stuprocentowa, tj ostatni krok dokładnie wykonał by się w 177,231 sekundzie od startu.

    Gdyby użyć funkcji micros() kroki były by jeszcze bardziej równomierne bo raster czasowy tej funkcji to 4µs choć może być trochę pogorszony czasami wykonania instrukcji.

    Ale tak patrząc praktycznie to też nie jestem pewien czy sam silnik przy sterowaniu 1/32 będzie miał aż tak wysoką precyzję kąta by taka nieregularność czasów przy rastrze milisekundowym była aż tak istotna. Ale po prostu nie wiem, A widzę że kolega emarcus jest bliższy tematyce praktycznego stosowania tych silników to ewentualnie oceni tą sprawę.

    W użyciu funkcji millis() (a micros() tym bardziej) występuje jeszcze problem, na który trzeba uważać, z przepełnieniem licznika milisekund po 50 dniach (o ile w ogóle konstrukcja ma działać non-stop tyle czasu), ale jest do przejścia. Tu tylko sygnalizuję, by nie zaciemniać tematu.
  • REKLAMA
  • #5 18584102
    futaba
    Poziom 10  
    Posty: 60
    Ocena: 17
    Dzięki Panowie za dużą garść informacji, teraz wiem już trochę więcej, a jak zapoznam się z zawartością Waszych linków, to pewnie dam radę dokończyć to w wersji mnie satysfakcjonującej.
    emarcus - z tym oscyloskopem to chodziło mi o możliwość mierzenia czasu trwania impulsu sterującego na cewkach i w ten sposób zmierzenie ile to tak naprawdę trwa, gdzieś coś takiego wygoglałem, co do zasilania silnika to mogę podać na cewki maksymalną wartość dopuszczaną przez driver, nie ma z tym najmniejszego problemu, silnik będzie obciążony stałym momentem, który jest kilkakrotnie mniejszy niż deklarowany katalogowy dla zastosowanego silnika, więc powinno się udać to zrobić z krokiem 1/32, zależny mi na większej rozdzielczości.
    rb401 - silnik w jednym cyklu ma się kręcić maksymalnie kilkadziesiąt minut, więc te 50 dni jest nieosiągalne :)
    Jeszcze raz dziękuje i zabieram się do pracy, czasu postało niewiele :)
    Pozdrawiam
    Grzesiek.
  • Pomocny post
    #6 18584947
    starob
    Poziom 29  
    Posty: 1088
    Pomógł: 128
    Ocena: 137
    rb401 napisał:
    To że wyliczony z założeń krok silnika trwa 0,02769234375s

    Co dale częstotliwość impulsów STEP :36,11106409149641Hz
    Proponuje podejście nieszablonowe.
    Czy nie prościej robić taki generator o stałej częstotliwości, a silnik na czas określony włączać ENABLE - albo włączać sam generator?
    Nie wiem czy da się taki generator sprzętowy ustawić?
  • Pomocny post
    #7 18586336
    rb401
    Poziom 39  
    Posty: 3002
    Pomógł: 750
    Ocena: 984
    starob napisał:
    Czy nie prościej robić taki generator o stałej częstotliwości, a silnik na czas określony włączać ENABLE - albo włączać sam generator?
    Nie wiem czy da się taki generator sprzętowy ustawić?


    Bardzo ciekawy sposób spojrzenia na problem. Bo tak w zasadzie, masz rację. Jak na informacje które są w wątku, to faktycznie, Arduino spełnia tu tylko i wyłącznie rolę zwykłego generatora, syntezującego żądaną częstotliwość w oparciu o kwarc którym taktowany jest mikrokontroler. A już logikę sterowania silnikiem załatwia układ na stepsticku.

    Tak nawet przymierzyłem standardowe częstotliwości pospolitych kwarców do prostych stopni podziału (2 do potęgi N), czy przypadkiem nie wyjdzie coś ekstremalnie prostego, ale nie udało się. Choć możliwe że trzeba by też poprzymierzać inne stopnie podziału i coś by się trafiło. Zresztą budowa takiego generatora to osobna już kwestia, bardziej do ogarnięcia przez zaawansowanego krótkofalowca, dla którego takie tematy to chleb powszedni.

    Bo i tak w kwestii dokładności czasu obrotu (którego wymaganej precyzji w tym projekcie nie znam), nawet gdy algorytm liczy dokładnie, zależy od taktowania na Arduino. A z tym jest różnie, a najgorzej chyba na oryginalnym (włoskim) Arduino UNO gdzie włożony jest rezonator ceramiczny o tolerancji 5000ppm !. To już w klonach jest lepiej bo są raczej głównie kwarce. A dla porównania, 1ms dopuszczalnego błędu na czasie pełnego obrotu, wymaga dokładności od kwarcu rzędu 5ppm.
  • #8 18808369
    futaba
    Poziom 10  
    Posty: 60
    Ocena: 17
    Znalazłem w sieci gotowy projekt i wszystko działa jak należy. Całość była mi potrzebna do napędu jednej osi w głowicy paralaktycznej do astrofotografii.

Podsumowanie tematu

✨ Dyskusja dotyczy sterowania silnikiem krokowym NEMA 17 za pomocą Arduino i sterownika DRV8825. Użytkownik poszukuje sposobu na uzyskanie precyzyjnego obrotu ciągłego, z czasem jednego pełnego obrotu wynoszącym 2:57.231. Odpowiedzi sugerują zastosowanie przerwań do dokładniejszego odmierzania czasu oraz zwracają uwagę na problemy związane z gubieniem kroków przy mikrostepowym wysterowaniu. Wskazano również na konieczność użycia enkodera do monitorowania rzeczywistego położenia wirnika. Użytkownik ostatecznie znalazł gotowy projekt, który spełnia jego wymagania.
REKLAMA