Wracamy do huśtawki z nowym podejściem – sterowaniem z wykorzystaniem PID-a. Niestety, konstrukcja mechaniczna uniemożliwiła poprawną pracę układu… trzeba ponownie popracować nad mocowaniem ramienia łączącego serwo z pierścieniem rury.
Warto przeczytać ten artykulik ze wprowadzeniem do PID-a:
Mamy Nowy Rok 2022 i pierwsze spotkanie Koła Fi-BOT. Fajnie, że studenci pracują pomimo przerwy świątecznej, bo wyniki są bardzo ciekawe!
Pan Stanisław uparł się na dopracowaniu konstrukcji mechanicznej oraz oprogramowania. Sam nie wiem, co było bardziej marudne… Przypomnę na czym polega zabawa w huśtawkę – należy tak sterować położeniem rury (góra/dół – tym zajmuje się serwosilniczek), aby kulka znajdująca się wewnątrz znalazła się w środku rury. To dość znane zagadnienie, ale Pan Stanisław podszedł do tego niestandardowo – zastosował wzorki z fizyki dla zsuwającej się kulki z równi pochyłej (z uwzględnieniem jej obrotów, czyli mechanik bryły sztywnej). Nie ma tu żadnego PID-a, tylko czystka fizyka! Czy to działa? Działa! o dziwo – jak dla mnie – bo myślałem, że taki sposób spowoduje ciągłe bujanie piłki w lewo i w prawo. A tu proszę! Gratulacje! Ze względu na zbliżającą się sesję egzaminacyjną opis rozwiązania zostanie dodany gdzieś w miesiącu luty (po sesji).
W międzyczasie Pan Bartek kombinuje z produkcją płytek PCB na hobbystycznej frezarce CNC, a Pan Dominik wymyślił bardzo nieszablonowy sposób poruszania huśtawką (warto go zrealizować! choć będzie trzeba popracować mechanicznie).
Fajnie, że właśnie tak rozpoczął się Nowy Rok na Fi-BOTcie!
Poniedziałek to nie dzień spotkań koła, ale kto chętny – może! I tak Pan Stanisław postanowił wykorzystać okienko w swoich zajęciach i przystąpił do ulepszania konstrukcji…
Konstrukcja „buja” się już mniej, pomimo zastąpienia trytytek sztywną wykałaczką 😉 Liczy się pomysłowość! Dalej są spore luzy, bo otwory w obejmie są za duże w stosunku do grubości wykałaczki. Wybór wykałaczki nie jest jednak przypadkowy – idealnie rozmiarami pasuje do otworów w metalowych (oryginalnych) profilach Maker Beama (podwieszenie w górnej części konstrukcji).
Na uwagę zasługuje pierwsza próba łączenia serwa z obejmą rury – wykorzystano gruby, małoplastyczny pręcik. Te dwie jego cechy są tutaj jego zaletami – tworzy on bowiem sztywne połączenie. Były problemy przy jego wyginaniu i przetykaniu przez otwory, ale co tam. Jest pierwsze podejście. Czy działa? Filmik poniżej:
Działa to zdecydowanie gorzej niż się spodziewaliśmy 😛 Wszędzie te luzy! No i nogi (płozy?) zdecydowanie za krótkie (i za lekkie, trzeba dociążyć). W międzyczasie pojawił się Pan Bartek i zaproponował wymianę pianki (w mocowaniu serwa) na coś sztywniejszego… korek! Sam się zdziwiłem, że to Pan Bartek zaproponował! Wersja 2 i pół po lekkiej modyfikacji:
Jednak to niewiele pomogło… Pan Bartek skrzywił się tylko, spytał o średnicę rury i chyba postanowił przygotować nowy projekt w 3D aby przyspieszyć pracę nad projektem 😉 Zobaczymy!
Studenci dzielnie pracują nad projektem sterowanej huśtawki (samopoziomującej się). Schemat układu z poprzedniego tygodnia:
A tera pierwsze próby jego wykonania „w realu”:
Jednak wszystko się „buja” 😛 Roboczo wykorzystane trytytki powodują duże luzy w obu osiach, a dalej niejasny jest sposób połączenia orczyka serwa z drugim pierścieniem obejmującym rurę. Coś tu trzeba wymyślić (wydrukować?).
Już wiemy, do czego zmierzamy w tym semestrze – będziemy stabilizować huśtawkę! Projekt bardzo ciekawy i w zasięgu ręki każdego początkującego hobbysty. O co chodzi? Na huśtawce poruszać się będzie kulka (różowa na rysunku poniżej), która zmieniając swoje położenie przechyli huśtawkę w inne położenie. Ale jest też silniczek (zielony), którym będzie sterować Arduino UNO (pomarańczowe) tak, by kulka nie wypadła z huśtawki i pozostawała w środku (położeniu równowagi).
musimy określać położenie kulki na huśtawce – wykorzystamy poznany tydzień temu czujnik odległości HC-SR04
przechylanie huśtawki: mikroserwo powinno wystarczyć, ale jeśli okaże się za słabe – to mamy też serwa.
Huśtawka z pleksi rury.
Pan Stanisław tak się zaangażował w projekt, że zakupił już element konstrukcyjny huśtawki – rurę (ładna! długa: 50cm, ale gruba, bo ścianki 3mm, no i droga…). Pomysł fajny, ale czy czujnik odległości na końcu takiej rury będzie dobrze wskazywać pomiary odległości? W końcu emituje on dźwięki, które będą „buszować” w zamkniętej rurze i kolejne pomiary mogą być bezsensowne. Dlatego trzeba było to sprawdzić.
Na nasze szczęście okazało się, że (o dziwo!) czujnik działa poprawnie! Sprawdziliśmy to z wykorzystaniem metrówek.
Silniczek – a dokładniej mikro serwo.
Proponuję wykorzystać mikro serwo do poruszania ramieniem huśtawki. Jest to silnik sterowany sygnałem PWM, który możemy ustawić w określonej pozycji: od 0 (zera) do 180 stopni. Do obracającego się orczyka przyczepimy element łączący go z ramieniem huśtawki.
W tym konkretnym przypadku możemy podłączyć zasilanie serwa bezpośrednio do płytki Arduino UNO, bo pojedyncze serwo pożera jedynie ~200mA prądu (nie możemy przekraczać 500mA, bo uszkodzimy Arduino lub podłączonego z nim kompa – a tego nie chcemy).
Programowanie polega na użyciu biblioteki Servo.h i znajdującego się w niej obiektu Servo. Tworzymy zmienną (u nas silnik) i przypisujemy jej sterowanie do pinu 9 – metoda attach(). Następnie ustawiamy ramię silnika na określoną pozycję – tutaj 5, 90 i 175 stopni – za pomocą metody write(). Celowo pomijam skrajne wartości 0 i 180 stopni, bo to nadwyręża serwa.
Zwracam także uwagę, że po ustawieniu serwa na konkretną wartość należy dać mu czas na realizację tego polecenia – serwa działają powoli! Nasze MG90S obraca się o 60 stopni w 0,1 sekundy – dlatego 2s opóźnienie przed kolejnym ustawieniem to rozsądna wartość.
Budowa konstrukcji.
I tu zaczynają się schody… Trzeba się trochę pobrudzić 😉 Może sklejka lub podobny, miękki materiał – łatwy do obróbki bez zaawansowanego osprzętu? A może wspomniane profile Maker Beam?
Jeszcze zobaczymy co zrobimy, ale najpierw trzeba przemyśleć połączenie silniczka z ramieniem huśtawki. Są różne koncepcje. Poniżej wynik prac przy tablicy….
Trzymak do rury.
Aby złapać rurę (huśtawkę) i przytwierdzić ją do stabilnej konstrukcji – trzeba mieć odpowiedni uchwyt. Pewnie można poszukać w jakimś popularnym sklepie z materiałami budowlanymi, ale postanowiłem lekko pomóc i zaprojektowałem na szybko taki uchwyt – poniżej zdjęcie jego połówki, bo właśnie dwie takie części tworzą całość. Uchwyt ma sporo nadmiarowych „uniwersalnych” otworów – tak na przyszłość, aby nie tylko pełnił funkcję trzymania rury i obracania jej, ale i mechanizmu połączenia z silniczkiem… Powinno się przydać.
Jak widać sporo się działo… a to dopiero początek tego projektu 😉
Poznajemy ultradźwiękowy czujnik odległości – układ HC-SR04. Emituje on fale dźwiękowe o częstotliwości 40 kHz (czyli spoza zakresu słyszalności człowieka) i czeka na jej powrót. Mierząc czas nadejścia tej informacji (powrotnej) znamy odległość do obiektu, od którego odbiła się fala dźwiękowa (a właściwie 2x odległość, bo fala pokonała drogę w jedną stronę i z powrotem).
Działanie układu odbywa się zgodnie z następującym protokołem (schematem):
włączamy TRIG (stan wysoki =5V) na 10 us aby uruchomić procedurę wyemitowania dźwięku (8 impulsów 40 kHz);
wyłączamy TRIG (stan niski =0V), pin ECHO przechodzi w stan wysoki i zmieni go na niski, gdy sygnał wróci (a jeśli nie wróci, ECHO zmieni się po czasie 38 ms);
mierzymy czas trwania sygnału wysokiego na pinie ECHO – znając ten czas i zakładając prędkość dźwięku 340 m/s mamy już odległość do obiektu.
Pierwszy programik wykorzystuje funkcję pulseIn() w celu określenia długości trwania sygnału HIGH na pinie ECHO.
Nie jestem wielkim zwolennikiem funkcji pulseIn() – choć działa bardzo dobrze. Do odczytu stanu pinów służy funkcja digitalRead(), którą trzeba tylko odpowiednio „zapętlić” — poniższy kod właśnie to realizuje. Wykorzystujemy też funkcję mierzenia czasu działania Arduino w mikrosekundach (czyli w 1/1000 milisekund!) czyli funkcji micros(). Oto i kod:
#define TRIG 8
#define ECHO 7
unsigned int t1,t2;
byte aaa;
void setup() {
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(TRIG, 0);
delayMicroseconds(5);
digitalWrite(TRIG, 1);
delayMicroseconds(10);
digitalWrite(TRIG, 0);
//czekanie na przelaczenie pinu ECHO w stan HIGH... wszak nic nie dzieje sie natychmiast!
while (digitalRead(ECHO) == LOW);
t1=micros();
while ((aaa=digitalRead(ECHO)) == HIGH);// Serial.println(aaa);
t2=micros()-t1;
Serial.print(t2);
Serial.print(", ");
Serial.print(t2/58.0);
Serial.println(" [cm]");
delay(100);
}
Dwie rzeczy wymagają wyjaśnienia: 1) Pętle while kończą się średnikiem – czyli pętla nie wykonuje nic! od razu wraca do sprawdzenia warunku kontynuowania pętli – tak szybko, jak się da; nie ma strat czasu na wypisywanie rzeczy, na jakieś obliczenia…. 2) czekamy na ustawienie pinu ECHO w stan HIGH tak długo, jak czujnik SR_HC04 to zrobi (bo choć protokół o tym właśnie mówi, to nic nie dzieje się natychmiast – nawet światło ma skończoną prędkość); dlatego pojawiła się pętla trwająca tak długo, aż stan pinu ECHO jest LOW. Po tej pętli mamy pewność, że ECHO jest już HIGH i uruchamiamy „stoper” (zapisujemy aktualną wartość mikrosekund) do zmiennej t1. Teraz ponownie zapętlamy program aż stan pinu ECHO zmieni się na LOW – to sygnalizuje powrót sygnału do układu. Ta pętla posługuje się pomocniczą zmienną aaa (ale beznadziejna nazwa) zapisującą stan pinu ECHO – niby niepotrzebnie, ale można odkomentować następną linię i będziemy widzieć jej wartość. To kolejna mała rzecz wymagająca komentarza. Po tej pętli ponownie zapisujemy „stoper” – czyli aktualną wartość mikrosekund, tworząc zmienną t2 równą różnicy zatrzymanego czasu i wartości t1… Zmienna t2 ma teraz dokładnie takie samo znaczenie jak w pierwszym przykładzie (programie) i dalsza część pozostaje niezmieniona.
Które rozwiązanie lepsze? W przypadku jednego czujnika pewnie pierwsze jest fajniejsze, ale gdy mamy więcej czujek działających jednocześnie? Wówczas rozwiązanie z pulseIn() nie zagra, bo zatrzyma wykonanie programu i nie pozwoli na wykrycie sygnału wracającego do innego czujnika – czyli popsuje wyniki dla drugiego, trzeciego czujnika. Drugie rozwiązanie można łatwo rozbudować do współpracy z wieloma czujnikami (np. wprowadzając zmienne t2, t3, t4… ) mierzące czas powrotu sygnału z kolejnych czujek. Ale nie upieram się nad wyższością jednego nad drugim. Mi bardziej pasuje funkcja digitalRead() i dlatego wolę drugi programik. Warto na koniec wspomnieć, że jest dedykowana biblioteka do obsługi układu SR-HC04 (gdzie? poszukaj!) i wiem, że świetnie nadaje się do obsługi wielu czujników.