Spis treści
Skąd pomysł na projekt?
Kolejny rok, kolejne święta – w związku z tym musiałem wziąć udział w kolejnej edycji wydarzenia Reddit Gifts, które polega na anonimowej wymianie prezentów przez użytkowników serwisu Reddit. Niestety w tym roku miałem wymianę z osobami z Wielkiej Brytanii, a połączenie tej lokalizacji z Brexitem nie wyszło mi najlepiej (problemy z dostawami przesyłek, Eurotunelem, itd. – ale nie o tym w tym wpisie). Z tej okazji otrzymałem z brytyjskiego Amazona w prezencie „manipulator z linijek”, czyli MeArm Robot Classic Maker Kits. Niestety w najbiedniejszej wersji, więc bez żadnego sterowania – goła konstrukcja z serwomechanizmami FS90MG. I tutaj trzeba było coś wymyślić 😉
O projekcie
Trochę czasu mi zajęło, żeby znaleźć sposób na oprogramowanie ramienia. Na początku musiałem to niestety złożyć, czyli dużo odklejania folii i skręcania konstrukcji. Za późno też znalazłem wideo z całym procesem składania i trochę czasu przez to zmarnowałem. Ale po jakimś czasie konstrukcja była gotowa. Teraz brakowało tylko sterowania.
W sprawie sterowania na początku próbowałem pójść najłatwiejszą drogą, czyli znaleźć coś gotowego. Po przeszukaniu GitHub’a i nie znalezieniu niczego co mógłbym zrobić bez dodatkowych wydatków zrozumiałem, że muszę wziąć sprawy w swoje ręce. Na początku planowałem napisać coś na Arduino czy Rapsberry, ale z jednej strony byłby problem z zakupem potrzebnych sterownikiem serw a z drugiej z wykonaniem jakiegoś przyjemnego interfejsu do sterowania.
Dlatego skończyłem z tym co już w zeszłym roku do takich zadań poznałem, czyli oprogramowaniem TouchGFX, które generuje interfejsy graficzne dla mikrokontrolerów ST – połączenie elastycznego interfejsu graficznego dla ekranu dotykowego i możliwości mikrokontrolera ARM. Do projektu postanowiłem wykorzystać posiadaną przeze mnie płytkę STM32F429I-DISC1. Jest wyposażona w mikrokontroler STM32F429ZIT6 i rezystancyjny ekran dotykowy, a więc wszystko czego potrzebowałem do projektu.
Potem było już z górki. Opracowałem interfejs w TouchGFX, wygenerowałem potrzebne kody źródłowe, dokonałem ich edycji w oprogramowaniu STM32CubeIDE (dodając kody z inicjalizacją i konfiguracją timer’ów, DMA, itd. działające w oparciu o bibliotekę HAL), skompilowałem wszystko i voilà – ramię robota ożyło 🙂 Potem tylko kalibracja serw i hardware był gotowy. Byłem zdziwiony, że do sterowania serwomechanizmami wystarczy napięcie 2.92 V, a nawet 2.80 V (nie wiem czy moja płytka nie jest przypadkiem uszkodzona).
Film z działaniem można zobaczyć poniżej:
Kody źródłowe i schematy
Podsumowanie
Okazało się, że był to całkiem przyjemny projekt dla osoby, która nigdy wcześniej się takimi rzeczami nie zajmowała (czyli sterowaniem serwomechanizmami). W przyszłości przydałoby się zautomatyzować działanie ramienia, więc pewnie skończy się to na możliwości nagrania sekwencji kolejnych pozycji robota i jej powtarzania – ale to może jak będzie trochę więcej wolnego czasu 😉
Aktualizacja 14.04.2021 r.
Sequence recorder
Stało się to prędzej niż później – funkcja pozwalająca na nagrywanie sekwencji położeń ramienia gotowa! 🙂 Dzięki niej możliwe jest zapętlone powtarzanie zadanych pozycji. Poniżej przykład działania:
Jak to działa?
W oprogramowaniu TouchGFX opracowałem nowy ekran pozwalający na tworzenie sekwencji (opis okna i przycisków można znaleźć na GitHub’ie):
Zasada działania polega wyznaczeniu w głównym oknie pozycji robota, którą chcemy dodać do sekwencji, a następnie na ekranie sequenceScreen przyciskiem nr 6 dodajemy pozycję do przewijanej listy (nr 4). Czynności powtarzamy do momentu opracowania całej listy. Następnie możemy odtworzyć opracowaną sekwencję przyciskiem nr 7 (uruchamiany wtedy jest asynchroniczny wątek w systemie FreeRTOS odpowiedzialny za przesuwanie ramienia do właściwych pozycji).
Niestety w przypadku zresetowania mikrokontrolera tracona jest cała utworzona lista z powodu przechowywania jej tylko w pamięci RAM. Aby usunąć ten problem postanowiłem dodać zapisywanie listy oraz prędkości odtwarzania sekwencji do nieulotnej pamięci Flash (tej samej w której przechowywany jest mój program). Po analizie rozkładu pamięci Flash w oprogramowaniu STM32CubeIDE wybrałem do tego celu ostatni sektor mikroprocesora (23; nawet w połowie go nie zapełniam). Dodatkowo zabezpieczyłem się przed nadpisywaniem sektora przez linker poprzez zmniejszenie ilości dostępnej pamięci na program o wielkość sektora (128 KB).
Największym problemem była dynamiczna lista, której długość miała być zależna od ilości dodanych pozycji. Niestety po długim czasie kręcenia się w kółko zostałem uświadomiony, że mikrokontrolery nie żyją w zgodzie z dynamiczną alokacją pamięci jak pod klasycznymi systemami operacyjnymi. Ostatecznie skończyłem ze statycznym buforem dla tekstu wszystkich pozycji w liście oraz odpowiadającym im kontenerami positionContainer (czyli bufory oraz kontenery istnieją w pamięci programu przez cały okres jego życia, a w razie potrzeby wykorzystania po prostu edytowane są ich parametry, a następne dodawane do przewijanej listy). I tak bym musiał taką sytuację rozważyć jako najbardziej krytyczny przypadek, gdybym chciał korzystać z dynamicznej alokacji pamięci, więc nie jest to taki problem.
Do komunikacji między wątkami (interfejsu graficznego i sterowania pozycją ramienia) wykorzystuję zmienne bool’owskie klasy sequenceScreenView, które przekazują do funkcji handleTickEvent() polecenia odświeżenia listy pozycji lub obszaru tekstowego dotyczącego informowania użytkownika o stanie działania algorytmu.
Film przedstawiający ostateczną wersję projektu można obejrzeć poniżej:
Podsumowanie
Teraz opracowana aplikacja w końcu wydaje się kompletna 🙂 No i jak na Automatyka i Robotyka przystało w końcu mam własne skonstruowane przeze mnie ramię robota 🙂
W przyszłości może warto byłoby dodać jakieś przesyłanie komend z pozycjami ramienia przez UART/USB, podłączyć ramię do komputera/ESP32 i sterować nim poprzez sieć… Ale to może w jakiejś dalszej w przyszłości, bo pomysłów na projekty tylko przybywa, a trochę gorzej jest z ich realizacją 😉