Podstawy: odczyt analogowy – moduł JOY + wieżyczka

Podstawy Arduino

Poznajemy funckję analogRead() – podłączamy potencjometr i sprawdzamy odczyty napięcia (porównujemy ze wskazaniami multimetru). Natrafiliśmy na „pułapkę informatyka”: dzielenie całkowite! W celu odczytania wartości napięcia nie można było napisać analogRead(A0)*5/1024, zamiast tego należało rzutować typy lub wymuisić obliczenia w arytmetyce liczb rzeczywistej, przez napisanie liczby 5 jako liczba rzeczywista: analogRead(A0)*5.0/1024. Teraz już wszystko działa, więc podłączamy dwa potencjometry ale… w module popularnej gałki JOY-sticka:

Moduł gałki JOY-a (czyli dwa potencjometry).

Moduł wykorzystaliśmy do rozbudowy zabawy z mikroserwami z poprzenich zajęć – tym razem mamy do dyspozycji wieżyczkę sterowanych dwoma mikrosilniczkami.

Wieżyczka sterowana JOY-em.
Należy podkreślić, że zasilanie dwóch takich silniczków bezpośrednio z Arduino nie jest mądrym pomysłem, dlatego warto użyć zewnętrznego zasilania.

Maskotka

Prace trwają: BB z PP rozkładają pojazd i montują profesjonalne uchwyty montażowe do zasilania 😉

Wydrukowane „trzymaki” do akumulatora (oczywiście autorstwa BB).
Trzymaki w akcji 😉

Widać, że podwozie Maskotki nadaje się już do wymiany – paskudne te otwory… Wynika to z różnych koncepcji systemu kół, które wymusiły docinanie otworów „na szybko”. Kolejnym krokiem będzie przygotowanie nowej płyty…

PID oraz podstawy: PWM + (mikro)serwo

Podstawy Arduino

Piny cyfrowe PWM z multimetrem i LED-em, a potem serwosilniczek (Serwo.h, silnik.attache(pin), silnik.write(stopnie).

Maskotka

BB: regulator PID dla 1 koła: poniżej wynik działania algorytmu regulującego pracę silnika: kolor czerwony to krzywa pożądana (nastaw użytkownika, potencjometrem), kolor niebieski to aktualna praca koła. Oś Y na wykresie to RPS, czyli obroty na sekundę.

Praca regulatora PID ma polegać na tym, że RPS koła ma podążać za ustaloną wartością niezależnie od zewnętrznych czynników (np. koło na lodzie=kręci się praktycznie bez oporów, lub koło w błocie =ciężko mu wyjechać). Najważniejsze współczynniki regulatora PID Pab bartek dobrał metodą „prób i błędów” (plus własne, wcześniejsze doświadczenie) i są dobrane dla konkretnego silnika (dlatego ich tutaj nie podaję). Zauważ, jak szybko silnik dopasowuje się do pożądanej wartości). Przy okazji: wykres ze „starej” wersji algorytmu, na zajęciach Pan Bartek go udoskonalił i reakcja koła jest jeszcze szybsza!

pomysły, inspiracje…

Nowy termin spotkań

Zapraszam w piątki godz. 10:00, sala 1064

Theo Jansen

Pan Bartek chyba się nudzi w czasie sesji 😉 Podczas gdy inni studenci poświęcają się zaliczeniom/egzaminom, to on zainspirował się pracami Theo Jansena:

Wynikiem tych inspiracji są poniższe symulacje:

A co z tego wyniknie? Czas pokaże…

KG (c) 2020

UPDATE:
Model 3D wykonany, drukarka w ruch, program wgrany i oto efekt:

Brawo Pan Bartek!

KG (c) październik 2020

e-Fi-BOT

Pan Bartek po zmianie konstrukcji nóżek (dodane przekładnie zębate) jest w stanie sterować swoim heXapodem. Na razie działa podnoszenie „bestii”, ale niebawem… kto wie, kto wie 😉

Zainteresowanych zapraszam na e-Fi-BOTa (Zoom Meeting ID to mój oficjalny numer z konsultacji ze studentami). Możemy też spotykać się indywidualnie aby obejrzeć postępy pracy. Bądźmy w kontakcie, aby nie stracić semestru.


Brak kamerki? To nie problem – łącze z telefonu na jednym koncie, a na drugim – fonia i ekran PCta. Dla chcącego nic trudnego 😉

KG (c) 2020

Dżin Stefan (upgrade Maskotki)

Pan Leszek zaproponował fajny pomysł – zamiast planowanej „głowy” maskotki zrobić w to miejsce ludka nadmuchiwanego powietrzem! Jego uruchomienie, czyli niejako  „wyskoczenie” z wnętrza obudowy spowodowało u mnie skojarzenia bajkowego Dżina – i stąd tytuł dzisiejszego wpisu.

Na naszej balicy powstała pierwsza wersja projektu (kolor niebieski, po lewej stonie poniżych zrzutów-tablic :D), która szybko z opcji dwunożnej przeewoluowała do jednonożnej (prawy zrzut-tablicy, kolor czarny) – jako łatwiszej w realizacji, a może i ciekwszej?

Niby wszystko wydawało się proste: bierzemy jakiś materiał, lekki i wytrzymały (padło na worki na śmieci), tniemy i łączymy (taśma izolacyjna), potem wiatraczek do nadmuchania (na początku ten z obudowy PC-ta, taki jak w zasilaczach komputerowych) i będzie super. No i nie było.

Okazało się bowiem, że takie wiatraczki (typowo: 12V, 0.2A) są zdecydowanie za słabe aby napompować naszego Stefana – a aktualny projekt to maleństwo w stosunku do docelowego Dżina – 1m wysokości? czemu nie!

Po prostu podmuch wiatru generowany przez takie wiatraczki był za słaby. Znalazłem coś lepszego (z komputera Fujitsu) co powodowało kilkakrotnie większy podmuch – ale tylko lekko polepszyło sprawę. Jak rozwiązać ten problem? Dwie kwestie: 1) lepszy silnik, lub 2) zmniejszenie wagi naszego ludka (lub oba na raz).

Zmniejszenie wagi ludka okazało się proste do wykonania (choć pracochłonne). Podczas pomiarów na precyzyjnej wadze jubilerskiej okazało się, że waga izolki klejącej jedną rękę jest równa wadze samej ręki!  Dlatego zwykła taśma klejąca (przezroczysta) to lepszy pomysł. JEDNAK to za mało. Może w przyszłości należy kleić na klej? na gorąco (żelazkiem)? Trzeba o tym pomyśleć.

Ciąg powietrza: ciągle zbyt mały.
Dlatego zaproponowałem silnik od dronów XXD A2212 1400KV 2-3S (ciąg 830g) z mocnym, 30A regulatorem prędkości ESC (Electronic Speed Control). Przy tej okazji przedstawiłem sposób działania tego regulatora – protokół sterujący dokładnie taki sam jak serwo silniczki! Sterujemy więc sygnałem 50Hz z wypełnieniem 1ms (0% mocy) do 2ms (100% mocy). Nasz zasilacz ustawiony na max 3A prądu był i tak niewykorzystany w całości – przy tych wielkich śmigłach odważyłem się dać jedyni 20% mocy, a i tak deseczka z silniczkiem podskakiwała 😉

Teoretycznie mamy więc rozwiązane problematyczne kwestie – teraz tylko czas na zakup niezbędnych podzespołów i ich montaż. Podsumowując:

  1. Ludek z worków to dobry pomysł (materiał mocny).
  2. Klejenie lub prasowanie żelazkiem połączeń – konieczne.
  3. Ciąg powietrza z silnika bezszczotkowego sterowanego ESC.
  4. Pomysł na Stefana: jedna noga dwie ręce? a może 5 rąk? a może grecka litera fi? xi? chi? kappa? 😀
  5. Bardziej demoniczna twarz naszego Dżina? rekwizyty w rękach? Pojawiła się Pani Karolina, może ona coś wymyśli 😉

Tablica na koniec zajęć

Gratuluję twórczej pracy i zapraszam na kolejne spotkanie za tydzień!

(c) K.G. 2019

Maskotka, Line Follower oraz podstawy

Pracujemy w trzech płaszczyznach (3D? hmmmm)

Sterowanie serwem za pomocą joysticka

Na zajęciach sterowaliśmy serwomechanizmami za pomocą joysticka. Na początku używaliśmy niewielkiego modułu z joystickiem podłączanego bezpośrednio do Arduino. W drugiej części użyliśmy nakładki (shield) na Arduino z joystickiem oraz czterema przyciskami (podobnie jak na gamepadach).

Moduł z joystickiem

Moduł posiada pięć pinów. GND oraz 5V podłączamy do Arduino. VRx i VRy to piny sterujące odpowiednio osią OX (czyli lewo-prawo) oraz OY (czyli góra-dół). Podłączamy je do pinów analogowych. Ostatni pin odpowiada za przycisk, jednak nie używaliśmy go w tym zadaniu.

Prosty program wyświetlający położenie joystika

void setup(){
  Serial.begin(9600);
}
int x,y;
void loop(){
   x = analogRead(A0);
   y = analogRead(A1);
   Serial.print("x=");
   Serial.print(x);
   Serial.print(", y=");
   Serial.println(y);  
  }

Położenie na osi OX (także OY) to liczby z zakresu 0..1023. Położenie spoczynkowe powinno odpowiadać wartości 511 (liczby 0..510 to wychylenie w lewo, liczby 512..1023 to wychylenie w prawo). Użycie tego programu pozwoliło nam sprawdzić, że tak jednak nie jest – u nas joy w położeniu spoczynkowym miał wartości 514, 517 (oś OX i OY).

Podczas działania tego programu możemy postawić sobie następujące zadanie: ustawić pozycję joy-a w takim położeniu, aby odczyty były x=800 y=200. Okazuje się to jednak bardzo trudne! Widzimy więc, że sterowanie joy-em nie jest łatwe i wymaga sporo wprawy.

Wieżyczka

Używana przez nas wieżyczka (do której można przyczepić, np. kamerkę internetową by nią sterować) składała się z dwóch serw na podstawce. Umożliwia to poruszanie się mechanizmu na boki oraz w górę i dół.

Wszystkie potrzebne elementy połączyliśmy za pomocą płytki prototypowej. Zamiast zasilania z Arduino użyliśmy zewnętrznego koszyka na 4 baterie o łącznym napięciu 5V. Dlaczego tak zrobiliśmy? Chodziło nam o oddzielne zasilanie silników aby nie przeciążyć płytki Arduino – pojedyncze serwo może pobrać nawet 200mA prądu (co sprawdzaliśmy na poprzednich zajęciach), a wydajność prądowa Arduino UNO to około 200-400 mA. Dlatego dwa takie serwa mogą uszkodzić naszą płytkę. My użyliśmy oddzielnego zasilania silników aby temu zapobiec. WAŻNE: w przypadku używania kilku źródeł zasilania (u nas Arduino 5V i 4x baterie AAA) musimy uwspólnilić masy (GDN z Arduino, „minus” z bateryjki).

Użyliśmy płytki prototypowej, gdzie na jednej szynie (koloru niebieskiego) wetknęliśmy „-” z koszyka baterii oraz GND Arduino. Do tej „szyny” podłączone były masy serw (przewody koloru brązowego). Druga szyna (czerwona – z drugiej strony płytki, dla naszej wygody) doprowadzone miała przewód „+” z koszyka baterii i tam podłączone były zasilania silników serw (czerwone przewody serw). UWAGA: nie można łączyć pinu 5V Arduino z zewnętrznym zasilaniem baterii – może to spowodować uszkodzenie płytki! Łączymy (=uwspólniamy) jedynie masy. Przewody sterujące serwami (koloru żółtego) podłączyliśmy do pinów PWM Arduino UNO – u nas #3 i #5.

Program sterujący

Na początku standardowo dołączamy do programu bibliotekę umożliwiającą sterowanie serwami. Następnie dodajemy zmienne do obu serw, jedno odpowiedzialne za ruch góra-dół, a drugie lewo-prawo.

#include <Servo.h>
Servo GoraDol;
Servo LewoPrawo;

void setup (){
  Serial.begin(9600);
  GoraDol.attach(3);
  LewoPrawo.attach(5);
}
int x,y;

W kolejnej części deklarujemy zmienne odpowiadające za położenie obu osi joysticka – dokładnie tak, jak w pierwszym programie odczytującym położenia joy-a. Wyświetlamy wartości x oraz y w monitorze szeregowym. Joystick zwykle nie jest idealnie skalibrowany, jednak nie ma to znaczenia przy niewielkiej precyzji.

Funkcja map pozwala na łatwe proporcjonalne przeliczenie wartości. Używamy jej, ponieważ położenia joysticka są z zakresiu 0-1023, natomiast sterowanie serwem chcemy wyrażamy w stopniach 0-180. Wynik przypisujemy od razu do zmiennych x oraz y (używamy tych samych zmiennych, niszcząc ich poprzednie wartości). W argumentach funkcji wpisujemy zmienną do przeliczenia, następnie jej obecny zakres i na końcu zakres po zamianie. Po przeliczeniu wartości możemy je przekazać do serwomechanizmów.

   x=map(x,0,1023,0,180); //funkcja map
   LewoPrawo.write(x);
   y=map(y,0,1023,0,180);
   GoraDol.write(y);
   delay(10);

Nakładka (shield) na Arduino

Fajnym rozwiązaniem jest wykorzystanie specjalnej nakładki (shield), która poszerza możliwości Arduino. Piny obu komponentów pasują do siebie, więc nie da się pomylić przy wpinaniu nakładki. Joystick oraz przyciski są fabrycznie podłączone do pinów, więc nie musimy tego robić w programie. Na nakładce wszystkie piny są podpisane, więc później będziemy tylko operować odpowiednimi oznaczeniami pinów.

Modyfikacja programu – przycisk „zamrażający” położenie wieżyczki

Program sterujący jest bardzo podobny do poprzedniego. Jedyną różnicą jest brak podłączenia pinów cyfrowych. Dodatkową funkcją, którą wprowadzamy do naszego programu, jest zatrzymywanie serwa w ustawionej pozycji. Chcemy aby wciśnięcie wybranego przycisku (np. koloru czerwonego) zablokowywało dalsze sterowanie wieżyczką. Kolejne wciśnięcie tego przycisku powoduje odblokowanie sterowania. W tym celu do kodu wprowadzamy zmienną typu logicznego bool (nazwaną tryb) i ustawiamy ją na wartość true. Następnie wybieramy przycisk (np. ten czerwony), który ma sterować zatrzymaniem serwa i  sprawdzamy, który numer pinu u odpowiada. W naszym programie jest to pin 5.  Tworzymy instrukcję sterującą if, która wykona się po wciśnięciu przycisku. Do wartości zmiennej tryb, przypisujemy jej odwrotność. Czyli jeśli tryb jest true, zostanie zmieniony na false i odwrotnie. Funkcja delay() wprowadzamy aby zarejestrować tylko jedną zmianę ustawienia przycisku (przyciski lubią „drgać” co powoduje nie jeden „klik” a wiele takich „klików” – opóźnienie je zniweluje). Działa to w taki sposób, że jeśli tryb jest wartością false, czyli zostanie raz zmieniony we wcześniejszym if’ie, sterowanie joyem zostaje zablokowane. Natomiast po kolejnym użyciu przycisku, tryb zmieni się z false na true, a sterowanie zostanie odblokowane.

bool tryb=true;
void loop(){
  x=analogRead(A0);
  y=analogRead(A1); 
   if (digitalRead(5)==HIGH){
      tryb=!tryb;
      delay(50);
   }

   if(tryb==true){ 
   x=map(x,0,1023,0,180); //funkcja map
   LewoPrawo.write(x);
   y=map(y,0,1023,0,180);
   GoraDol.write(y);
  }
}

Podsumowanie

Jak można zauważyć programy umożliwiające sterowanie servami nie są skomplikowane ani długie. Można sprytnie wykorzystać komponenty posiadające więcej niż jedną oś ruchu, dzięki czemu nasze możliwości się poszerzają. Jednak precyzyjne sterowanie takimi joystikami nie jest łatwe…

(c) Ewelina, KG 2017

Sterowanie servem za pomocą potencjometru

Na ostatnich zajęciach łączyliśmy wiedzę nabytą na dwóch poprzednich spotkaniach, czyli działanie potencjometru oraz serva. Chcieliśmy wykorzystać możliwość zmiany nastawy potencjometru, w celu sterowania ramionami serwomechanizmu. Podobnie jak na zajęciach przedświątecznych, wykorzystamy do tego komendy biblioteki sterującej servami.

Sterowanie serva

#include <Servo.h>
Servo silnik;

void setup (){
  Serial.begin(9600);
  silnik.attach(3);
}

Servo podłączamy tak samo jak na przedświątecznych zajęciach, jednak w tym przypadku używamy 3 pinu, a sam mechanizm nazywamy silnikiem (linia #2 i #6).

Wykorzystanie potencjometru

int pot;
void loop(){
   pot=analogRead(A0);//odczytujemy liczby z zakresu od 0 do 1023
   pot=pot*180.0/1023;//zamienimy na liczby od 0 do 180
   Serial.print(pot);
   silnik.write(pot);
}

Na początku deklarujemy zmienną zapisującą stan potencjometru. W ciele funkcji void loop() podłączamy potencjometr do portu analogowego A0. Linia #4 przelicza zakres potencjometru. Jak pamiętamy, wynosi on od 0 do 1023, natomiast stopnie wychylenia serva chcemy wyrażać w zakresie 0-180. 180 konwertujemy na zmienną typu float dopisując do niej część dziesiętną w celu uniknięcia dzielenia całkowitego. W innym wypadku otrzymywalibyśmy nieprawdziwe wyniki, ponieważ wynikiem dzielenia 180/1023 zawsze będzie 0, przez co całe działanie również wyniesie 0. Przy zapisie 180.0/1023 mamy do czynienia z dzieleniem rzeczywistym, którego wynikiem będzie liczba rzeczywista. Następnie przy przemnożeniu przez zmienną całkowitą pot dostaniemy również liczbę rzeczywistą. Ostateczny wynik jest rzutowany na liczbę całkowitą w momencie przypisania operatorem równości.

Ulepszenie – dodatkowy if

W celu ulepszenia naszego kodu, chcieliśmy aby położenie ramion serwa było aktualizowane jedynie wtedy, kiedy zmienimy położenie potencjometru. Tym samym chcemy uniknąć sytuacji wydawania polecenia „ustaw serwo na pozycję XX” jeśli właśnie aktualną pozycją jest XX (nie ma to sensu, mimo tego, że to działa – jak w naszym pierwszym, prostym programie). Użyliśmy do tego instrukcji sterującej if. W linii #1 dopisaliśmy kolejną zmienną nazwaną old, która ma za zadanie zapisywać poprzedni stan położenia potencjometru (odczytanego napięcia). W warunkach if-a sprawdzamy, czy zmienna pot (czyli aktualny stan potencjometru), różni się od zmiennej old (czyli jego poprzedni stan).  Jeśli nie, funkcja Serial.print() nic nie wypisze i nie zmieniamy położenia serwa. W przeciwnym przypadku zostanie wypisane nowe napięcie, a ramiona serwa zmienią położenie. Na końcu przypisujemy zmienną old do pot, aby móc dokonać nowego porównania w kolejnej iteracji pętli. 

int pot, old; //old - zmienna zapisujaca poprzedni odczyt

void loop(){
  pot=analogRead(A0);
  pot=pot*180.0/1023.0; 
  if (pot!=old){ //aby zmieniac polozenie tylko wtedy, kiedy sie zmienilo, a nie wyswietlac polozenie ciagle
   Serial.print(pot);
   silnik.write(pot);
   old=pot; 
  }
}

Podsumowanie

Dzięki naszemu programowi możemy sterować ramionami serwa kręcąc potencjometrem. Przeliczenie wartości napięcia na stopnie umożliwia dość precyzyjne ustawienie serva.

2018, Ewelina (c)

Łączenie rejestrów przesuwnych oraz sterowanie serwomechanizmami.

Na ostatnim spotkaniu przed przerwą świąteczną rozwinęliśmy projekt rozpoczęty na poprzednich zajęciach tj. wyświetlanie cyfr przy pomocy wyświetlacza siedmiosegmentowego oraz rejestru przesuwnego. Główną korzyścią tej metody jest użycie jedynie trzech pinów cyfrowych Arduino. Okazuje się, że dołączenie drugiego wyświetlacza siedmiosegmentowego wymaga podłączenia drugiego rejestru przesuwnego, ale liczba pinów cyfrowych pozostaje taka sama !

Logika stosowania wielu rejestrów przesuwnych może być porównana do tworzenia jednego rejestru, który przedłużamy kolejnymi chipami 74HC595.

Podłączenie drugiego układu scalonego 74HC595 ogranicza się do podłączenia pinów RCLK oraz SRCLK do tych samych pinów arduino co odpowiadające RCLK oraz SRCLK piny pierwszego rejestru. Będzie to oznaczało, że nowy chip będzie on otrzymywał te same sygnały sterujące co pierwszy. Różnicą jest podłączenie pinu SER. Zamiast bezpośrednio do Arduino, podłączamy ten pin do wyjścia 9 naszego pierwszego rejestru przesuwnego. Dzięki temu całość będzie funkcjonowała jak jeden, przedłużony rejestr przesuwny.

 

Nasuwa się pytanie: jak zmodyfikować ostatnio napisany przez nas program tak, by poprawnie działał?
Odpowiedź jest prosta. Przygotowaliśmy się na to już na poprzednim spotkaniu i wystarczy wprowadzić nową wartość dla zmiennej ileScalakow (widocznej od razu w pierwszej linijce kodu), tak by równała się liczbie zastosowanych rejestrów, czyli 2:

Cały kod pozwalający sprawdzić działanie wyświetlaczy

#define ileScalakow 2
#define ilePinow ileScalakow * 8
int SER=8; 
int RCLK=9;
int SRCLK=10; 
int rejestr[ilePinow];

void setup(){
  pinMode(SER, OUTPUT);
  pinMode(RCLK, OUTPUT);
  pinMode(SRCLK, OUTPUT);
  czyscRejestr();
  zapiszRejestr();
}
void czyscRejestr(){
  for(int i=0; i<ilePinow; i++)
    rejestr[i]=LOW;
}
void zapiszRejestr(){
  digitalWrite(RCLK, LOW); 
  for(int i=ilePinow-1; i>=0; i--){
    digitalWrite(SRCLK, LOW);
    digitalWrite(SER, rejestr[i]);
    digitalWrite(SRCLK, HIGH); 
  }
  digitalWrite(RCLK, HIGH); 
}
void ustawPin(int ktory, int wartosc){
  rejestr[ktory]=wartosc;
}

void loop(){
  int i;
  for(i=0;i<ilePinow;i++)
    ustawPin(i, LOW);
    zapiszRejestr();
    delay(500);
   for(i=0;i<ilePinow;i++){
    ustawPin(i, HIGH);
    zapiszRejestr();
    delay(500);
}
}

Po tej prostej zmianie kod działa poprawnie. Jest to przykład jak odpowiednie wprowadzanie zmiennych pozwala na skalowalność i rozwijanie kreowanych programów.

Sterowanie serwomechanizmami

Serwomechanizm, lub potocznie serwo, to nic innego jak silniczek prądu stałego sterowany PWM (modulator szerokości impulsu) z podłączonym odpowiednim układem zębatek. To niewielkie i niedrogie urządzenie pozwala wygenerować niespodziewanie dużą siłę i moment obrotowy, szczególnie zważywszy na jego rozmiary i nieduży pobór mocy (przy mini serwach np. używanych przez nas SG92r produkcji TowerPro rzędu kilku watów).

Przed rozpoczęciem jakichkolwiek doświadczeń z serwami warto pamiętać właśnie o poborze mocy. Rekomendowane jest zasilanie ich z zewnętrznego źródła mocy np. baterii lub zasilacza prądu stałego. Przyczyną jest niebezpieczeństwo, jakie niesie za sobą skok natężenia prądu podczas ruchu serw – podłączenie kilku na raz do Arduino może niechybnie doprowadzić do spalenia sterownika.

Znalezione obrazy dla zapytania arduino servo batteries

Tworzenie programu sterującego serwami

Arduino posiada dedykowaną bibliotekę do sterowania serwami, co niezwykle ułatwia sterowanie i zarządzanie.

#include <Servo.h>

Nasz program pozwala na wpisywanie wartości do monitora szeregowego i dyktowanie ich serwomechanizmom.

Servo serwomechanizm;
int pozycja = 90;

void setup() 
{ 
 serwomechanizm.attach(9);
 Serial.begin(9600);
}

„Servo” jest formą deklaracji, że dany obiekt o nazwie „Serwmechanizm” ma być traktowany przez interpreter kodu jako serwomechanizm. Deklarujemy je w tej samej konwencji, co np. zmienne typu integer. Traktowanie go jak serwomechanizm oznacza, że możemy przypisać mu jakiś pin oraz pozycję (będą to odpowiednie zmienne w obiekcie Servo).

W naszym kodzie w etapie setup() przypisaliśmy pozycję wyjściową 90 stopni (2. linijka), pin 9 (7. linijka) oraz uruchomiliśmy monitor szeregowy dla częstotliwości 9600 baud. Następnie w loop() przy pomocy metody „parseInt” każemy „nasłuchiwać” wartości, które zostaną przypisane zmiennej „pozycja”.

void loop() 
{ 
 if (Serial.available() > 0) {
pozycja = Serial.parseInt();
 }
 if (pozycja > 0 && pozycja < 180) { 
 serwomechanizm.write(pozycja);
 } else { 
 pozycja = pozycja%160+10;
 serwomechanizm.write(pozycja);
 } 
 
}

Tym sposobem możemy sterować serwomechanizmem z klawiatury przypisując mu kąt od 0 do 180 stopni. Warto jednak pamiętać, by unikać skrajnych pozycji takich jak 0 i 180 stopni, gdyż w niektórych przypadkach może to doprowadzić do uszkodzenia serwomechanizmu.

Adnotacja: W bloku „else” umieściłem zabezpieczenie, które nie pozwoli również na przypisanie wartości większych niż 180. Była to nadprogramowa metoda, która pozwala ograniczyć przypisywane na serwo wartości tak, by zamykały się pomiędzy bezpiecznymi kątami 10 – 170 stopni. Sposoby zabezpieczania zależą od nas, jednak nie warto ich zaniedbywać. Szkoda naszego sprzętu i nerwów!

 

Pomiar prądu płynącego przez serwo.

Na bardziej ciekawych czekała również możliwość pomiaru prądu płynącego przez serwo. Warto pamiętać, że pomiar natężenia prądu należy przeprowadzać szeregowo względem badanego układu. Oznacza to, że multimetr w trybie pomiaru prądu musi być „po drodze” prądu między źródłem zasilania, a serwem. Dlatego zrobiliśmy to w następujący sposób:

Źródło napięcia (bez obaw, 5V i prąd zdecydowanie poniżej 1 A można swobodnie „izolować” suchymi dłońmi) dołączyliśmy do czerwonej sondy multimetru, a czarną do wejścia 5V serwa – jest to właśnie połączenie szeregowe.

Przy okazji mogliśmy zbadać wartość prądu pobieraną przez pracujące serwo. Wartości te na ogół wynosiły kilkadziesiąt mA, ale czasami (w skarajnym położeniu a także podczas zmiany położenia) wynosiły 100-200 mA. Oznacza to, że podłączenie kilku serw do Arduino jako źródła napięcia (a nie tylko do zadawania sygnału) skończyłoby się spaleniem płytki. Dlatego budując bardziej złożone układy z pewnością użyjemy zewnętrznych źródeł napięcia.

Do zobaczenia na kolejnym spotkaniu!
Maciej (c)

Zajęcia nr 5 – serwo silniki, map(), bluetooth

 Serwo silnik (a właściwie mikro-serwo)

serwo1Czyli silnik, który obraca się od 0 do 180 stopni (ma blokadę na inne wychylenia). Potem utrzymuje swoją pozycję. Służy do tworzenia obrotowych ramion itd…

Trzy przewody – zasilanie (czerowny +5V, czarny/brązowy GND) oraz jeden sterujący – musi być PWM. Za dużo nie wnikałem o co chodzi w sterowaniu tym silnikiem, tylko wspomniałem o potencjometrze wewnątrz i o wypełnieniu sygnału sterującego… więcej może później? Zobaczymy.

 

Do sterowania tym silnikiem użyliśmy 2 nowych funkcji z nowej biblioteki:

  • #include <Servo.h> – na początku programu informujemy, że chcemy funkcje z tej nowej biblioteki
  • Servo silniczek; tworzymy zmienną typu silnik-serwo, czyli właśnie o to nam chodzi!
  • silniczek.attach(3); powoduje przekazanie informacji do Arduino, że sterujemy silnikiem przez pin numer 3 (przypominam: musi być to pin PWM, czyli jak nie 3, to 5,9…)
  • silniczek.write(133); ustawia nasz silnik w pozycji 133 stopni. Albo na dowolny inny z zakresu 0..180 stopni. Dziecinie proste 😉

Serwo sterowane z klawiatury

Przypomnieliśmy sobie jak odczytywać liczby z klawiatury (funkcja parseInt() dla obiektu Serial) i stworzyliśmy program ustawiający silnik w pozycji wczytanej z klawiatury. Proste a przyjemne. No i zawsze warto powtarzać wiedzę 😉

Serwo sterowane potencjometrem

Połączenie poprzednich zajęć – potencjometr liniowy (dzielnik napięć!) wykorzystany do ustawiania pozycji serwa – ruszam „gałką” w lewo, orczyk w serwie obraca się w lewo. Tak samo w prawo. Fajne!

Serwo sterowane potencjometrem – program PRO

Dbamy o szczegóły – i nie chcemy ustawiać położenia serwa wówczas, gdy potencjometr nie zminił swojej pozycji. Bez złośliwości – my staramy się programować na serio

Prąd „zjadany” przez serwo – mierzymy!

W skrajnych ustawieniach serwa (tj. w okolicy 0 stopni, oraz w okolicach 180 stopni) słyszymy buczenie/piszczenie serwo-silnika. Coś się dzieje. Amperomierz w garść i mierzymy prąd.

serwo1

Przyjrzyj się uważnie obrazkowi i zwróć uwagę, jak podłączony jest amperomierz.

Oczywiście w wirtualnym Arduino (ciągle polecam circuits.io) silniczek serwo jest idealny i nie widzimy tego, co było u nas na zajęciach….

Dodatkowo: w przypadku mierników uniwersalnych ustaw największą wartość prądu, jaką się spodziewasz dostać – nie odwrotnie! W przeciwnym przypadku zwiększając zakres przepalisz bezpiecznik w multimetrze…

Funkcja map()

Czyli skalowanie wartości z jednego zakresu na drugi zakres. Przykład, z którym my się bawiliśmy: serwo silniczek sterowany potencjometrem. Odczytujemy nastawy potencjometru z portu analogowego Arduino jako liczbę (nazwijmy ją x) z zakresu 0..1023, a następnie ustawiamy serwo w położeniu z zakresu 0..180 stopni (nazwijmy te stopnie y). Czyli musimy dokonać zamiany wczytaj liczby x na y. Na zajęciach pokazałem skalowanie funkcją liniową, rozwiązaliśmy ten układ równań, ale Arduino jest także dla tych co tego nie umieją zrobić i przygotowało funkcję map(). W naszym przypadku będzie to:

y=map(x, 0, 1023, 0, 180);

Należy pamiętać, że funkcja map() działa tylko na liczbach całkowitych (int).

Serwo sterowane przez Androida – bluetooth XM-15B

Dlaczego ten? Bo działa w zakresie 3-6V, czyli można go bezpiecznie podłączyć do Arduino. Inne modele – popularne HC-05, HC-06 komunikują się przez 3.3V i wymagają „zbijania” napięcia (np. dzielnikiem napięć). To proste, ale… po co się w to bawić, jak można kupić właśnie moduł pozbawiony tej uciążliwości? Praujemy więc z XM-15B.

 

Pamiętajmy o łączeniu „na krzyż” portów RxD,TxD modułu XM-15B z portami RxD,TxD płytki Arduino (także tymi wirtualnymi).

Komunikacja z 8LAMP

Ze sklepu Play bierzemy prostą apkę i sprawdzamy, co ona wysyła do naszego bluetootha. Kod:

#include <SoftwareSerial.h>

#define RxD 8
#define TxD 9
SoftwareSerial btSerial(RxD,TxD);

void setup() {
  Serial.begin(9600);
  btSerial.begin(9600);
  Serial.println("start!");
}

void loop() {
  if (btSerial.available()){
    Serial.print("Odebrałem znak= ");
    Serial.println(btSerial.read());
  }  
}

Następnie tak modyfikujemy ten program, by wczytany znak sterował naszym serwem – guzik '1′ ustawiał serwo na 90 stopni, guzik '2′ na 10 stopni i guzik '3′ na 170 stopni. Inne modyfikacje mile widziane 😉

Ważne

Na następne zajęcia proszę o zainstalowanie ze sklepu Play aplikacji Arduino Bluetooth Controler bo będziemy sterować pojazdem.