Archiwa tagu: ard-motor-shield-r3

Jak sterować robotem, czyli budowa i obsługa prostego enkodera.

Jak sami zauważyliście, dwukołowa platforma robota, którą oferuje sklep Nettigo.pl ma tendencję do skręcania. Spróbujcie – napiszcie program, który nakazuje jedynie jazdę na wprost. Celem tego i kilku następnych artykułów będzie analiza i minimalizacja tego zjawiska oraz prezentacja różnych sposobów regulacji. Mam nadzieję, że będzie to przyjemny start w świat regulatorów.

Liczenie obrotów układ

Czytaj dalej

Beam Follower czyli robot z Arduino goni światło

Zasada działania:

W tym przypadku robot zamiast podążać za linią goni światło latarki – zupełnie jak kot, który stara się złapać plamkę lasera. Tak jak wcześniej wykorzystamy falową naturę światła. Mianowicie, naszymi czujnikami natężenia światła będą fototranzystory wrażliwe na podczerwień. Dlaczego takie? Bo działają ;) Światło latarki zawiera sporo promieniowania podczerwonego. Teoretycznie można też użyć fotorezystorów, jednak są one znacznie mniej dokładne.

Podłączenie:

Podłączenie fototranzystora

Jak widać, nie należy ono do bardzo skomplikowanych. Krótsza nóżka do masy, dłuższa do wejścia analogowego w arduino i rezystora. Jak pamiętacie, w module optycznym Line Followera zostawiłem dwa wolne wyprowadzenia. Wykorzystamy je teraz ;) Fototranzystory bez najmniejszego problemu można wlutować w płytkę, na której znajdują się transoptory. Jak widać, na poprzednio zlutowane transoptory nałożyłem warstwę taśmy izolacyjnej aby uniknąć zwarć.

Podłączenie fototranzystora w praktyce

Oczywiście, równie dobrze możecie w ogóle tego nie lutować, tylko wykorzystać płytkę stykową BB-170 przymocowaną np. gumką recepturką do korpusu. To już od Was zależy ;)
Niezależnie od tego, który sposób wybierzecie, nie ustawcie czujników za daleko od siebie, szerokość płytki BB-170 jest optymalna. Poza tym ustawcie je pod kątem do siebie, to zwiększy różnicę między ilością światła padającą na oba fototranzystory.

Moduł linefollowera z dodatkowymi fototranzystorami:

Gotowy moduł, 2 w jednym

Moduł linefollowera z dodatkowymi fototranzystorami, widok z dołu:

Gotowy moduł, widok z dołu

Program, czyli co robot myśli:

Deklaracja zmiennych. “left” i “right” to numery pinów analogowych do których będziemy podłączać czujniki. Tak jak poprzednio, “predkosc” i “predkosc2” to wartości wypełnienia PWM i trzeba je dopasować samodzielnie. Z kolei dwie ostatnie deklaracje odpowiadają za czułość robota. Zbyt mała czułość sprawi, że robot nie będzie jechał za światłem, zbyt duża z kolei – że będzie jechał za nim bardzo wolno. Sprawdźcie sami: w miejsce “wartoscmax” wpiszcie 1000 i zobaczcie co się stanie ;)

#include <MotorShield.h>
MS_DCMotor prawy(MOTOR_A);
MS_DCMotor lewy(MOTOR_B);
#define left 2
#define right 3
#define predkosc 150
#define predkosc2 100 //predkosc przy skrecaniu
#define wartoscmin 0
#define wartoscmax 700

Funkcja odpowiadająca za zapis pomiaru do struktury i jednoczesnemu zaokrągleniu wyniku. Funkcja map() pozwala przeliczyć jakiś zbiór wartości na inny, wg wzoru podanego na stronie. Zmniejszenie przedziału sprawia, że zaokrąglamy odczyty z fototranzystorów.

void zmierz(struct Pomiary &odczyt)
{
odczyt.lewy = map(analogRead(left), 0, 1023, wartoscmin, wartoscmax);
odczyt.prawy = map(analogRead(right), 0, 1023, wartoscmin, wartoscmax);
}

Funkcja sterująca. Dzięki wcześniejszemu zaokrągleniu odczytów możemy zastosować najprostsze rozwiązanie – sprawdzenie czy napięcie na lewym fototranzystorze jest większe/mniejsze/równe napięciu na prawym. W ten sposób wiemy, po  której stronie jest jaśniej.

void steruj(struct Pomiary odczyt)
{
// jesli fototranzystor jest wpięty między analog pin i masę
if(odczyt.lewy == odczyt.prawy)
{
prawy.setSpeed(predkosc);
lewy.setSpeed(predkosc);
}
if(odczyt.lewy < odczyt.prawy)
{
//wiecej swiatla po lewej
prawy.setSpeed(predkosc2);
lewy.setSpeed(0);
}
if(odczyt.lewy > odczyt.prawy)
{
//wiecej swiatla po prawej
prawy.setSpeed(0);
lewy.setSpeed(predkosc2);
}
}

Na koniec…

Program możecie ściągnąć tutaj. Tak jak wcześniej, zachęcam do modyfikowania tego projektu ;)

Jest to przykładowa konstrukcja, dla naszego zestawu Robo Kit

Robo Kit, czyli pierwsze kroki z robotyką. Line Follower.

O co chodzi:

Przyświecała nam idea stworzenia zestawu dzięki któremu można w przyjemny sposób rozpocząć przygodę z robotyką. Prostota obsługi jest tu priorytetem, dlatego też zdecydowaliśmy się na wykorzystanie gotowych modułów do realizacji jak największej ilości funkcji. Pojazd podążający za linią (line follower) jest najlepszy na początek. W miarę prosty w realizacji, pozwala jednocześnie zebrać pierwsze doświadczenia. Dzięki wykorzystaniu gotowych modułów (Arduino UNO, Motor Shield, gotowe podwozie robota) możemy kolejne roboty budować w oparciu o te same podzespoły. Jednocześnie nie jesteście ograniczeni tylko do robotów – Arduino może być sercem projektów niemających nic wspólnego z robotyką.

Zasada działania, czyli teoria do pominięcia:

Jak sprawić by robot widział linię? Żeby odpowiedzieć sobie na to pytanie, należy wpierw zadać sobie inne: W jaki sposób my widzimy? Czemu nocne niebo jest czarne, kartka jest biała, a liście zielone? Wszystko to wynika ze zdolności do odbijania światła. A w zasadzie – do zdolności odbijania fali o konkretnej długości. Liście są zielone, bo zawarty w nich chlorofil odbija fale elektromagnetyczne o długości odpowiadającej zieleni, resztę pochłania. W ten sam sposób – dno studni czy nocne niebo wydaje się nam czarne, bo światło (fale EM) są przez nie pochłaniane. Właśnie z tej własności skorzystamy budując naszego robota.
Jako oczka followera wykorzystamy transoptory odbiciowe CNY70. Transoptor to zestaw diody i fototranzystora. W tym wypadku jest to dioda podczerwona. Podczerwień to fala EM na tyle długa, że ludzkie oko jej nie widzi. Podlega ona jednak tym samym prawom co światło widzialne – “czerń” ją bardzo dobrze pochłania, a “biel” bardzo dobrze odbija. Dzięki temu transoptor położony na kartce będzie dobrze przewodził, z kolei położony na taśmie izolacyjnej – nie będzie przewodził prawie w ogóle.

Czytaj dalej

Samochodzik, czyli jak wykorzystać modem Xbee.

Jakiś czas temu wpadłem na pomysł budowy quadrocoptera. Jednak, że nie od razu Rzym zbudowano, stwierdziłem, że zacznę od skonstruowania czegoś mniejszego, tańszego i bezpieczniejszego, czegoś na czym mógłbym spokojnie testować zdalne sterowanie. Tak oto urodziła się idea trójkołowego samochodzika.

Od czego zacząć

Konstrukcja nie powala, po prostu wyciąłem z kartonu prostokąt o wymiarach 10×20 i doczepiłem do niego zaciskami dwa sześciowoltowe silniczki.

Samochodzik wersja bardzo alfa

Samochodzik wersja bardzo alfa

Jego sercem i rozumem jest Arduino UNO z nałożonym Motor Shieldem. W zasadzie w tak prostym modelu można pominąć ów shield, gdyby założyć, że nie będziemy korzystać z biegu wstecznego i sterować silnikami za pomocą PWM,, ale akurat miałem go pod ręką i grzechem byłoby tego nie wykorzystać ;) Poza tym wykorzystałem dwa modemy Xbee S2 oraz, znaleziony na dnie szafy, joystick analogowy, który z powodzeniem można zastąpić Joystick Shield Kitem. Wykorzystanie go ma tą zaletę, że oszczędzi Wam wiele pracy i zmniejszy ilość walających się kabli.

Rozbieranie joysticka

Josticki analogowe to tak naprawdę dwa potencjometry, ustawione prostopadle do siebie. Jeden odpowiada za odchylenie w osi OX, drugi w osi OY. Wychylenie drążka powoduje zmianę rezystancji tych potencjometrów, zwykle mają one rezystancje od około 0 do 100k Ohm.

Joystick

Joystick

Specjalnie na potrzeby padów, joysticków, etc. w komputerach pojawiły się GamePorty. Jak sami pewnie się domyślacie, najpierw musiałem dojść do tego który przewód za co odpowiada. Odciąłem wtyczkę od kabla i posiłkując się opisem pinów z wikipedii stwierdziłem, że widoczny na zdjęciu przewód pomarańczowy odpowiada za oś OX, a brązowy – OY. Dlatego polecam wykorzystanie shielda – oszczędzicie sobie pracy. Kolejnym problemem był sam odczyt spadku napięcia na potencjometrze. Niestety, nie mogłem mierzyć go bezpośrednio. Dlatego też wykorzystałem opisany TU dzielnik napięcia, tak samo jak tam wykorzystałem rezystor 10k i mierzyłem spadek napięcia zamiast na joysticku – na ów rezystorze. To z kolei spowodowało, że napięcie nie zmieniało się liniowo, lecz hiperbolicznie – w związku z tym ustawiłem cztery możliwe wychylenia (zero/lekko/średnio/mocno) i zbadałem napięcia dla tych wychyleń. W ten sposób ustaliłem, że dla odczytu poniżej 190 (190*5/1023 = 0.92 V) drążek jest wychylony do przodu, dla odczytu powyżej 240 (1,17V) drążek odchylony jest do tyłu, itd.

Skoro już mamy czym sterować…

Przyszedł czas na zastanowienie się jak przekazywać polecenia do Arduino na pokładzie samochodzika. Po podłączeniu (RX do DOUT, TX do DIN) i skonfigurowaniu Xbee wedle tutorialu, nadszedł etap na napisanie programu. Dzięki blogowi Sprae, który w bardzo czytelny sposób tłumaczy tajniki wysyłania struktur, w bólach powstały dwa programy, nadawaczy i odbiorczy (linki na końcu postu):
Jak sami pewnie zauważycie, są to w zasadzie odpowiednio przerobione programy zamieszczone na blogu Sprae, nie wynajdywałem koła od nowa ;) On też tłumaczy tam w bardzo dobry sposób jak działa proces wysyłania i odczytywania poszczególnych bitów. W związku z tym objaśnię w tym poście tylko wybrane fragmenty kodu. Aha, ważna sprawa: program odbiorczy nie chce się kompilować (przynajmniej u mnie) w Arduino IDE 1.0.1 ! Do wgrania programu na Uno wykorzystałem IDE 0.22.

int Speed[] = {0, 100, 175, 255};
int currentSpeed;
int currentForce;

Tutaj deklaruję zmienne pomocnicze, które wykorzystam w dalszych częściach kodu.

struct paczka
{
  int dir;
  int vel; /*velocity*/
  int turn;
  int force;
} pack;

Oto struktura, przechowująca odczyt wychylenia joysticka, która zostanie wysłana do pojazdu. Pole:

  • ” dir” odpowiada za kierunek (255 – przód, 0 – tył)
  •  “vel”  odpowiada za prędkośc (0 – zero/100 – mała/175 – pół/255 – cała)
  •  “turn” to kierunek skrętu, czyli czy skręcamy w lewo czy w prawo (0 – nie skręcamy/125 – lewo/255 – prawo)
  •   “force” to siła z jaką skręcamy (0/100/175/255), a dokładniej jaki jest stosunek wypełnienia PWM sterującego jednym kołem, do wypełnienia PWM odpowiadającego z drugie koło

Całą strukturę zbudowałem w oparciu o wartości typu “int”, gdyż miałem pewne problemy w przesyłaniu do struktury znaków i tablic znaków (“char”). Równie dobrze zamiast 225 oznaczającego kierunek w przód, mogłoby być tam np. 5, to są tylko przyjęte przeze mnie oznaczenia. Oznaczenia to tylko umowa. A propos umów i oznaczeń, który wzór na moc czynną jest poprawny?

 

   czy        ??

Odpowiedź na dole strony.

    if(NAPY <190) /*forward*/
    {
      if(NAPY >= 150 && NAPY < 190)
      {
        currentSpeed = Speed[1];
      }
      else if(NAPY >=100 && NAPY < 150)
      {
        currentSpeed = Speed[2];
      }
       else
      {
        currentSpeed = Speed[3];
      }
      pack.dir = 255;
      pack.vel = currentSpeed;
    }

Ten fragment kodu odpowiada założeniu o który pisałem w poprzednim akapicie. Dla odczytu poniżej 190 (0.92 V) program zapisuje w polu struktury odpowiadającej za kierunek wartość “255”, a następnie sprawdza jak bardzo wychylony jest joystick. Im mniejsze jest zmierzone napięcie tym większa jest wartość wychylenia. Kolejne przedziały są przyporządkowane wartościom z kolejnych komórek pomocniczej tablicy.

Wybrane fragmenty programu odbiorczego:

Deklaracja zmiennych oraz bibliotek.

#include <MotorShield.h>
#include <EEPROM.h>

MS_DCMotor right(MOTOR_A);
MS_DCMotor left(MOTOR_B);
int Speed[] = {0, 100, 175, 255};
int currentSpeed;

Biblioteka EEPROM nie jest konieczna do działania samochodzika, w sumie spokojnie można powiedzieć, że jest zbędna ;). Po prostu w czasie tworzenia programu chciałem sprawdzić jak działa przesyłanie danych między XBEE, a najprostsze było napisanie funkcji, opisanej poniżej, zapisującej odebrane dane w pamięci EEPROM.

void pack_save(struct paczka *pack, unsigned int address)
{
  byte *data = (byte *) pack;
  unsigned int size = sizeof(paczka);
  for (unsigned int i=0; i<size; i++)
  {
    EEPROM.write(address+i, data[i]);
  }
}

W ten sposób mogłem sprawdzić co zostało odebrane. Jeśli chcecie sami sprawdzić co odbiera Wasze Xbee usuńcie symbole “/*” oraz “*/”. Wszystko co jest pomiędzy nimi, w języku C, oznacza komentarz i jest pomijane przez kompilator. Ponieważ prędkość zapisu do pamięci EEPROM jest relatywnie niska, należy zwiększyć opóźnienie w wykonaniu następnej pętli programu (delay). Z doświadczenia wiem, że przy zapisywaniu odebranych danych i opóźnieniu rzędu 10~30 ms, Arduino wiesza się po paru cyklach. Pamiętajcie też, że trwałość pamięci EEPROM jest obliczona na ok 100000 cykli zapisu i odczytu, więc korzystajcie z niej rozważnie.

void rotator_controller(struct paczka pack)
{
    if(pack.dir == 255)
      {
      right.run(RELEASE);
      left.run(RELEASE); 
      right.run(FORWARD);
      left.run(FORWARD);
      right.setSpeed(pack.vel);
      left.setSpeed(pack.vel);
       }
   if(pack.dir == 0)
      {
      right.run(RELEASE);
      left.run(RELEASE); 
      right.run(BACKWARD);
      left.run(BACKWARD);
      right.setSpeed(pack.vel);
      left.setSpeed(pack.vel);
      }
    if(pack.dir == 125)
    {
      right.run(BRAKE);
      left.run(BRAKE);
      right.setSpeed(Speed[0]);
      left.setSpeed(Speed[0]);

    }

Tak jak widać, jeśli “pack.dir” odpowiadające kierunkowi ma odpowiednią wartość, w tym przypadku, “255” pojazd jedzie do przodu. Na tej samej zasadzie dla “0” będzie jechał do tyłu, a dla “125” zostanie włączony hamulec.

    if(pack.turn == 125) /*left*/
    {
      right.setSpeed(pack.vel);
      if(pack.force == 100)
        left.setSpeed(pack.vel/1.5);
      if(pack.force == 175)
        left.setSpeed(pack.vel/2);
      if(pack.force == 255)
        left.setSpeed(pack.vel/3);
    }

Tak jak napisałem wcześniej, skręcanie polega tu na różnicy wypełnienia PWM sterującego jednym kołem, a drugim. Dzięki temu promień skrętu jest niewielki, a gdyby zmienić odrobinę kod, tak by dla maksymalnego wychylenia koła obracały się w przeciwnych kierunkach, samochodzik będzie się obracał w miejscu. Jak czołg, który zajmuje zaszczytne miejsce na liście “TO DO”.

W zasadzie już wszystko mamy

Do sterowania silnikami wykorzystałem, ze względu na wygodę MotorShielda oraz napisaną do nie go bibliotekę. Biblioteka znakomicie upraszcza cały program, a poza tym zauważyłem ciekawą zależność. Przy własnoręcznie napisanym programie obsługującym silniki  wyły nieludzko, z kolei przy tej bibliotece pracują w miarę cicho. W ten sposób można sterować np tym robotem.

Efekty pracy:

Odpowiedź do pytania:

Oba są poprawne. Wszystko zależy od umowy, od tego jakie oznaczenia się przyjmuje. Przykładowo, na wydziale Elektrycznym mojej Alma Mater obowiązuje wzór pierwszy, z kolei na wydziale Elektroniki, stosuje się drugi wzór bo operują oni wielkościami amplitudy sygnału, a do liczenia mocy wykorzystuje się wartość skuteczną. A wartość skuteczna, dla sygnału przemiennego, jest opisywana wzorem:

Programy nadawcze i odbiorcze

Użyte elementy:

Ten samochodzik zbudowany został z następujących elementów z oferty Nettigo: