sterujemy pojazdem – oprogramowanie

Kontynuujemy oprogramowywanie pojazdu – ciągle chodzi nam o jak najpłynniejszą jazdę.

Propozycje softu:

  • tworzymy liczniki czasu jazdy (w milisekundach) do przodu, w lewo, w prawo
  • każdorazowe naciskanie przycisków na pilocie zwiększa odpowiednie liczniki
  • w pętli głównej unikamy zatrzymywania Arduino – czyli funkcji delay, zamiast to
  • używamy funkcji millis() do sprawdzenia aktualnego czasu i wyłączeniu silników, jeśli liczniki pracy do przodu (w lewo, w prawo) się skończyły
  • a teraz najciekawsze modyfikacje:
  • jeśli oba liczniki: do przodu i skrętu (nieważne: w lewo czy w prawo) są niezerowe, to w zależności od ich stosunku sterujemy PWM-em koła i robimy albo lekki skręt, albo bardzo mocny (bez jechania do przodu).

Kolejne zajęcia po Świętach – wtorek 25 kwietnia – sterujemy pilotem platformą – nie zapomnijcie przynieść ze sobą pilota na podczerwień.  Zapraszam!

 

sterujemy pojazdem (TSOP 2236) + tuning platformy

Rozpoczęliśmy od sprawdzenia, na ile czasu jazdy starczą nam zainstalowane akumulatorki. Pierwszy program był się bardzo prosty – cała naprzód (i  mierzymy prąd).

Potem zamonotowaliśmy czujkę TSOP 2236 i wpisaliśmy obsługę poleceń: jedź do przodu, tyłu, skręcaj (niektórzy nawet dwa rodziaje skrętów – ciasny, oraz szeroki).

Okazuje się, że pojazdy jeżdzą, ale trudno się nimi steruje – wykręcenie „ósemki” na przygotowanym torze nie jest wcale łatwe. Sprawa wymaga odpowiedniego oprogramowania rozkazów jazdy – na tym trzeba się skupić.

Kolejne zajęcia – także we wtorek 16:00 – sterujemy pilotem platformą – nie zapomnijcie przynieść ze sobą pilota od TV/radia/odkurzacza.  Zapraszam!

 

pilot od TV — czujka TSOP 22xx + platforma pojazdu

Poznaliśmy odbiornik podczerwieni TSOP 2236. 

#define VCC 13
#define IR 12
#include <IRLib.h>
IRrecv pilot(IR);//pin
IRdecode dekoder;

void setup(){
  pinMode(VCC, OUTPUT);
  digitalWrite(VCC, 1);//wlaczamy napiecie dla odbiornika IR
  pilot.enableIRIn();//uruchamiamy odbiornik IR
  Serial.begin(9600);
}

void loop() 
{
   if (pilot.GetResults(&dekoder)) {
     dekoder.decode();    //dekoduj dane
     pilot.resume();     //restartuj odbiornik
     Serial.print("0x");      
     Serial.println(dekoder.value, HEX);//szesnastkowo - tak tylko...
   }//if
}/loop

W powyższym przykładzie zakładam, że pilot odbiornik IR podłączony był bezpośrednio do płytki Arduino o tak:

co jest bardzo stabilne i (warto podkreślić) nie wymaga płytki stykowej. Wszystko zgodnie ze specyfikacją – odbiornik IR dostaje zasilanie 5V z pinu #13 Arduina, a wymagany prąd to tylko 5mA (czy pamiętasz, jakim maksymalnie prądem można obciążyć piny cyfrowe Arduino?). Dlatego na początku kodu pojawia się deklaracja VCC i włączenie tego pinu. Reszta zgodna z biblioteką IRLib – nie musimy bawić się w dekodowanie sygnału, wszystko zostało zrobione przez Chris Younga – dziękujemy!

Dodatkowo: zbudowaliśmy platformę pojazdu, którą za tydzień – będziemy sterować pilotem od TV. Jak widać stawiam na prostotę i możliwość późniejszej rozbudowy – dlatego nasze pojazdy są dość sporych rozmiarów. Zachęcam do tego typu prac ręcznych.

Kolejne zajęcia – także we wtorek 16:00 – sterujemy pilotem platformą – nie zapomnijcie przynieść ze sobą pilota od TV/radia/odkurzacza.  Zapraszam!

 

silniczki DC + fotorezystor

Sterujemy szybkością silniczka światłem – dlatego zaczęsliśmy od

  • zbudowania dzielnika napięć z fotorezystorem
  • wczytywaniu napięcia z tego dzielnika na port analogowy Arduino
  • podłączenie L298N z silnikiem
  • wybranie pinu PWM do sterowania szybkością obrotów
  • przydatna funkcja skalująca wartości z jednego zakresu na drugi: map

A oto i bohaterowie naszych zajęć:

Kolejne zajęcia – także we wtorek 16:00 – sterujemy dwoma silnikami za pomocą światła.  Zapraszam!

 

„Cudowne” radyjko internetowe za jedyne 650 zł :P

Będąc na jednym z poratali (sportowych) zostałem uraczony reklamą – jedną z takich inteligentnych, co to pasują do gustu klienta. No i faktycznie – sprzęt elektroniczny zdarza mi się przeglądać w necie, więc reklama trafiona.

ADVANCE ACOUSTIC WTX-MICROSTREAM


Czyli co to takiego? otóż jest to ODTWARZACZ SIECIOWY WI-FI Z RADIEM INTERNETOWYM.  Wow. Chwalą to za

  • mała gabaryty, 
  • 24-bitowym przetworniku cyfrowo-analogowym Wolfson WM8740,
  • obsługę formatów audio : ALAC, FLAC, APE, APPLE LOSSLESS,AAC, AAC-LC,HE-AAC,WAV, MP3, WMA,
  • możliwość transmisji w zakresie od 48kHz/16bit do 192kHz/24bit, 
  • dedykowaną aplikację na iPada i Androida.

Nie powinienem się czepiać, ale to wszystko za cenę 650 zł. Przepraszam, ILE? Tak, nie pomyliłem się – 650 pln.

Nie jestem audiofilem, więc może nie doceniłem serca układu – przetwornika Wolfsona. Słucham radia online (i innej muzy) przez Raspberry Pi i oprogramowanie Music Player Deamon (wraz z klientem mpc i MPDroid na Androidzie, Sonata pod Linuxem). Wiem wiem, jakość dzwięku z RPi jest krytykowany przez wielu znawców i nawet ja czasami dostrzegam różnicę. Ale za trzykrotnie mniejsze pieniądze mam to wiele z tego, co oferuje reklamowane „cudo”. No i różnice są słyszalne wówczas, gdy ma się odpowiednio dobre źródło muzyczne – a wiele, wiele radyjek nadaje w 92kbps czy nawet w 64kbps. Wówczas nie ma co zwalać winy na Malinę. A gdy już nawet to nam przeszkadza, to zawsze można dokupić zewnątrzną kartę muzyczną na USB i to chyba rozwiązuje ten problem. 

Czyli zachęcam do zakupu Raspberry Pi także i z powodu słuchania muzy – już nie wspomnę o wielu innych funkcjach tego kompuera, których oczywiście nie obsługuje przesadnie drogie użądzenie. Warto uczyć się obsługi Linuxa by potem nie kupować takich gadgetów.

autor: K.G.

 

silniczki DC + moduł L298

Ponownie programowaliśmy silniczek DC, tym razem wykorzystywaliśmy moduł na bazie L298. Przypomnieliśmy sobie kilka istnych rzeczy:

  • wczytywanie znaków z klawiatury do Arduino – funkcja Serial.read() 
  • pisanie „niechluje” instrukcji warunkowej w C/C++
  • wczytywanie liczb z klawiatury – funkcja Serial.parseInt()
  • podłączenie modułu L298 do koła i bateryjki — sprawdzamy, czy rozumiemy jak to działa
  • jeśli rozumiemy, to podłączamy do Arduino
  • prosty program włączający obroty silnik w jedną stronę na czas 1 sekundy, a potem w stronę przeciwną (też na czas 1 sek) i tak w kółko
  • modyfikacja programu na wczytywanie liczb: liczba 0 silnik stop, liczba <0 — silnik w jedną stronę, liczba >0 silnik w przeciwną stronę
  • kolejna modyfikacja o uwzględnienie sterowania szybkością obrotów – wczytujemy liczbę z przedziału -255..255 i sterujemy nie tylko kierunkiem obrotów, ale też i szybkością
  • przy okazji zachęciłem do wirtualnego Arduino na www.circuits.io

A oto i bohater naszych zajęć:

Znalezione obrazy dla zapytania modul l298

Kolejne zajęcia – także we wtorek 16:00 – sterujemy silnikiem za pomocą światła.  Zapraszam!

 

silniczki DC + sterownik L293N

 

Zajęliśmy się silniczkami prądu stałego i przypominając sobie nawet najprostrze programiki dla Arduino udało się nam:

  • praca z multimetrem – mierzenie prądu płynącego przez działający silniczek – uwaga na odpowiednie nastawy zakresów pomiaru  
  • zwrócenie uwagi na wydajność prądową pinów cyfrowych Arduino oraz pinu zasilającego 5V
  • omówienie układu L293 – sterownik silnika (mostek H) – jego zalety? warto pamiętać!
  • budowa układu na płytce stykowej i „oprogramowanie” go w Arduino 
  • regulacja szybkości obrotów – pin PWM
  • regulacja szybkości ze zwiększonym zasilaniem silniczka (2x 6V) –  wcale nie spaliliśmy nasz silniczek!

Kolejne zajęcia – także we wtorek 16:00 – budujemy nasz pojazd.  Zapraszam!

 

fotorezystor + oscyloskop (processing, finał bis)

Oscylockop – finał „bis”

Sesja powoli za nami… a my wróciliśmy do fotorezystora i wykresów. Oto co udało się nam powtórzyć:

  • praca z multimetrem – mierzenie oporności, napięcia
  • dzielnik napięć na płytce stykowej – wyliczanie oczekiwanego napięcia i sprawdzanie multimetrem
  • dzielnik napięć z fotorezystorem
  • podłączenie Arduino do naszego dzielnika i wypisywanie odczytów na ekran
  • zamiana liczb całkowitych z portu analogowego Arduino na konkretne wartości napięcia – porównanie z multimetrem
  • zmiana programu w Arduino: stosujemy protokół wysyłania liczb całkowitych, omawiany na wcześniejszych zajęciach
  • uruchomienie processinga z prostym oscyloskopem i cieszenie się wykresem! 

Kolejne zajęcia – także we wtorek 16:00 – czujka pola magnetycznego + niespodzianka. Zapraszam!

 

RaspberryPi czy inne? Sopine-64, Asus Tinker Board

Dla tych, co chcą być na czasie – od siebie dodam, że tylko na RPi jest darmowa wersja Wolfram Mathematicy – a to bardzo dużo. Proszę zwrócić też uwagę na Asus-a: duży producent, a wypuszcza komputer praktycznie bez supportu 😛 

sopine-64

Asus Tinker Board 

Bardzo ciekawa propozycja:

  1. znany producent=gwarancja jakości, wsparcia (teoretycznie); jakość widać na pierwszy rzut oka – taki drobiazg jak oznaczenie portów GPIO kolorami – miłe i praktyczne; wspracie? no właśnie… jest Debian + KODI, ale cała reszta niewiadoma! brrrr
  2. świetne parametry! na papierze „bije” RPi v3 dwukrotnie (2GB RAM DDR3, 4 rdzenie 1.8GHz – ale w praktyce tak nie jest: jeden z filtrów w GIMPie kończy działanie w 10.1s na ASUSie, a na RPI v3 w 11.7s — i gdzie tu ta super wydajaność? 
  3. cena w Botlandzie to 399 zł (koniec lutego 2017 r) — oby nie za dużo? 
  4. zwracam uwagę na ciekawy filmik YT z unboxingu i uruchomienia Debiana – niech zainteresowani obejrzą i zdecydują.

Pozwolę sobie podsumować dzieło ASUSa następująco: fajne, ale o prawdziwej sile komputera decyduje oprogramowanie i wsparcie społeczności – a tego jak na razie brak.

Processing — oscyloskop (finał)

Oscyloskop

Kontynuujemy tworzenie oscyloskopu w processingu. Skupimy się na ostatnich barkujących elementach -kreska przesuwająca się w trakcie zbierania pomiarów, napisy na ekranie oraz obsługa myszy (historia wartości). 

Animacja kreski

Chcę dodać kreskę (od góry ekranu do dołu, u mnie kolor żółty, linia bardzo cienka – na 1 pixel) przesuwającą się z lewa do prawa podczas działania naszego oscyloskopu. Przedstawia to sekwencja poniższych obrazków:

     

Rozwiązań jest wiele, a my proponujemy następujące:

  1. kasujemy starą kreskę w pozycji xPos (czyli rysujemy ją kolorem tła),
  2. rysujemy dalszą część właściwego wykresu, 
  3. rysujemy nową kreskę w pozycji xPos+skokX (naszym ulubionym kolorem).

Te trzy kroki powodują, że nie musimy „odświerzać” całego ekranu dla każdego kawałka krzywej na oscyloskopie (tj. nie musimy rysować całego wykresu od początku, bazując na wcześniej zapamiętanych wartościach otrzymywanych z Arduino). To rozwiązanie jest proste i działa fajnie, dlatego je stosujemy.

void draw(){
 int x=getValue(); 
 print("z Arduino x=",x);
 y=wspA*x;
 
  strokeWeight(1);  //grubość kreski = 1 pixel
  stroke(0);  //kasowanie = kolor ekranu 
  line(xPos, 0, xPos, height);

  strokeWeight(10);// grubość kreski dla wykresu
  stroke(0,0,255); //kolor wykresu
  line(xPos - skokX, poprzedniY, xPos, y);

  strokeWeight(1); //ponownie grubość kreski
  stroke(0,0,200);// moj ulubiony kolor
  line(xPos+skokX, 0, xPos+skokX, height);
   
   xPos=xPos+skokX;
   if (xPos>=width){
     xPos=0;
     background(0);
   }
}

Na uwagę zasługuje

  • ciągła „zabawa” z kolorami i grubościami linii – oddzielnie dla kreski, oddzielnie dla tworzonego wykresu (no i kasowanie kreski musi mieć tą samą grubość, co nasza pionowa kreska).

Napisy

Są niezbędne, aby szybko orientować się jakie wartości są rysowane – mamy wszak możliwość skalowania osi y, czyli zawężania/zwiększanie widocznego zakresu. Dodatkowo, można (a nawet wypada) pisać wartość aktualnie otrzymaną z Arduino. Modyfikujemy funkcję setup() dodając (gdzieś na koniec) następujące linie

PFont f;
f = createFont("Arial",16,true); // Arial, 16 point, anti-aliasing on
textFont(f,36);

W powyższym kodzie przygotowujemy processing do pisania teksów – posługujemy się pomocniczą zmienną f (bez większego znaczenia). Aby pisać napisy używamy 

fill(0,0,100); //zmieniamy kolor teksu, jeśli chcemy
textSize(36); //zmieniamy rozmiar tekstu, jeśli chcemy
text("gawryl", 10,100); //piszemy tekst "gawryl" w pozycji x=10, y=100

Funkcja text() ma spore możliwości, dlatego warto zajrzeć do jej instrukcji. Można nawet używać jej w ten sposób:

int i=17;
text(i, 10,100); //piszemy liczbę całkowitą i
text(3.0*i, 10, 200); //piszemy liczbę rzeczywistą
float f=3.14;
text(f, 10, 300);//piszemy liczbę rzeczywistą

Jak widać konwersja typów na napisy następuje automatycznie – to bardzo ułatwia sprawę pisania tekstów. Proponuję testować poznane możliwości – ale szybko dojdziemy do etapu, gdzie napisy nachodzą na siebie, przekrywają się, są nieczytelne i należy je wyczyścić.

Czyszczenie napisów

Postępowanie podobne do metody z animowaną linią (z początku zajęć) nie jest jednak zadawalające. Chodzi o to, że skoro zdecydowaliśmy się na wyeliminowanie czyszczenia ekranu do minimum i kasowanie poprzenich napisów polega na pisanie ich ponownie kolerm tła – to jednak pozostają jakieś pozostałości. Dlatego… proponuję ograniczyć obszar wykresu tylko do części okna, a nie do całej dostępnej szerokości x wysokości okienka. Dzięki temu zabiegowi będziemy mogli bezkarnie czyścić obszar przeznaczony do napisy (zielony prostokąt na rysunku), a pozostawiać w spokoju właściwy wykres (obszar z czarnym tłem). Aby to zobrazować popatrzmy na rysunek:

Proponuję więc, aby każdorazowo funkcja draw() rysowała prostokąt (u mnie w kolorze zielonym) w określonych pozycjach, kasując całą zawartość tam się znajdującą. Następnie nowe napisy moga być już wypisywane wewnątrz tego prostokątu, bez brzydkich artefaktów z poprzedniej metody. Dalej następuje rysowanie właściwego wykresu i pionowej kreski, od której rozpoczęliśmy nasze zajęcia.

Pomysł z zielonym obszarem oczywiście wymaga zmiany współczynników skalowania wspAwspB prostej dopasowującej wczytany x z Arduino na współrzędną y okienka processinga. Powodzenia!

Historia wykresu

Chodzi o to, aby można było zatrzymać kreślenie wykresu (to już mamy obsługiwane) a dodatkowo aby można było lewym klawiszem myszy kliknąć i sprawdzić (wypisać w zielonym obszarze) wartość wykresu. Musimy więc pamiętać poprzednie pomiary – będziemy je przechowywać w pomocniczych tablicach. Dlatego wprowadzamy zmienne globalne

int[] values;
float[] times;

void setup(){

Deklarację tablic values oraz times umieszczamy gdzieś na początku kodu, aby zmienne te były widoczne wewnątrz wszystkich funkcji poniżej – a więc setup(), getValue() oraz draw(). Następnie modyfikujemy funkcję setup() o utworzenie konkretnych rozmiarów tych tablic:

values = new int[width];
times = new float[width];

Nie wnikając w zawiłości dynamicznego przydzielania pamięci – powyższe linie tworzą teyle elementów tablicy values oraz times, jaka jest szerokość naszego okienka z wykresem. Przy okazji widać, że skoro Arduino nadaje do nas liczby z zakresu 0..1023 to na ich przechowywanie przygotowałem tablicę liczb całkowitch, natomiast druga tablica przechowuje liczby rzeczywiste. Ta druga tablica będzie notować mi czas odebrania (w sekundach) przez processing konkretnej liczby – bardzo przydatne w późniejszej pracy z oscyloskopem.

Modyfikujemy funkcję odbierającą dane z portu szeregowego o fragment wypełniający nasze tablice:

int getValue(){
  int value = -1;
  while (port.available() >= 3){
    if (port.read() == 0xff){
       value = (port.read() <<8) | (port.read());
       values[xPos]=value;
       times[xPos]=millis()/1000.0;
    }//if
  }//while
  return value;
}//getValue

Zdecydowałem się na zapisywanie liczb do tablic z wykorzystaniem zmiennej xPos – takie rozwiązanie jest sprytne, ale będzie pociągało za sobą pewne następstwa. Przy okazji poznajemy nową funkcję processinga millis() – która, podobnie jak w Arduino, zwraca czas działania programu w milisekundach – dzięki temu zapisujemy czas „odebrania” danej nadesłanej z Arduino. Liczbę tą dzielę przez 1000.0 aby mieć wartość w sekundach (z przecinkiem – jak w Polsce lubimy).

Obsługa myszy – historia

Mówiliśmy o obsłudze myszy sprawdzając zmienną mousePressed – dzięki czemu wiemy, że wciśnięto przycisk myszy. Ale taki sposób stosujemy wewnątrz funkcji draw(), a my chcemy zatrzymać kreślenie wykresu (pomijając wywołanie funkcji draw()) a jednocześnie obsłużyć zdarzenia z myszy. Dlatego proponuję zrobić to tak:

void mousePressed() {
  int i = (mouseX/skokX)*skokX;
//pomocnicze linie
  print("x= ",mouseX,i); 
  print(" historia= ",values[i]); 
  println(" ", i]);
//właściwe wypisywanie
  fill(0,200,0);//kolor czyszczenia prostokata
  rect(0,height-50, width, height);
  fill(255);//kolor dlugopisu
  text(times[i], 300, height-20);
  text(values[i], 200, height-20);
}

Specjalna funkcja o nazwie mousePressed() będzie wywoływać się automatycznie za każdym razem, gdy mysz będzie klikana. My musimy wpisać tylko odpowiedni kod.

Mój kod ma aż 3 linie pomocniczych wypisywań — do usunięcia w finalnej wersji programiku. Zmienna i potrzeba mi jest po to, aby przeliczyć współrzędną x-ową kursora myszki na odpowiedni indeks w tablicy – wszak nasz oscyloskop wyposażyliśmy w możliwość rysowania punktów rzadko lub gęsto (decyduje o tym zmienna skokX, obsługiwana z klawiatury). Skoro więc dwuktornie odwołuję się do tego samego indeksu, wypisując wartość times oraz values – nawet w finalnej wersji, pozbawionej pomocniczych print-ów –  to nie liczę tego każdorazowo, tylko przechowuję go w zmiennej.

Ja swoje napisy rysuję 20 pikseli od dołu ekranu, w pozycjach 200 i 300 (licząc od  lewej strony). To jest w obszarze mojego „zielonego prostokąta”.

Czego się dziś nauczyłeś

  • pisanie tekstów
  • tworzenie dynamicznych tablic
  • (inna) obsługa myszy

(ciągle) pozostaje kilka kwestii do rozwiązania:

  • poprawne wczytywanie liczb (z Arduino wysyłamy 0..1023, a processing „widzi” tylko jakieś małe liczby, <30?)
  • skalowanie wykresu – czyli chcemy mieć tak, by liczby z zakresu 0..1023 zawsze mieściły się na ekranie, a nie „wyskakiwały” poza aktualną wysokość ekranu
  • skalowanie minimalnej liczby (więcej skalowań)
  • przesuwanie wykresu góra/dół (więcej skalowań)
  • obsługa myszki i wyświetlanie dowolnych wartości z historii wykresu
  • pisanie napisów w oknie processinga (np. liczb z wartościami na wykresach)
  • pisanie skali na wykresie (np. mL i ML z brzegu okienka)
  • podpis osi x – można użyć czasu do opisu tej osi, będzie widać kiedy odebrano konkretną daną
  • ładniejsza grafika

Zapraszam na kolejne zajęcia, na których podłączymy nasz oscyloskop do czujki pola magnetczynego oraz do fotorezystora.