Sterowanie robotem Astorino za pomocą smartfona
Kontakt w sprawie artykułu: Joanna Kowalkowska - 2025-09-09

Prezentujemy pracę, która zdobyła I miejsce w kategorii „Astorino. Poziom wyżej” w ramach konkursu „Astorino Film Festival”.
Praca powstała w Zespole Szkół Technicznych w Bytomiu, a jej autorami są uczniowie: Nikodem Nieckarz i Dawid Przewłocki.
1. Cel projektu
Celem projektu była nauka funkcji DRIVE, pętli WHILE, a także obsługi modułu wejść i wyjść Astorino z wykorzystaniem zewnętrznego mikrokontrolera, który miał możliwość obierania sygnałów poprzez moduł Bluetooth.
2. Opis Astorino
Ramię robota Astorino, wyposażone w precyzyjne silniki krokowe i czujniki pozycji, reaguje na polecenia z dokładnością i płynnością. Dzięki tej zaawansowanej integracji, Astorino może być używany do różnorodnych zadań, takich jak podnoszenie, przenoszenie lub precyzyjne pozycjonowanie przedmiotów.
Jednak jego funkcjonalność nie kończy się na podstawowych ruchach. Dodatkowe porty wejść i wyjść otwierają drzwi do szerszego spektrum możliwości, pozwalając na sterowanie robotem poprzez różne źródła zewnętrzne.
Jednym z tych źródeł sterowania jest mikrokontroler Arduino, którego wszechstronność pozwala użytkownikowi, za pomocą modułu Bluetooth, płynnie kierować jego sygnałami prosto z telefonu za pomocą aplikacji Bluetooth Electronics.
Wykorzystując w pełni potencjał sterowniczy mikrokontrolera Arduino oraz elastyczność programistyczną ramienia robota Astorino możemy stworzyć nowoczesny kontroler ramieniem robota, dostępny bezpośrednio na naszym telefonie.
3. Proces programowania
Podczas realizacji projektu natrafiliśmy na kilka problemów. Pierwszy pojawił się podczas fazy ,,projektowania” samych założeń sterowania, gdy zastanawialiśmy się, jak zrealizować dokładną zmianę położenia pozycji robota. Jednak udało nam się rozwiązać ten problem dzięki funkcji DRIVE, która pozwalała nam na dokładną zmianę współrzędnych pozycji robota, a także przez użycie funkcji WHILE, dzięki której program został zapętlony. Ostatnią barierą okazała się sama długość programu, gdyż jego pierwsza wersja okazała się być zbyt duża, na szczęście po uszczupleniu i modernizacji programu udało nam się zażegnać i ten problem.
4. Schematy
4.1. Schemat elektryczny (Użyty program: EasyEda)

4.2. Schemat pneumatyczny (Użyty program: FluidSim)

5. Programy
5.1. Program Arduino
void setup() // kod wykonywany po starcie arduino
{
Serial.begin(9600); //Ustawienie prędkości transmisji
pinMode(22, OUTPUT); // Konfiguracja pinu 22 jako wyjście
pinMode(23, OUTPUT); // Konfiguracja pinu 23 jako wyjście
pinMode(24, OUTPUT); // Konfiguracja pinu 24 jako wyjście
pinMode(25, OUTPUT); // Konfiguracja pinu 25 jako wyjście
pinMode(26, OUTPUT); // Konfiguracja pinu 26 jako wyjście
pinMode(27, OUTPUT); //Konfiguracja pinu 27 jako wyjście
pinMode(28, OUTPUT); // Konfiguracja pinu 28 jako wyjście
digitalWrite(22, HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23, HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24, HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25, HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26, HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27, HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28, HIGH); // Ustawienie stanu pinu 28 na wysoki
}
void loop() // kod wykonywany w pętli
{
if(Serial.available()>0) // sprawdzenie czy przychodzący bajt ma wartość >0
{
char odczyt = Serial.read(); // odczytanie przychodzącego bajtu
switch(odczyt) // odczytanie sygnału
{
case '1': // Przypadek, gdy sygnał jest równy “1”
digitalWrite(22,LOW); // Ustawienie stanu pinu 22 na niski
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
case '2': // Przypadek, gdy sygnał jest równy “2”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,LOW); // Ustawienie stanu pinu 23 na niski
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
case '3': // Przypadek, gdy sygnał jest równy “3”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,LOW); // Ustawienie stanu pinu 24 na niski
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
case '4': // Przypadek, gdy sygnał jest równy “4”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,LOW); // Ustawienie stanu pinu 25 na niski
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
case '5': // Przypadek, gdy sygnał jest równy “5”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,LOW); // Ustawienie stanu pinu 26 na niski
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
case '6': // Przypadek, gdy sygnał jest równy “6”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,LOW); // Ustawienie stanu pinu 27 na niski
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
case '7': // Przypadek, gdy sygnał jest równy “7”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,LOW); // Ustawienie stanu pinu 28 na niski
break; // Zakończenie funkcji przypadku
case '8': // Przypadek, gdy sygnał jest równy “8”
digitalWrite(22,LOW); // Ustawienie stanu pinu 22 na niski
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,LOW); // Ustawienie stanu pinu 28 na niski
break; // Zakończenie funkcji przypadku
Case '9': // Przypadek, gdy sygnał jest równy “9”
digitalWrite(22,LOW); // Ustawienie stanu pinu 22 na niski
digitalWrite(23,LOW); // Ustawienie stanu pinu 23 niski
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
case 'a': // Przypadek, gdy sygnał jest równy “a”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,LOW); // Ustawienie stanu pinu 23 na niski
digitalWrite(24,LOW); // Ustawienie stanu pinu 24 na niski
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
case 'b': // Przypadek, gdy sygnał jest równy “b”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,LOW); // Ustawienie stanu pinu 24 na niski
digitalWrite(25,LOW); // Ustawienie stanu pinu 25 na niski
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
case 'c': // Przypadek, gdy sygnał jest równy “c”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,LOW); // Ustawienie stanu pinu 25 na niski
digitalWrite(26,LOW); // Ustawienie stanu pinu 26 na niski
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 27 na wysoki
break; // Zakończenie funkcji przypadku
case 'd': // Przypadek, gdy sygnał jest równy k “d”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,LOW); // Ustawienie stanu pinu 26 na niski
digitalWrite(27,LOW); // Ustawienie stanu pinu 27 na niski
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
case 'e': // Przypadek, gdy sygnał jest równy “e”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,LOW); // Ustawienie stanu pinu 27 na niski
digitalWrite(28,LOW); // Ustawienie stanu pinu 28 na niski
break; // Zakończenie funkcji przypadku
case 'g': // Przypadek, gdy sygnał jest równy “g”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,LOW); // Ustawienie stanu pinu 22 na niski
digitalWrite(24,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(28,LOW); // Ustawienie stanu pinu 27 na niski
break; // Zakończenie funkcji przypadku
case 'i': // Przypadek, gdy sygnał jest równy “i”
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,LOW); // Ustawienie stanu pinu 24 na niski
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,LOW); // Ustawienie stanu pinu 26 na niski
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
default : // Wykonuje, gdy żadny sygnał z powyższych nie jest nadawany
digitalWrite(22,HIGH); // Ustawienie stanu pinu 22 na wysoki
digitalWrite(23,HIGH); // Ustawienie stanu pinu 23 na wysoki
digitalWrite(24,HIGH); // Ustawienie stanu pinu 24 na wysoki
digitalWrite(25,HIGH); // Ustawienie stanu pinu 25 na wysoki
digitalWrite(26,HIGH); // Ustawienie stanu pinu 26 na wysoki
digitalWrite(27,HIGH); // Ustawienie stanu pinu 27 na wysoki
digitalWrite(28,HIGH); // Ustawienie stanu pinu 28 na wysoki
break; // Zakończenie funkcji przypadku
} //koniec pętli odczytywania sygnału
Serial.println(odczyt); // Ukazanie wartości odczytanej w terminalu
} // Zakończenie sprawdzenia czy przychodzący bajt ma wartość >0
}
5.2. Program Astorino
y=0 // Ustawienie wartości y na “0”
WHILE (y==0) DO // Pętla while wykonuje się tylko w momencie spełnienia warunku y=0
twait 0.2 // Zatrzymanie programu na 0.2s
SIGNAL 2 // Ustawienie stanu pinu 2 na wysoki
WHILE (SIG(1002)) == TRUE AND (SIG(1003)) == FALSE AND (SIG(1008)) == FALSE DO //pętla wywołana sygnałem na wejściu 2 jeżeli nie ma sygnału na 3 oraz 8 wejściu
DRIVE 1,-10,100 // Poruszenie osią JT1 o -10o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1003)) == TRUE AND (SIG(1002)) == FALSE AND (SIG(1004)) == FALSE AND (SIG(1008)) == FALSE DO //pętla wywołana sygnałem na wejściu 3 jeżeli nie ma sygnału na 2 oraz 3 wejściu
DRIVE 1,10,100 // Poruszenie osią JT1 o 10o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1004)) == TRUE AND (SIG(1003)) == FALSE AND (SIG(1005)) == FALSE AND (SIG(1006)) == FALSE DO //pętla wywołana sygnałem na wejściu 4 jeżeli nie ma sygnału na 3 oraz 5 wejściu
DRIVE 2,-5,100 // Poruszenie osią JT2 o -5o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1005)) == TRUE AND (SIG(1004)) == FALSE AND (SIG(1006)) == FALSE DO //pętla wywołana sygnałem na wejściu 5 jeżeli nie ma sygnału na 4 oraz 6 wejściu
DRIVE 2,5,100 // Poruszenie osią JT2 o 5o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1006)) == TRUE AND (SIG(1005)) == FALSE AND (SIG(1007)) == FALSE AND (SIG(1004)) == FALSE DO //pętla wywołana sygnałem na wejściu 6 jeżeli nie ma sygnału na 7 oraz 5 wejściu
DRIVE 3,-5,100 // Poruszenie osią JT3 o -5o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1007)) == TRUE AND (SIG(1006)) == FALSE AND (SIG(1008)) == FALSE DO //pętla wywołana sygnałem na wejściu 7 jeżeli nie ma sygnału na 6 oraz 8 wejściu
DRIVE 3,5,100 // Poruszenie osią JT3 o 5o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1008)) == TRUE AND (SIG(1002)) == FALSE AND (SIG(1007)) == FALSE AND (SIG(1003)) == FALSE DO //pętla wywołana sygnałem na wejściu 8 jeżeli nie ma sygnału na 2 , 3 oraz 7 wejściu
DRIVE 4,-5,100 // Poruszenie osią JT4 o -5o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1008)) == TRUE AND (SIG(1002)) == TRUE DO //pętla wywołana sygnałem na wejściu 8 oraz 2
DRIVE 4,5,100 // Poruszenie osią JT4 o 5o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1002)) == TRUE AND (SIG(1003)) == TRUE DO //pętla wywołana sygnałem na wejściu 2 oraz 3
DRIVE 5,-5,100 // Poruszenie osią JT5 o -5o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1003)) == TRUE AND (SIG(1004)) == TRUE DO //pętla wywołana sygnałem na wejściu 3 oraz 4
DRIVE 5,5,100 // Poruszenie osią JT5 o 5o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1004)) == TRUE AND (SIG(1005)) == TRUE DO //pętla wywołana sygnałem na wejściu 4 oraz 5
DRIVE 6,-5,100 // Poruszenie osią JT6 o -5o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1005)) == TRUE AND (SIG(1006)) == TRUE DO //pętla wywołana sygnałem na wejściu 5 oraz 6
DRIVE 6,5,100 // Poruszenie osią JT6 o 5o z prędkością 100%
END // Zakończenie pętli while
WHILE (SIG(1006)) == TRUE AND (SIG(1007)) == TRUE DO //pętla wywołana sygnałem na wejściu 6 oraz 7
Signal –1 // Ustawienie stanu pinu 1 na niski
END // Zakończenie pętli while
WHILE (SIG(1007)) == TRUE AND (SIG(1008)) == TRUE DO //pętla wywołana sygnałem na wejściu 7 oraz 8
Signal 1 // Ustawienie stanu pinu 1 na wysoki
END // Zakończenie pętli while
WHILE (SIG(1003)) == TRUE AND (SIG(1008)) == TRUE DO 0 //pętla wywołana sygnałem na wejściu 3 oraz 8
HOME // Powrót ramienia robota do pozycji wejściowej
END // Zakończenie pętli while
WHILE (SIG(1006)) == TRUE AND (SIG(1004)) == TRUE DO
SIGNAL -2 // Ustawienie stanu pinu 2 na niski
END // Zakończenie pętli while
END // Zakończenie pętli loop
.END // Zakończenie programu
6. Spis elementów
Elementy elektryczne:
- Arduino Mega 2560.
- 8 Przekaźników 5V DC.
- Przekaźnik 24V DC.
- Moduł bluetooth HC-05.
- Zestaw przewodów.
Elementy pneumatyczne:
- Sprężarka.
- Zawór 3/2 normalnie otwarty.
- Siłownik jednostronnego działania pchający ze sprężyną powrotną.
- Zespół przygotowania powietrza.
- Zawór zwrotno-dławiący.
7. Zastosowanie
- Przenoszenie ciężkich, a także niebezpiecznych dla człowieka obiektów.
- Nauka o osiach kinematycznych robota.
- Maszyny służące do celów rekreacyjnych.
8. Korzyści
Dzięki realizacji projektu zdobyliśmy doświadczenie w tworzeniu programów Astorino bazujących na przesyłaniu sygnałów poprzez,
używania modułu bluetooth jako odbiornika a także przesuwaniu dowolnej osi robota o dokładną ilość stopni dzięki funkcji DRIVE a także programów stosujących pętlę While .
9. Zespół
Autorzy pracy:

Nikodem Nieckarz

Dawid Przewłocki