TinkerCAD – wirtualne Arduino – dla początkujących (i nie tylko)

Wirtualne Arduino – czyli SYMULATOR płytki Arduino (ale także i prostej elektroniki). Dla kogo? Dla każdego, kto chce spróbować zabwy z Arduino. Nie trzeba więc kupować zestawu, wystarczy usiąść przed ekranem swojego komputera i bawić się płytką Arduino tak jak prawdziwą! Fajne, i za darmo!

Rejestracja

Projekt TINKERCAD jest własnością firmy AUTODESK i najpierw wymaga rejestracji. Zakładamy więc konto (darmowe) i dopiero wówczas możemy korzystać z serwisu.

Uprzedzam, że ani ja, ani Wydział Fizyki UwB nie jest powiązany z AUTODESK ani nie czerpie profitów z tego oprogramowania – polecam je jako bardzo ciekawe i łatwe w użyciu. Dodam, że jest to jedno z wielu dostępnych symulatorów Arduino – K. Gawryluk.

www.tinkercad.com

Zakładamy konto (o ile jeszcze nie mamy) wpisując powyższy adres i wybierając przycisk ZAREJESTRUJ SIĘ.

Prawy górny róg:

Potem postępujemy zgodnie z ekranami, podając swoje miejsce zamieszkania i datę urodzin:

podajemy też swój adres email i wybieramy hasło (proponuję też przyjrzeć się warunkom korzystania z usług – choć nie widzę tam „haczyków”):

Kolejny etap to już tylko potwierdzenie utworzenia konta – uruchamiamy swoją pocztę i potwierdzamy nadesłany email z Grupy Autodesk. Możemy już działać!

Po zalogowaniu – panel użytkownika

Z lewej strony widzimy swoje zdjęcie (o ile takie dodaliśmy), poniżej opcje tworzenia różnych projektów (bo TinkerCAD to nie tylko wirtualne Arduino!). W centralnej części mamy obrazki z naszymi wcześniejszymi projektami – oczywiście po założeniu nowego konta nie ma ich tyle, co na moim obrazku.

Ważne: TinkerCAD zapisuje automatycznie nasze projekty w „chmurze”, czyli możemy korzystać z nich wszędzie, na każdym komputerze (z dostępem do internetu – oczywiście). Jest to plus, ale i… minus! Często ładowanie projektów jest poooowooooolnneeeee (coż, nie jesteśmy jedynymi użytkownikami – to bardzo dobry i popularny serwis).

Wirtualna elektronika – nasz pierwszy obwód

Aby rozpocząć zabawę z elektroniką wybieramy sekcję Circuits – czyli (w wolnym tłumaczeniu) obwody elektroniczne. Sekcja ta zaznaczona jest na obrazku poniżej kolorem niebieskim (znajduje się zaraz pod naszym imieniem i nazwiskiem, lub nickiem).

Po wybraniu Circuits klikamy duży, zielony przycisk Create new Circuit (co tłumaczymy jako Tworzymy nowy obwód elektroniczny).

Brawo! Możemy rozpocząć dodawanie elementów elektronicznych! Gdzie je znaleźć? Proszę przyjrzeć się prawej stronie okienka z rozwijaną listą Components Basic. Na liście tej znajduje się sporo fajnych rzeczy – bateryjki, oporniki, płytka stykowa…

Proszę odnaleźć płytkę stykową – klikamy ją myszką i znajduje się ona na naszym wirtualnym biurku! Tak samo robimy z bateryjką 1.5V – klikamy i dodajemy!

Następnie wybieramy na biurku bateryjkę – klikamy ją myszką. Pojawia się dodatkowe menu z różnymi opcjami:

Można zmienić nazwę (hmmm…. chyba zbyteczne, choć może być przydatne w większych projektach), ale my zmieniamy liczbę bateryjek w zestawie – modyfikujemy pole Count  jak na rysunku powyżej. Mamy napięcie 4.5V !

Łączymy przewody – wystarczy kliknąć na wyprowadzenie z bateryjki (pojawia się też „dymek” z podpowiedzią – w języku angielskim) a następnie drugi raz kliknąć w innym miejscu – pojawi się połączenie przewodem.

Dodajemy kolejny przewód -warto dbać o porządek podczas pracy z elektroniką (także tą wirtualną!). Zmieniamy kolory przewodów w menu. Pamiętajmy, że dobrze jest oznaczać czarnymi przewodami „-” z bateryjki, a czerwonymi przewodami – bieguny „+”.

Dodajemy opornik (trzeba go najpierw odnaleźć z prawej strony – nazywa się Resistor). 

Proszę zmienić też wartość oporu: pole Resistance powinno być ustawione na 220 ohmów. Wirtualnymi elementami można obracać – użyj ikonki z lewej, górnej części ekranu:

Teraz dodajemy diodę elektroluminescencyjną (LED):

Pamiętajmy, że diody mają wyróżnioną polaryzację – dwie „nóżki”: anodę („+”) i katodę („-„) więc ważne jest, która nóżka jest która. Postaraj się zrobić tak, jak na rysunku powyżej.

Na koniec dodajemy ostatni przewód zamykający obwód elektryczny. Brawo – w ten sposób stworzyłeś wirtualny obwód!

Aby go uruchomić należy wybrać przycisk Start Simulatoin (uruchom symulację).

Jeśli wszystko dobrze podłączyłeś, LED powinien się świecić a Ty powinieneś się cieszyć, że wszystko działa! 

Co teraz? Może sprawdź parę rzeczy:

  • jak wpłynie większa wartość opornika w Twoim układzie? W tym celu zatrzymaj symulację (Stop simulation) i kliknij opornik – zmień mu wartość Resistance w menu na większą – 500 Ohm, 1000 Ohm a może nawet 10 kOhm? Po tej zmianie ponownie uruchom symulację.
  • a może tak przepalić LED-a? spokojnie, komputer nie ucierpi – ale Ty nauczysz się, że gdy wartość opornika będzie za mała – popłynie za duży prąd (tutaj: powyżej 20mA) i led „wybuchnie” (wirtualnie!).  W tym celu zatrzymaj symulację i zmień wartość opornika na bardzo mały, np. 22 Ohm, a może nawet 2 Ohm. Pamiętaj, aby nie robić tego z prawdziwym obwodem na własnym biurku!
  • można też zmienić napięcie zasilania układu – zatrzymaj symulację, wybierz myszą koszyk z bateriami i zmień pola Count, Type. Zauważ, że jest tam także możliwość dodania przełącznika: Build-In switch
  • zauważ, że możesz dodawać też multimetr – i robić pomiary aby sprawdzić, jaki prąd płynie w układzie lub jaki jest spadek napięcia na poszczególnych elementach elektronicznych!
  • poszukaj elementów, które możesz znać – wybierz przycisk (mikrostyk) i zbuduj taki układ:

Układ z Arduino UNO

Tworzymy nowy projekt – wracamy do głównego panelu wybierając kolorową ikonkę TIN KER CAD. Tworząc nowy układ automatycznie otrzymujemy zabawną nazwę (poniżej „Amazing Curcan-Hago”) – jeśli Ci nie pasuje, lewy klik na napisie i zmieniamy!

Ponownie wybieramy Circuits oraz Create new Circuit. Dodajemy elementy jak na zdjęciu poniżej:

Po dodaniu do układu płytki Arduino UNO  pojawiła się nowa opcja w menu Code (czyli programuj Arduino) – obok przycisku Start Simulation. Po wciśnięciu tego przycisku rozwinie się pole (z prawej strony) umożliwiające pisanie programu a raczej… budowanie go z „klocków” w stylu Scracha. Można z tego korzystać (co kto lubi), ale ja wolę się przełączyć na pisanie programu w języku C/C++

Zmieniamy więc pole Blocks na liście na Text i mamy program w C/C++

Zwróć uwagę, że ja zmodyfikowałem tekst programu: zamieniłem liczby 13 na 7 – gdyż u mnie LED podłączony jest do pinu numer 7 na płytce Arduino. Możemy już uruchomic symulację (Start Simulation) i Arduino będzie wykonywać nasz program! Zwróć też uwagę, że przewód podłączeniowy w tym momencie jest wciśnięty w Arduino.

Co dalej? Proponuję zatrzymać się w tym momencie i bawić się wirtualną płytką:

  • zmodyfikować program tak, aby LED świecił i i gasł nie w odstępie 1 sekundy, ale z przerwami co 2 sekundy
  • a może tak zmienić program, aby najpierw LED zaświecił się na 1 sek, zgasł na 1 sek, potem zaświecił się na 2 sek, zgasł na 1 sek, potem świecił się na 3 sek a zgasł na 1 sek – po tym cyklu wszystko ma się powtórzyć
  • można dodać więcej LED-ów – czy umiesz odtworzyć poniższy układ w wirtualnym Arduino?

Wyświetlacz 7-segmentowy

Dodawanie kolejnych LED-ów może być zabawne, ale czas teraz na wyświetlacz siedmio-segmentowy: znajdź go na liście komponentów elektronicznych (Components) i dodaj go na płytkę stykową

Zwróć uwagę, że możesz zmienić rodzaj wyświetlacza: wspólna anoda („+”) lub wspólna katoda („-„). To ma znaczenie! Podłączaj wyświetlacz wybierając piny z Arduino takie, jak lubisz, np.

a potem programuj! Zwróć uwagę, że kursor myszki nad wyświetlaczem wyświetla „dymek” z podpowiedzią, która nóżka co oznacza. Postaraj się stworzyć program wyświetlający wszystkie cyfty! Zacznij od 3-ki:

Teraz zaczyna się przygoda!

Tak, teraz możesz się bawić w programowanie elektroniki! Jest to bardzo bezpieczne, gdyż nawet jeśli coś źle połączysz (co się pewnie zdarzy) – to popsujesz tylko wirtualne Arduino! Jeśli jednak „złapiesz bakcyla” i będziesz chcieć więcej – kup prawdziwe Arduino z osprzętem (przewody, płytka stykowa, oporniki i LEDy) i baw się w rzeczywistym świecie (to jeszcze lepsza frajda – gwarantuję!). Jeśli jednak znudziła Cię ta zabawa – nic straconego, nie wydałeś ani złotówki – zamknij program i poświęć czas na swoje ulubione zabawy. Twój wybór.

Więcej? a może kolorowe LEDy RGB?

Zestaw elementów TinkerCADa ciągle się rozrasta i można już się „bawić” modułam WS2812B! Proszę spróbować:

Ws2812b oraz potencjometr

Czy tylko zabawa?

Pamiętaj, że wirtualne Arduino ze strony TINKERCAD to nie tylko „zabawa” dla początkujących – warto budować i sprawdzać swoje prawdziwe projekty, przed ich podłączeniem! Powodzenia!

(c) K. Garwyluk 2018
pochwal się ze mną swoimi projektami
k. gawryluk@uwb.edu.pl

Przygotowania + pianinko

XVI Festiwal przed nami – przygotowujemy się do pokazów. Przy tej okazji: poznajemy funkcję tone() w Arduino aby wydobywać dzwięki z podłączonego głośniczka. Działa! A jaki ubaw, gdy Mario-Bros brzmi z naszej maszynki (wiem wiem, cofamy się do lat ’80, ale… mimo to widzę zadowolenie na twarzach!).

Musieliśmy przypomnieć sobie działanie przycisków (ale nie modułów), tylko micro-styków. Dlatego rozmawialiśmy o INPUT_PULLUP (wbudowany rezystor podciągający) i dlaczego właśnie tak należy postępować z mikrostykami. Zrobiliśmy mini-pianinko:

Sprawa niby prosta – przycisk wciśnięty = graj dany ton, zwolniony = cisza. Ale ale… Okazało się, że trzeba mądrze programować przyciski!

(c) KG 2018

Optymalizacja sterowania

Słowem wstępu…

Dzisiejszego dnia pracowaliśmy nad optymalizacją naszego sterowania pojazdem.

Wciąż używamy do tego naszego smartfona, a konkretniej aplikacji „ArduinoRC”, która za pomocą bluetooth w naszym telefonie łączy się z modułem Bluetooth XM-15B podłączonego do Arduino. Więcej o tym w tym artykule.

Na poniższym zdjęciu nasz wypasiony „panel sterowania” 🙂

 

Dotychczas nasz program działał w dosyć prosty sposób – jeżeli Arduino odczytało określony znak z komunikacji szeregowej  bluetooth, to przekazywało do silniczka konkretne stany tak aby koła kręciły się na przykład w przód.

 

Poznaliśmy jednak głębszą teorię sterowania i pojawił się następujący problem:

A więc w aplikacji „ArduinoRC” klikamy strzałkę w górę. Załóżmy że przekazywany znak to literka 'W’, po odczytaniu której kółka mają się kręcić w przód.  Po przekazaniu jej komunikacją szeregową, Arduino posłusznie uruchamia silniczki, po czym je wyłącza. Gdy na telefonie tym razem przytrzymamy strzałkę, zamiast pojedynczego znaku 'W’, Arduino odczyta serie znaków – „WWWWWWWWWW … „. Po każdym z odczytanych znaków silniczki na chwilę staną, po czym po wczytaniu następnego – znowu ruszą. Taki efekt 'szarpania’ to nienajlepsze rozwiązanie ponieważ ciągłe włączanie i wyłączanie silniczka powoduje większe zużycie baterii. Więc zamiast sekwencji:

włącz(1) – wyłącz(1) – włącz(2) – wyłącz(2) – włącz(3) – wyłącz(3)

proponujemy logiczniejsza sekwencje:

włącz(1) – kontynuuj(2) – kontynuuj(3) – wyłącz(3).

Oczywiście nie zobaczymy tego problemu gołym okiem, ponieważ Arduino może odczytywać parę tysięcy takich znaków na sekundę.

Rozwiązanie problemu

Pomysłów na rozwiązanie tego problemu było parę, trzeba było jednak liczyć się z tym że Arduino to nie komputer stacjonarny i warto zrobić to w miarę możliwości optymalnie, aby nie zaśmiecać pamięci mikrokontrolera.

Z pomocą przyszła nam funkcja millis() z wbudowanej biblioteki, która zwraca czas który upłynął od włączenia urządzenia w milisekundach. Utworzyliśmy też parę pomocniczych zmiennych i utworzyliśmy sprytny sposób aby usprawnić pracę silnika.

Znowu użyłem swoich ponadprzeciętnych umiejętności artystycznych oraz zaawansowanego oprogramowania do obróbki graficznej (Paint i Gimp) aby stworzyć kilka schematów blokowych.

Przedstawiają one po kolei:

1. Działanie głównej pętli loop

Jak widać główna pętla programu Arduino będzie składała się z dwóch bloków: Obsługi Bluetootha, a potem Obsługi stopu silnika. Tak, tylko stopu silnika, bo uruchomienie silników zajdzie się w Obsłudze Bluetooth. Raz puszczone koła w ruch zatrzymają się dopiero w drugim bloku, po upływie określonego czasu. 

2. Działanie obsługi Bluetooth

Powyższy schemat koncentruje się tylko na jednej instrukcji – jedz do przodu (wczytanie W). Gdy już wszystko będzie dobrze działać – w podobny sposób trzeba dodać kolejne polecenia (zda do tylu, w lewo i w prawo). 

Sama obsługa instrukcji jazdy do przodu (obsługa 'W’) będzie obszerniej wytłumaczona za chwilę, ale już sam schemat algorytmu dużo może wyjaśnić:

3. Działanie obsługi odczytania znaku 'W’

Na początku, utwórzmy zmienną pomocniczą P i na razie przypiszmy jej liczbę 0. Będzie to zmienna przechowująca czas działania Arduino w milisekundach, po którego przekroczeniu nasze kółka przestaną się kręcić.

Zmienna DeltaT przechowywuje czas w milisekundach, przez jaki nasze kółka mają się kręcić po jednorazowym odczytaniu znaku. My akurat ustaliliśmy wartość 100 milisekund, jest to optymalna wartość przy której w praktyce nasza maszyna śmiga jak należy.

Dla lepszego wyobrażenia sobie tego o czym mowa, poniżej przedstawiłem oś przedstawiającą upływ czasu od włączenia Arduino. Zaznaczyłem zupełnie przypadkową wartość, akurat w tym przypadku oznacza, że minęło 10234 milisekund (czyli jakieś 10,2 sekund od włączenia urządzenia).

Kolejny krok w naszym schemacie to instrukcja warunkowa:

Czy P<milis() ?

W tej chwili Arduino wywołuje funkcje millis() i porównuje ją ze zmienną P. Między uruchomieniem urządzenia a wczytaniem znaku z naszego telefonu musiała minąć przynajmniej 1/1000 sekundy. Warunek zostaje więc spełniony – upływ czasu w milisekundach jest większy od 0. Przechodzimy więc do następnego bloku zgodnie ze schematem.

  1. P = millis() + DeltaT
  2. włączSilnik()

1.Zmienna P przyjmuje wartość sumy aktualnego upływu czasu   i   czasu przez jaki nasze kółka mają się kręcić po jednorazowym odczytaniu znaku.

2.Nasz silnik uruchamia się a wehikuł jedzie do przodu.

 

Tak jak wspominałem, zmienna P będzie przetrzymywała czas działania Arduino po którym silnik przestaje działać – teraz widzimy to na osi. Działa to mniej więcej w ten sposób:

  1. Wczytany został sygnał 'W’.
  2. Aktualnie minęło 10234 milisekund od czasu uruchomienia urządzenia.
  3. Silnik uruchamia się.
  4. Silnik ma pracować dopóki czas działania Arduino nie przekroczy 10334 milisekund.

Całkiem proste prawda? 🙂

To co opisałem do tej pory, to reakcja na pojedynczy znak 'W’. Jednak ja chcę aby mój samochodzik podjechał dwa metry do przodu, a co mi tam! Zobaczmy więc co zdarzy się jeśli przytrzymam strzałkę w aplikacji sterującej, a Arduino dostanie serie znaków „WWWWWWWWWWW … „.

Ok, analogiczna do powyższej sytuacja:

  1. Arduino odczytuje pojedynczy znak 'W’
  2. zmienna P przyjmuje odpowiednią wartość
  3. silniczek rusza

Jednak zanim minie nasze DeltaT czyli 100 milisekund, Arduino dostaje kolejny znak – kolejne 'W’. I co teraz? Wróćmy do naszego schematu blokowego nr 2 – tym razem zacznijmy działanie od instrukcji warunkowej (zmienne przypisuje tylko na początku działania programu) – i spójrzmy na poniższy wykres:

Aktualnie nasze P jest większe od czasu który upłynął dotychczas – rozpatrując więc działanie schematu blokowego, pierwszy warunek nie zostaje spełniony – wykonuje się instrukcja:

P = P + DeltaT

Czyli zmienna P która dotychczas przyjmowała konkretną wartość, powiększy się o kolejne DeltaT – czyli o 100. Oznacza to że czas działania urządzenia w którym silnik ma się wyłączyć wydłuża się o 100 milisekund.

Po odczytywaniu kolejnych znaków – analogicznie czas ten będzie się wydłużał. Będzie tym bardziej dłuższy, im dłużej przytrzymam strzałkę i im więcej znaków w jednej sekwencji odczyta Arduino. Przy tym warto zauważyć że w takiej sytuacji nasz silnik nie zatrzyma się, będzie działał dopóki trzymam strzałkę. Tak więc nasz problem został rozwiązany.

Na koniec ostatni blok programu – sprawdzenie, czy trzeba zatrzymać silniki.

4. Działanie obsługi stopu silników

 

PROGRAM i obiekty

Teraz zapoznajmy się z praktycznym kodem na Arduino. Naturalnie jest on obszerniejszy niż schematy blokowe, ponieważ obsługuje On całe działanie samochodu. W tym przykładzie zdecydowałem się na stworzenie klasy – jest to forma programowania obiektowego,  co umożliwia język C++. Różni się więc od poprzednich programów z fi-bot-a – gdzie programowaliśmy strukturalnie (język C). Opiszę więc komentarzem kluczowe linijki kodu których działanie opisałem wcześniej.

#include <SoftwareSerial.h>
#define RxD 2
#define TxD 3
#define IN1 4
#define IN2 5
#define IN3 6
#define IN4 7

SoftwareSerial btSerial(RxD,TxD);
unsigned long int przod = millis();                           
unsigned int delta_t=100;               

class Silnik      //w tym przykladzie zdecydowalem sie na stworzenie klasy - jest to forma 
{                 //programowania obiektowego co umozliwia język C++, a nie jak w poprzednich
  public:         //artykulach - tylko programowania strukturalnego a'la język C

  void wylaczSilnik()
  {
    digitalWrite(IN1,HIGH);
    digitalWrite(IN2,HIGH);
    digitalWrite(IN3,HIGH);
    digitalWrite(IN4,HIGH);
  }
 
  void doPrzodu()                        
  {
    digitalWrite(IN1,HIGH);
    digitalWrite(IN2,LOW);
    digitalWrite(IN3,HIGH);
    digitalWrite(IN4,LOW);
  }

  void doTylu()
  {
    digitalWrite(IN1,LOW);
    digitalWrite(IN2,HIGH);
    digitalWrite(IN3,LOW);
    digitalWrite(IN4,HIGH);
  }

  void wPrawo()
  {
    digitalWrite(IN1,HIGH);
    digitalWrite(IN2,LOW);
    digitalWrite(IN3,HIGH);
    digitalWrite(IN4,HIGH);
  }

  void wLewo()
  {
     digitalWrite(IN1,HIGH);
     digitalWrite(IN2,HIGH);
     digitalWrite(IN3,HIGH);
     digitalWrite(IN4,LOW);
  }
};

  Silnik Maria;

void setup() {
  Serial.begin(9600);
  Serial.println("start!");
  btSerial.begin(9600);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
 
}
              
void loop() {                          //schemat blokowy nr 1
  if(btSerial.available())             //schemat blokowy nr 3
  {
    char zn=btSerial.read();           
    Serial.println(zn);

   
    switch(zn)
    {
      case 'W':                        //schemat blokowy nr 2
      if(przod<millis())               
      {
        przod=millis()+delta_t;        
        Maria.doPrzodu();
      }

      else                              
      {
        przod+=delta_t;
      }

      break;

      case 'S':
      if(przod<millis())
      {
        przod=millis()+delta_t;
        Maria.doTylu();
      }

      else
      {
        przod+=delta_t;
      }
     
      break;

      case 'A':
      if(przod<millis())
      {
        przod=millis()+delta_t;
        Maria.wLewo();
      }

      else
      {
        przod+=delta_t;
      }
      break;
     
      case 'D':
      if(przod<millis())
      {
        przod=millis()+delta_t;
        Maria.wPrawo();
      }

      else
      {
        przod+=delta_t;
      }
      break;
    }
  }

  if(millis()>przod)                    //schemat blokowy nr 4
    {
      Maria.wylaczSilnik();             
    }
}

To by było na tyle, bądźcie na bieżąco 🙂

Pozdrawiam!

(c) Przemysław Baj 2018

Arduino – nowości

Arduino prezentuje nowe płytki rozwojowe z komunikacją bezprzewodową – MKR1010 posiada dwa programowalne procesory – jeden z rdzeniem ARM oraz drugi zawierający dwa rdzenie Espresif-IC. Oprócz tego na płytce zamontowano układ identyfikacyjny Microchip ECC508, który umożliwia zabezpieczenie połączeń i komunikacji sieciowej (więcej).

źródło: mikrokontroler.pl

Robot – maskotka (cz. 1)

Dziś trafiło mnie olśnienie – dziękuję Szymonowi, Mateuszowi i Przemkowi za naszą wspólną rozmowę, w wyniku której powstał ten właśnie koncept. Czyli: aby nasza maskotka była atrakcyjna (przypominała bardziej robota niż popielniczkę na kółkach :P) zakupiłem taki oto gadget:

KASK OTWARTY JET WL708 SKUTER WHITE XS HOMOLOGACJA

Na korpusie (jak na razie z aluminiowego śmietnika) zamocujemy efektowny kask 😉 No z takim bajerem to będzie prawdziwy robot 😉 Warto zadbać o ciekawą kolorystykę samego korpusu. Trafił mnie taki oto pomysł (już mówiłem – w stylu „artystów” znad polskiego morza zarabiających na tworzeniu futurystycznych obrazów sprejami i czym-tam popadnie). Chodzi mi o taki efekt (jest kto chętny do malowania? albo ma znajomego?):

Jeśli chodzi o sam korpus: to kupno kosza już nieaktualne – lepiej akusz blachy duraluminiowej i ją sobie wygiąć. Na allegro arkusz 100x50cm i grubość 1mm (czyli grubość aż aż) to koszt ~40zł. Dużo bardziej opłacalne. Już się dowiedziałem, że taką blachę Wydział ma na stanie (procedura przejęcia arkusza już rozpoczęta!). Ale jest lepszy pomysł niż tworzenie walca… mianowicie konstrukcja typu łezka. Proszę przyjrzeć się poniższym obrazkowi (rzut z góry):

Łatwo przygotować podstawę takiej konstrukcji (płyta meblowa 18mm oraz wyrzynarka). Zyskujemy:

  • stabilność konstrukcji – dwa koła wewnątrz „łezki”, szerko jak się da. Trzecie koło (skrętne) na dole konstrukcji
  • łączenie blachy (na dole) proste wo wykonania – umieszczamy kawał drewienka (znowu płyta meblowa? cóż, to mam pod ręką!) i przewiercamy do niej
  • to dużo ciekawszy kształt niż walec – nikt nie powie, że to kosz na śmieci

Arkusz blachy może mieć wysokość ~50cm, więc cała konstrukcja może wyglądać jakoś tak (proszę sobie zwizualizować jeszcze ten kask na górze! mi się projektować w 3d nie chciało :P)

 

Jeszcze jedno: głowa (kask) może (musi!) być ruchoma (kręcić się o 360 stopni) a może nawet…. podnosić się do góry! Potrzeba przekładnia ślimakowa. Skąd? Hmm…. ma ktoś stary, niepotrzebny fotel obrotowy? 😉 Tak tak, trzeba kombinować 😉

I co Wy na to? Dziękuję za inspirację i dzisiejszą rozmowę!

(c) KG 2018

Transoptor szczelinowy (czujnik szczelinowy)

Słowem wstępu…

Nasz Fi-Bot’owy zespół wciąż pracuje nad swoimi pojazdami. Podzieleni w pary wciąż ulepszamy swoje maszyny dodając kolejne części i klepiąc nowe linijki kodu.

Tym razem przyszedł czas na rozwiązanie problemu zliczania obrotów kół, tak aby można było lepiej sprawdzać i kontrolować prędkość naszego pojazdu.

Z pomocą przyszedł nam właśnie…

Transoptor Szczelinowy

Jak działa to wspaniałe urządzenie? (już wcześniej się bawiliśmy takim modułem – wyznaczając wartość przyspieszenia ziemskiego).

Na samym początku potrzebowaliśmy kółka zębatego (poniżej: wydrukowane w 3D), które ma dokładnie 16 ząbków i które umieszczamy na osi obrotowej naszego koła(silniczek ma wał obrotowy po dwóch stronach). Następnie zamontowaliśmy czujnik szczelinowy tak, aby kółko zębate znajdowało się między nim.

Poniżej wykorzystałem moje ponad przeciętne zdolności artystyczne aby lepiej Wam to zobrazować. Kółko obracając się raz po raz przesłania wiązkę światła emitowanego z transoptora (a dokładniej z diody) i sygnał ten nie trafia do bramki – mamy stan wysoki (logiczną jedynkę), pokazuje to górny rysunek (lewa strona), albo przepuszcza wiązkę i mamy wówczas stan nisko (czyli zero, prawy obrazek). Obracając się mamy szereg stanów wysokich i niskich na wyjściu z transoptora.

Transoptor szczelinowy mówiąc łopatologicznie sprawdza czy między nim coś jest, lub nie ma. Jeżeli nasze koło się obraca, a razem z nim oś wraz z zębatką – czujnik szczelinowy jest w stanie odczytać:

  • czy między nim jest ząbek koła – i zwrócić 1
  • czy też ząbka niema – i zwrócić 0

Łatwo możemy więc wywnioskować że jeden obrót koła to „przejście” transoptora po 16 ząbkach koła zębatego.

Niestety nasze urządzenie nie odczyta zmiany stanów w czujniku w ten sposób:

101010101010101010

ponieważ urządzenie to nadaje nam z prędkością nawet do kilku tysięcy stanów na sekundę (w zależności od modelu), więc Arduino odczytywać będzie to mniej więcej tak:

0000000000011111111111111100000000000000111111111111111111111100000000

gdzie '1′ oczywiście znaczy, że w danej chwili ząbek jest między szczeliną, a '0′ że go nie ma.

Tak więc do zliczania obrotów musieliśmy napisać swój program. Na tym zakończy się teoria a zacznie się…

 

Transoptor w praktyce

Jeżeli chodzi o podłączenie modułu do Arduino to nie sprawia to większych trudności. Zasilanie modułu podpinamy pod pin z napięciem 5V, uziemienie do GND, natomiast ostatni kabelek wędruje pod wybrany przez nas pin cyfrowy. W moim przypadku był to pin z numerem 7.

Przejdźmy więc do pisania kodu 😉

Oczywiście pomysłów na rozwiązanie tego problemu jak i wykonanie i działanie samego programu było kilka, ja zamieszczam pod spodem swoją wersje.

void setup() {
  pinMode(7,INPUT);
  Serial.begin(9600);
}

bool zn;
bool temp=0;
int rotates=0;
int indents=0;

void loop() {
  zn = digitalRead(7);
  if(zn>temp)
  {
    indents++;
    temp=zn;
    Serial.print(rotates);
    Serial.print(" rotates ");
    Serial.print(indents);
    Serial.println(" indents");
  }
  else
  {
    temp=zn;
  }
  if(indents==16)
  {
    rotates++;
    indents=0;
  }
}

Na początku:

  1. w funkcji setup ustawiamy tryb wybranego przez nas pinu na input – czyli tryb wejścia, ponieważ dane będą wchodzić przez niego do naszego Arduino. Robimy to za pomocą funkcji pinMode(7, INPUT)
  2. uruchamiamy komunikacje szeregową z komputerem za pomocą funkcji Serial.begin(9600) – to właśnie na naszym monitorze będziemy odczytywać liczbę obrotów koła

Zanim jeszcze wejdziemy do naszej głównej pętli wprowadziłem potrzebne zmienne:

  1. bool zn – zmienna zn (od słowa znak) będzie przechowywać aktualny stan podawany przez czujnik. Typ zmiennych 'bool’ nadaje się do tego idealnie bo przechowuje On tylko 1 lub 0 – inaczej prawda lub fałsz.
  2. bool temp – zmienna temp (od słowa ang. temporary – tymczasowy) będzie zmienną pomocniczą. Na początku musimy przypisać jej wartość '0′, jednak jej działanie opiszę dokładniej później.
  3. int rotates – zmienna rotates (od słowa ang. rotations – obroty) jak sama nazwa wskazuje będzie przechowywać liczbę aktualnie zliczonych obrotów. Na początku będzie ich oczywiście 0.
  4. int indents – zmienna indents (od słowa ang. indents – wcięcie) będzie przechowywać liczbę zliczonych ząbków.  Na początku będzie ich oczywiście 0.

Przejdźmy więc do głównej funkcji programu – loop.

Na początku do zmiennej zn wczytujemy stan z czujnika – będzie to stan 1 lub 0 w zależności od tego czy w pozycji startu ząbek akurat jest między czujnikiem czy nie (nie ma to żadnego znaczenia). Używamy do tego funkcji digitalRead(7) gdzie '7′ jest oczywiście numerem naszego pinu.

Następnie pojawia się warunek if – jeżeli nasz wczytany stan zn będzie większy od stanu trzymanego w zmiennej pomocniczej temp – czyli będzie równy 1 – wtedy :

  1. indents ++   – zwiększ liczbę zliczonych ząbków o 1
  2. temp = zn   – zmienna temp przyjmuje wartość zn
  3. wypisz policzone obroty i wcięcia

w przeciwnym przypadku, jeżeli będzie mniejszy lub taki sam, wykonuje się tylko przypisanie wartości temp :

  1. temp = zn   – zmienna temp przyjmuje wartość zn

Co tu się właściwie stało? Tak jak pisałem wcześniej Arduino odczytuje stany czujnika w następujący sposób:

000000001111111111000000000000000111111111111110000001111111111111

Można tu wyróżnić sekwencje zer i jedynek. Sekwencja jedynek oznacza że przez tą krótką chwile czujnik odczytał ząbek między widełkami. Kiedy więc będzie można powiedzieć że ząbek przeskoczył przez czujnik? Wtedy i tylko wtedy gdy transoptor wczyta jedynkę po zerze. Zaczyna się wtedy sekwencja jedynek – ząbek jest chwile między widełkami, następnie znowu sekwencja zer – ząbka brak, i znowu sekwencja jedynek, czyli kolejny ząbek.

000000001111111111000000000000000111111111111110000001111111111111

Załóżmy że program zaczyna się od sekwencji zer – podawane stany będą ciągle zerami. Dopóki aktualny stan nie będzie większy od temp czyli nie będzie wynosił 1 (bo temp przyjmuje wartość '0′ na starcie programu), licznik ząbków nie powiększy się.

Kiedy program natrafi na pierwszą jedynkę – licznik ząbków powiększy się o 1, natomiast zmienna temp która do tej pory trzymała 0, przyjmie wartość 1. Gdy do zmiennej zn zostanie wczytana następna jedynka z sekwencji, licznik nie powiększy się ponieważ nie został spełniony warunek:   zn>temp   –   przecież jedynka nie jest większa od jedynki 😀

I tak w kółko dopóki znów nie zacznie się sekwencja zer – oczywiście warunek dalej nie zostanie spełniony bo 0 tym bardziej nie jest większe od 1, ale za to temp przyjmie wartość 0, tak żeby warunek spełnił się na początku kolejnej sekwencji jedynek i licznik ząbków znów powiększył się o 1.

Ostatnia i niezbędna rzecz w naszym programie – warunek   if (indents==16).

Musimy pamiętać że cały czas dodawaliśmy ząbki koła zębatego, a w sumie jest ich 16. Wnioskując logicznie Arduino musi odczytać te 16 ząbków, po czym:

  1. rotates++   – zwiększyć liczbę obrotów o 1
  2. indents=0   – wyzerować aktualnie zliczone ząbki, ponieważ już zatoczyło się pełne koło. Nasz program będzie je teraz dodawał od nowa.

Podsumowanie

Zakładam że połowa osób przysnęła czytając moje wypociny, dlatego zachęcam do samodzielnej zabawy. Na pewno umiejętność używania czujnika szczelinowego przyda się jeszcze nie raz.

Na przyszłych zajęciach będziemy dalej ulepszać nasz pojazd, szczególnie skupimy się na usprawnieniu sterowania 🙂 Zachęcam do bycia na bieżąco.

 

(c) Przemysław Baj 2018

pojazd cz.1

Dziś było więcej mechaniki, niż elektroniki… choć na koniec udało się Wszystkim złożyć swoje pojazdy i uruchomić – gratuluję! Za tydzień sterowanie i pierwsze jazdy próbne 😉

(c) KG 2018

Bluetooth

Z wielkim sukcesem i zadowoleniem oprogramowaliśmy moduł Bluetooth XM-15B

  • biblioteka SoftwareSerial.h — bardzo przydatna w pracy z bluetooth, bo potrzebujemy komunikacji szeregowej (Arduino UNO ma tylko jedną parę Tx/Rx!)
  • tworzymy zmienną SoftwareSerial i przypisujemy jej dwa piny cyfrowe – w kolejności Rx, Tx
  • nie zapomnijcie o włączeniu metodą begin(9600)
  • łączenie „na krzyż” z modułem XM-15B, czyli: Tx <–> Rx, Rx <–> Tx
  • czytanie i interpretowanie komend…. a myślicie, że po co ciągle ćwiczyliśmy czytanie z klawiatury? teraz się przyda!

Poniżej działanie aplikacji Blutooth Control Lamp i wyświetlaczem 7-mio segmentowym:

Podłączamy sterownik silników L298N i kolejna apka z Androida: Android RC

A tu mamy to, co niebawem nas czeka: troszkę większe silniczki (37Dx73L) z zaprojektowanym i wydrukowanych „trzymakiem”

Chciałem pogratulować całej 5-tce obecnej na dzisiejszych zajęciach – za zaangażowanie w pracę nad projektem – i naukę nawet w długi weekend majowy. Jestem przekonany, że Wam się to opłaci.

(c) KG 2018

Silniczek DC – mostek H – pracowita majówka?

….opis później…

Propozycja zajęć

W związku z majówką (długą! brrr) i moimi/naszymi pomysłami na robota R2D2 proponuję spotkać się w nastęnym tygodniu:

  • poniedziałek 30 kwietnia, godz. 10:00, lub
  • środa 2 maja, godz. 10:00 — zapraszam!

Niech każdy student wyśle mi email z informacją, co wybiera – bo choć rozmawialiśmy o środzie, to mi się ten poniedziałek bardziej podoba. Ale proszę o współpracę. O wynikach pointofmuję tutaj.

Zajęcia potrwają ~1.5h i skupimy się na sterowaniu pojazdem (proszę mieć ze sobą piloty na podczerwień – od TV, radia… ewentualnie smartfona z nadajnikiem podczerwieni). Będzie też komunikacja Bluetooth, więc proszę o zainstalowanie dwóch aplikacji (przewidziane są problemy z internetem w Kampusie, więc netu nie będzie):

(c) KG 2018

czujka wibracji – elektroniczna kostka do gry

Kolejny raz podstawy – czyli rozmawialiśmy oo doborze odpowiedniego opornika dla układu zasilanie-LED. Mierzyliśmy napięcia (czyli spadki napięć) oraz prądy. Każdy musi przez to prześć, dlatego zachęcam do zabawy w wirtualnym Arduino (jest tam multimetr, płytka stykowa i różne LEDy – proszę nie zlekceważyć tego ćwiczenia!).

Czujka drgań

Bardzo prosta, ale ile zabawy 😉 Prosta, bo ma trzy pin-y: VCC i GDN (czyli zasilanie, z przedziału 3.3V-5V) oraz pin Dout – sygnał cyfrowy informujący o drganiu. Cena to kilka złotych, zależnie od miejsca kupna.

Do czego? no wiele zastosowań, ale… takie śmieszniejsze (ale czy oby na pewno?) to alarm otwartej szuflady. Czyli: jeśli chcemy mieć pewność, że nasz młodszy brat nie będzie grzebać w naszej szufladzie, to … montujemy taki układ do wnętrza szuflady i jeśli jednak będzie próba jej otwarcia – to odezwie się alarm (lub taki incydent zostanie zapisany w pamięci). Potem można przejrzeć „dziennik zdarzeń” i przekonać się, czy faktycznie braciszek nie myszkował w naszej szufladzie 😉

To bardzo czuły czujnik

Właściwie to wystarczy stuknąć w stół i te minimalne drgania wprawią w działanie nasz czujnik. Pirwszy, prosty programik:

byte czujka=7;

void setup(){
  pinMode(czujka, INPUT);
  Serial.begin(9600);
}

void loop(){
  if (digitalRead(czujka)==0)
    Serial.println("czujka! drgania!");
}

Nie pomyslilem się – rejestrujemy drgania gdy odczytujemy napięcie LOW (czyli zero). Gdy brak drgań – odczytujemy stan HIGH (1). A może tak rozbudować program, aby zliczał liczbę drgań?

byte czujka=7;
unsigned int licz=0;

void setup(){
  pinMode(czujka, INPUT);
  Serial.begin(9600);
  licz=0;
}

void loop(){
  if (digitalRead(czujka)==0){
    licz++;
    Serial.print("czujka! drgania!  ");
    Serial.println(licz);
  }
}

Proszę uruchomić powyższy programik i zaobserwować, jak szybko nasz licznik (zmienna licz) rośnie. Przy okazji przekoanliśmy się na własne oczy, co się dzieje gdy przepełnimy licznik (testowaliśmy to na zmiennej typu byte, która zlicza liczby od 0..255 – łatwo taki licznik przepełnić!).

Kostka do gry – liczby losowe, nie pseudo-losowe!

Pokazałem państwu swój kolejny układ – elektroniczną kostkę do gry. Drgania powodują tworzenie liczb losowych (prawdziwie losowych, nie pserudo-losowych). Jak? wymyśliłem sobie tak: zliczam liczbę drgań, a gdy drgania ustaną – wynik wyświetlam z operacją modulo 6 + 1 (modulo 6 – to liczby z zakresu 0..5 więc dodaję jeszcze 1 aby mieć sześcienną kostkę do gry). Całość prezentuję na 7-segmentowym wyświetlaczu (no i dodatkowo „dla bajeru” uruchamiam melodyjkę).

Na powyższej fotce widzimy Arduino UNO (w wersji Ferrari – czerwoniutkie) z nakładką – proto-shieldem (aby nie trzeba było się bawić w oddzielną płytkę stykową). Roboczo wszystko połączone jest przewodami ze skrętki, ale całość nieźle trzyma się kupy 😉

Praca domowa

Proponuję pobawić się w wirtualnym Arduino i poćwiczyć wyświetlanie liczba na 7- segmentowym wyświetlaczu – to może się jeszcze wielokrotnie przydać!Nie zapomnijcie zapisać wyników Waszej pracy by potem pochwalić się nimi!

(c) KG 2018