komunikacja SPI (radiówka nRF24L01)

Komunikacja SPI

(Wpis ten jest reaktywacją wpisu z 2017 r. Okazało się, że warto podzielić oryginalny wpis na dwie mniejsze części – jedna dotycząca komunikacji I2C, druga SPI właśnie).

Tutaj https://www.arduino.cc/en/reference/SPI można poczytać czym jest protokół SPI. Nam wystarczy, że jest to szybka komunikacja synchroniczna na krótki dystans, wykorzystująca przynajmniej 3 linie nazwane MISO, MOSI i SCK. Dodatkowo są jeszcze linie CE i SCN. Jeśli więc w jakimś module zobaczymy tak nazwane piny – to znak, że działa w standardzie SPI właśnie. 

Specjalne piny SPI w Arduino to MISO (12 w Arduino), MOSI (11 w Arduino) oraz SCK (13 w Arduin0). Inne piny – CE i CSN są dowolne cyfrowe (występuje różne nazewnictwo – SS to Slave Select i odpowiada CE, który musi działać jako OUTPUT, w odróżnieniu od CSN). W poniższym przykładzie wybrałem 9 i 10 – a dlaczego? okaże się to później (na kolejnych spotkaniach naszego koła). 

nRF24L01+

Bardzo fajny moduł (no i bardzo tani – około 5 zł, co w porównaniu do modułów Bluetooth jest 1/5 ceny) – ale najpierw trzeba wiedzieć, jak podłączać go do Arduino:

UWAGA: zasilanie VCC jest z przedziału 3.3V-3.6V – podłączając do Arduino 5V USZKODZISZ moduł.

Oprogramowanie? Ponownie jest kilka bibliotek, ja użyłem nRF24L01.h by TMRh20. Jak poprzednio – doinstalowujemy do naszego Arduino IDE i tworzymy program odbierający dane:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(9, 10);//CE, CS
const byte rxAddr[6] = "grzyb";

void setup()
{
  Serial.begin(9600);
  Serial.print("nRF24 INIT=");
  bool ok=radio.begin();
  Serial.println(ok);
  radio.openReadingPipe(0, rxAddr);
  
  radio.startListening();
}

char text[32];

void loop()
{
  if (radio.available())
  {
    radio.read(&text, sizeof(text));
    
    Serial.print("t=");
    Serial.print(millis()/1000);
    Serial.print("s, text=");
    Serial.println(text);
  }
}

W linii 6 nadalismy nazwę naszemu strumieniowi – dowolne 5 znaków, niekoniecznie musi być tak jak u mnie… Ale nadajnik też musi nadawać na tym samym „paśmie”:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>

RF24 radio(9, 10);//CE, CS

uint8_t rxAddr[6] = "grzyb";

void setup()
{
  Serial.begin(9600);
  Serial.print("nRF24 INIT=");
  bool ok=radio.begin();
  Serial.println(ok);
  printf_begin;
  radio.printDetails();
  radio.setRetries(15, 15);
  radio.openWritingPipe(rxAddr);
  
  radio.stopListening();
}

char text[] = "Fiza:         OK!";

void loop()
{
  radio.write(&text, sizeof(text));
  text[7]=48+rand()%10;  
  text[8]=48+rand()%10;
  text[9]=48+rand()%10;
  text[10]=48+rand()%10;
  text[11]=48+rand()%10;
  Serial.println(text);
  delay(3000);
}

Maksymalna długość jednorazowo przesłanego napisu wynosi 32 bajty, a inne ważne rzeczy – w dokumentacji (zachęcam do czytania). 

Problemy? Modyfikacje? 

Np. problem ze zrywaniem połączenia – ludzie piszą o niestabilnym napięciu z pinu 3.3V Arduino oraz o problemie z prądem (pin 3.3V może maksymalnie dać tylko 50mA), dlatego dodają dodatkowy kondensator (mały, np 4.7 μF, 10 μF) do zasilania modułu:

Mogą pojawić się też problemy z anteną, więc albo kupujemy moduł z „wypasioną antenką”:

albo samodzielnie robimy sobie antenkę:

Polecam zajrzeć tutaj aby poczytać o problemach i różnych sposobach ich rozwiązywania, a także o oprogramowywaniu tego moduły.

(c) K.G. 2017, 2019

Pojazd sterowany — działa na radio!

Pojazd sterowany – nRF24L01

Pan Przemek oprogramował pojazd – działa przez radiówkę! Na razie sterowanie odbywa się przy pomocy 4-rech przycisków, a „grzybek” nie jest jeszcze oprogramowany. Od czegoś trzeba było zacząć 😉

Chwilowo nie zgłaszamy problemów z opóźnieniami spowodowanymi tekstowym protokołem – zobaczymy, co będzie dalej. Powyżej warsztat pracy Pana Przemka – jak widać kontroler jest minimalistyczny, a temat stworzenia fajniejszego pozostawiamy na później. Prace nad pojazdem sterowanym przez radio idą w bardzo dobrym kierunku. Za tydzień upgrade Maskotki, a potem nowe podwozie (+ modyfikacje serwomechanizmów do pracy ciągłej).

PM2D3D – małe kroczki, nowe wózki

Przełączenie sterowników silników krokowych na 1/16 kroku (poprzednio: 1/8 kroku) poskutkowało cichszą pracą, lekko wolniejszą – ale za to dokładniejszą (mniej „chwiejnych” linii). Poniżej fajny wydruk:

Dodatkowo trwają prace nad kolejną zmianą konstrukcji – nowe wózki, wydrukowane w 3D, mają zastąpić te z profili Makerbeama.  Zobaczymy co wyjdzie.


Więcej o projekcie PM2D3D na dedykowanej stronie.

(c) K.G.

Kontroler do pojazdu — tekstowy protokół

Pojazd sterowany – nRF24L01

Pan Przemek dalej kombinuje z komunikacją radiową na bazie układu nRF24. Jako nową zabawkę dostał JoyShield-a do Arduino, o takiego:

Jest to bardzo ciekawy układ, bo nie dość, że ma joystick oraz 7 przycisków (4 duże, kolorowe, jeden w joysticku, oraz 2 małe – mikrostyki), to ma jeszcze adaptery na radiówkę nRF24 (i inne też, ale tego nie tykamy). Wszystko złożone w „kanapkę” może pełnić funkcję kontrolera – po przyczepieniu bateryjki 9V (np. gumką recepturką).

Tekstowy protokół — kodowanie

Bazujemy na protokole tekstowym – shield odczytuje położenie joysticka, oraz 5 przycisków (chwilowo nie obsługujemy wszystkich). Dane wysyłane są przez nRF24 jako tekst, a poszczególne pola oddzielone są średnikiem. Jedna paczka danych wygląda więc tak:

507;512;0;1;1;0;0;

gdzie pierwsza liczba określa położenie joy-a na osi X, druga na osi Y, a kolejne zera i jedynki to stan logiczny 5-ciu przycisków. Bardzo proste w utworzeniu tego napisu — dzięki klasie String i jego licznie przeciążonych konstruktorach, oraz operatorowi „dodawania”.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
 
RF24 radio(9, 10);//CE, CS
 
uint8_t rxAddr[6] = "grzyb";
 
void setup(){
  Serial.begin(9600);
  Serial.print("nRF24 INIT=");

  bool ok=radio.begin();
  Serial.println(ok);
  radio.setRetries(15, 15);

  radio.openWritingPipe(rxAddr);  
  radio.stopListening();

  //dla modulu JoyShield
  pinMode(2, INPUT);
  pinMode(3, INPUT);  
  pinMode(4, INPUT);  
  pinMode(5, INPUT);  
  pinMode(6, INPUT); 
}
 
char bufor[32];
String napis;
 
void loop(){
  //tworzymy napis wedlug naszego protokolu 
  napis = String(analogRead(A0)) + ";" + String(analogRead(A1)) + ";" + String(digitalRead(2)) + ";" + String(digitalRead(3)) + ";" + String(digitalRead(4)) + ";" + String(digitalRead(5)) + ";"  + String(digitalRead(6)) + ";";

  //przygotowujemy bufor -- tablice z napisem...
  napis.toCharArray(bufor, 32);

  //wazne! wysylamy bufor a nie napis!
  radio.write(&bufor, sizeof(bufor));
}

Ponieważ radio wysyła dane w postaci tablicy, nie możemy wysyłać obiektu napis. Dlatego korzystamy z metody toCharArray() klasy String i przekopiowujemy zawartość napisu do bufora – tablicy. W „eter” wysyłamy tablicę bufor.

Tekstowy protokół — odczyt

No właśnie, prostota użycia napisów pociąga za sobą „problem” odczytywania takich danych. W grę wchodzą bardzo przydatne metody klasy String:

  • indexOf(napis) — zwracająca pozycję napisu w danym stringu (u nas napis to średnik, którym oddzielaliśmy liczby)
  • length() — zwracająca długość stringu
  • remove(od, do) — ucinająca napis od pozycji od do pozycji do
  • substring(od, do) — zwracająca podciąg w danym napisie, od pozycji od do pozycji do
  • toInt(napis) — zamienia napis na liczbę całkowitą (int)

Poniżej program dekodujący nasz protokół – czyli zamieniający napis na

int x,y;
byte b1,b2,b3,b4,b5;

Napis wczytany z klawiatury, przez komunikację szeregową – dzięki temu możemy testować nasz program na różne sposoby (o przeniesieniu tego kodu na radio — będzie za tydzień).

void setup() {
  //dane wprowadzamy z klawiatury przez Serial
  Serial.begin(9600);
}

String tekst;
String ciag;
char znak = ';';//separator pola
int x,y; //wspolrzedne x,y
byte b1,b2,b3,b4,b5;//stan 5 przyciskow
int k,l;//pomocnicze

unsigned long int t1,t2;

void loop() {
 if(Serial.available()>0){
    tekst=Serial.readString();
    Serial.println(tekst);

    t1=micros();
    k=tekst.indexOf(znak);
    ciag=tekst.substring(0,k);
    x=ciag.toInt();
    l=k+1;
    
    k=tekst.indexOf(znak,l);
    ciag=tekst.substring(l,k);
    y=ciag.toInt();  
    l=k+1;
    
    k=tekst.indexOf(znak,l);
    ciag=tekst.substring(l,k);
    b1=ciag.toInt();
    l=k+1;

    k=tekst.indexOf(znak,l);
    ciag=tekst.substring(l,k);
    b2=ciag.toInt();  
    l=k+1;

    k=tekst.indexOf(znak,l);
    ciag=tekst.substring(l,k);
    b3=ciag.toInt();  
    l=k+1;

    k=tekst.indexOf(znak,l);
    ciag=tekst.substring(l,k);
    b4=ciag.toInt();  
    l=k+1;

    k=tekst.indexOf(znak,l);
    ciag=tekst.substring(l,k);
    b5=ciag.toInt();  
    l=k+1;
    
    t2=micros();
    
    Serial.print("Pozycja X: ");
    Serial.println(x);
    Serial.print("Pozycja Y: ");
    Serial.println(y);
    Serial.print("PRZYCISK 1: ");
    Serial.println(b1);
    Serial.print("PRZYCISK 2: ");
    Serial.println(b2);
    Serial.print("PRZYCISK 3: ");
    Serial.println(b3);
    Serial.print("PRZYCISK 4: ");
    Serial.println(b4);
    Serial.print("PRZYCISK 5: ");
    Serial.println(b5);
    Serial.print("czas dekodowaia [mikrosekundy]= ");
    Serial.println(t2-t1);
  }//if
}//loop

Tekstowy protokół — szybkość dekodowania

Wielokrotne użycie powyższych funkcji powoduje, że odkodowanie napisu 507;512;0;1;1;0;0; i zamiana go na

int x, y;
byte b1,b2,b3,b4,b5;

zajmuje dla Arduino UNO od 260 do 550 mikrosekund (czyli ~0.5ms). A dlaczego nie jeden, równy czas? Bo w zależności od postaci dekodowanego napisu mikrokotrolerek musi więcej lub mniej pracować. Mniej „męczy” się w przypadku ciągu 1;1;1;0;0;0;0; a więcej w przypadku 1012;1017;0;0;0;1;1; Dobra, zrozumiałe. A czy to duży czas? Dla człowieka to nic, dla elektroniki sporo… Czy to nam wystarczy – czy nie spowoduje opóźnień (tzw „lagów”) w sterowaniu pojazdem? O tym przekonamy się po zastosowaniu tego protokołu do pojazdu (za tydzień).

Tekstowy protokół: modyfikacje — suma kontrolna

Można pomyśleć o rozbudowie naszego protokołu na dodatkowe „pole”, będące sumą kontrolą. Jeden z pomysłów to wysumowanie wszystkich danych (w końcu to liczby całkowite) i zapisanie tej sumy jako ostatni, dodatkowy element. Dla naszego przypadku wyglądałoby to tak: 507;512;0;1;1;0;0;1021; Po stronie odbiornika dekodujemy napis, liczymy sumę x+y+b1+b2+b3+b4+b5 i porównujemy z ostatnią wartością – nazwijmy ją sumak. A Jeśli nie ma równości… odrzucamy (ignorujemy) paczkę danych i czekamy na kolejną.

Tekstowy protokół: modyfikacje — protokół binarny

Lepiej by było stworzyć podobny protokół ale binarny, czyli nie bawić się w zapis liczb w postaci stringów, dodatkowo oddzielać je przecinkami tylko wysyłać x,y jako integer, a przyciski b1,b2,b3,b4 i b5 jako byte (nie 5 bajtów, a jeden – wszak 1 bajt = 8 bitów, mamy więc nadam zapas). Zyskujemy na tym mniejsze porcje danych – wszystkie informacje z JoyShielda to tylko 5 bajtów, a nie 14 (najlepszy przypadek) czy nawet 20 bajtów (najgorszy przypadek). No i nie ma zabawy w dekodowanie danych z wykorzystaniem metod klasy String… Ale to może przy innej okazji 😉

(c) K.G.

Płyta główna do Maskotki part 2

Chaos wewnątrz Maskotki zostaje ujarzmiony… ciągle sporo pracy… ale kto nie strajkuje, ten coś robi 😉 Wersja poweekendowa Pana Bartka:

A tutaj wersja z dzisiejszych zajęć:

Czego nie widać to miejsca mocowania wewnątrz obudowy Maskotki, ale nie ma sprawy. Jeszcze tylko konektory do silników i jest porządek! Kto dopatruje się logo śledzia? 😉

Dodatkowo, mamy nową wersję dmuchawy (w świecie WIRTUALNYM, projekt 3D – Pan Bartek):

No i w REALU (wydruk 3D – Pan Bartek, drukarka Ender 3):

Turbina jest (jak widać, po prawo) znacznie większa od tej z zeszłego tygodnia i… znacznie „dmuchawniejsza” 😀 Co więcej, nie trzeba już nawierać otworu fi-3.17mm, bo projekt 3D już to uwzględnił. Jednak… testy na 15% mocy (12V, 3A) pokazały, że jest OK tylko do pewenego momentu… Przy dalszym zwiększaniu mocy (doszedłem do 2A i 50% mocy) wiatraczek stracił przyczepność z wałem 😛 Trzeba było ponownie kombinować, jak go umocować, aby się nie oderwał. Znowu poszły cieniutkie nitki z przewodów (wielo-nitkowych), które jednak… zdały egzamin częściowo. Po chwili kręcenia na maksa (wow! po raz pierwszy 100% mocy!) nitki się przepaliły i silnik kręcił się sobie, a wiatraczek sobie. Lipa. Trzeba coś kombinować. Jak widać jest zabawa 😉

(c) K.G. 2019

Płyta główna do Maskotki, turbina 3D, radiówka nRF24 oraz LOGO!

Chaos wewnątrz Maskotki powoli zostaje ujarzmiony… jednak to sporo pracy, ale jak na razie jest zapał! Najpierw powstał projekt płyty głównej (oczywiście po burzliwej naradzie):

..potem rozebranie działającego układu:

…ciężka praca nad modułami zasilania:

a dążymy do poskładania tego wszystkiego na jednaj płycie:

Przy okazji – co to produkcja bez znaku firmowego? Taka płyta główna powinna mieć swoje  LOGO. Więc powstał wstępny projekt, który trzeba chyba umieścić na tej dużej powierzchni właśnie tworzonej płyty głównej (w końcu ta biała przestrzeń musi być zapełniona!). Acha – wszelkie skojarzenia z logo nadgryzionego jabłka są tylko przypadkowe 😉

Ma powstać coś takiego:

Idąc słowami klasyka: nie tylko na zewnątrz ma być elegancko, wykonanie wnętrza ma być też nienaganne, estetyczne i perfekt! (kto wie o kim mówię – śmiało w komentarzach, będą nagrody!).

Natomiast Pan Łukasz i Mateusz wprowadzeni zostali w świat sieci 2.4GHz i komunikacji bezprzewodowej… Była o tym mowa w innych latach o module nRF24L, ale dla nich to nowość. OK, czekam więc na wykonanie pracy domowej (bezprzewodowa wieżyczka z laserem + protokół kompikacyjny 7-mio literowy).

Co się tyczy Dżina Stefana to pomysł przeewaluował do balona-niespodzianki, trochę bardziej militarny temat ale też z pazurem 😉 zobaczymy! Na razie Pan Bartek wydrukował wentylator do silnika bezszczotkowego, gdyż śmigła od drona były lekko przerażające (no i niebezpieczne!).

Z mocowaniem trzeba było kombinować… wychodzi na to, że trzpień silniczka ma średnicę 3.17mm, a takowego wiertła nie posiadaliśmy (mam jedynie 3.08mm). Więc otwór wyszedł lekko za duży – spytacie: „małym wiertłem? jak to?” Otóż trzeba było trochę „pogibać” aby otwór był większy 😉 no i wyszedł lekko za duży 😛 Więc na „klina” dodałem nitki… z przewodów elektrycznych (kto zdzierał izolację z przewodów ten wie, że (często) składa się on z wielu mikro-przewodów – i to właśnie je wykorzystałem). No tak, ale z taką kombinowaną produkcją nie odważyłem się zakręcić więcej niż 20%. Wiało nieźle. Dobrze mieć LEJ kierujący powietrze centralnie do góry. Wniosek z tego taki, że trzeba projektować turbinę, lej (prowadzący powietrze) a także i kratkę ochronną – przed przypadkowym oderwaniem/zerwaniem turbiny z trzpienia.

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

(c) K.G. 2019

joyshield + stringi + nRF24

Dziś nowy gadget:

czyli joy-shield. Co to ten „shield”? To rozszerzenie, z różnymi modułami, które nadrukowane są na płytkę PCB i nie wymagają płytki stykowej i masy przewodów. Taką płytkę „wtyka” się w piny Arduino, tworząc „kanapkę”. Ten shield ma „gierkowe” przeznaczenie – choć my go wykorzystamy do sterowania pojazdem, ale są też inne (do internetu przez kabel eRJotkę, przez sieć bezprzewodową, z kartą SD do zapisu danych, z obsługą silników i inne). Warto łapać okazję na allegro lub podobnych, bo ja swój shield kupiłem za 25 zł! A co on ma w sobie?

  • Joystick (dwie osie + przycisk)
  • cztery przyciski z kolorowymi klawiszami
  • dwa dodatkowe przyciski microswich
  • złącze dla modułów transmisji radiowych:
    — nRF24xx
    —  xbee
    — APC200
  • stabilizator napięcie 3.3V (do zasilania układów radiowych)

Oczywiście moduł (=shield) przeznaczony do współpracy z płytkami Arduino UNO, MEGA, LEONARDO itp. Warto zwrócić uwagę na jakość wykonania – mój ma fajne opisy w łatwo dostępnych miejscach.

Obsługa joysticka – shielda

Okazuje się banalnie prosta. Czytamy położenie dwóch osi (x i y) – czyli porty analogowe A0 i A1 (cóż, ten shield je sobie „rezerwuje” i nie mamy ich możliwosci wykorzystywania). Wszystko ładnie opisane na płytce. Podobnie z przyciskami.

void setup() {
Serial.begin(9600);
}
int x,y;
void loop() {
  x=analogRead(A0);
  y=analogRead(A1);
  Serial.print(x);
  Serial.print("  ");
  Serial.print(y);
  if (digitalRead(5)==1)
    Serial.print(" niebieski");
  if (digitalRead(4)==1)
    Serial.print(" bialy");
  if (digitalRead(3)==1)
    Serial.print(" czerwony");
//i tak dalej
  Serial.println();
  delay(100);
}

Zwracam uwagę na „sprytne” granie metodą print oraz println wraz ze spacjami tak, aby wszystko mieściło się w jednej linii i nie było „pozlepiane”.

A odczytywanie przycisków – skoro używam funkcji digitalRead(pin) to dlaczego nie ma wcześniej pinMode(pin, INPUT)? Otóż domyślnie piny ustawione są w trybie INPUT, dlatego właśnie nic nie dopisywałem. Jesto to warte zapamiętania, co powino nie być trudne – w końcu dla wejść analogowych nie ustawialiśmy w tryb INPUT, czyli z wejściami cyfrowymi jest tak samo.

Stringi = napisy

Temat rzeka… trzeba zacząć, czym są tablice w C. Zauwazyłem, że godnym polecenia jest artykuł na oficjalnej stronie Arduino. Ja dołączam „zrzut ekranu” z zajęć.

Jak zmienić nasz poprzedni kod, aby działał na napisach?

void setup() {
   Serial.begin(9600);
}

String napis;
void loop() {
  napis=String(analogRead(A0));
  napis = napis + "  ";
  napis = napis + String(analogRead(A1));
  if (digitalRead(5)==1)
    napis = napis + String(" niebieski");
  if (digitalRead(4)==1)
    napis += String(" bialy");
  if (digitalRead(3)==1)
    napis += String(" czerwony");
  //i tak dalej
  Serial.println(napis);
  delay(100);
}

Oczywiście nic tutaj nie zyskaliśmy, a nawet gorzej – obsługa klasy String w Arduino jest zasobożerna – czyli mocno powiększa nasz kod, ale tym się jeszcze nie przejmujemy. Na uwagę zasługuje łatwe dodawanie (łączenie) ze sobą napisów – realizuje to zwykły operator + (plus)

Joyshield + nRF24L01+

Łączymy poznane dziś rzeczy z poprzednimi zajęciami i nadajemy to, co robimy na naszym kontrolerze. Właśnie dlatego użyliśmy wersji Stringowej kodu do joysticka, bo radyjko nadawało właśnie napisy – a nawet napisy z maksymalną długością 32 znaków (bajtów). Poniżej kod:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>

RF24 radio(9, 10);//CE, CS

uint8_t rxAddr[6] = "grzyb";

void setup(){
  Serial.begin(9600);
  Serial.print("nRF24 INIT=");
  bool ok=radio.begin();
  Serial.println(ok);
  printf_begin;
  radio.printDetails();
  radio.setRetries(15, 15);
  radio.openWritingPipe(rxAddr);
  
  radio.stopListening();
}

String napis;

void loop(){
  napis = String("Heniek "); 
  napis += String(analogRead(A0));
  napis += " ";
  napis += String(analogRead(A1));
  if (digitalRead(5)==1)
    napis += String(" niebieski");
  if (digitalRead(4)==1)
    napis += String(" bialy");
  if (digitalRead(3)==1) 
    napis += String(" czerwony");
  //i tak dalej<br>
  radio.write(napis.c_str(), napis.length());
  Serial.println(napis);
  delay(100);
}

Na uwagę zasługuje linia nr 37, gdzie musiałem użyć nowej metody klasy String o nazwie c_str(), której zadaniem jest stworzenie napisu w stylu języka C (nieobiektowego). Wymuszone jest to przez metodę write() klasy radio. Dodatkowo, długość napisu w klasie String uzyskujemy za pomocą metody length() – a nie sizeof(napis), gdyż to by zwróciło tylko rozmiar obiektu (a nie danych wewnątrz tego obiektu).

Z kolei w linii 26 rozpocząłem nasz napis imieniem (fikcyjnym) uczestnika koła Fi-BOT tak, aby uruchomiony przeze mnie program odbiornika nRF mógł łatwo zidentyfikować kto mi nadaje (Tosiek, Heniek czy Ziuta — także fikcyjne imiona).

Co dalej?

Wydawać by się mogło, że trzeba teraz tak przygotowany kod uruchomić do sterowania pojazdem. Nieprawda. Było by to baaaardzo kłopotliwe. Problem polega na tym, że trzeba odczytać napis w odbiorniku nRF umieszczonym w pojeździe, a potem odczytać aktualne wychylenie osi X i Y joya, i przyciski. Ale to trudne! Nawet przy pomocy funkcji toInt() zamieniającej napis na liczbę całkowitą – bo najpier należało by podzielić nasz napis na części – może przecinkami, jakoś tak:

123,512,czerwony,zielony

Czyli wówczas przecinek (kropka, myślnik – cokolwiek) by nam oddzielał jedną informację od drugiej, co by było do wykorzystania w połączeniu z metodą indexOf() z klasy String. Cała procedura mogła by wyglądać jakoś tak:

  • odczytujemy napis w pojeździe, przesłany przez joyshield (z przecinkami)
  • skupiamy się na pierwszej części napisu, aż do pierwszego przecinka – wiemy, że ma to być pozycja na osi X – funkcja StringSubstring() i/lub wspomniana indexOf()
  • zamieniamy ten krótki podciąg (od zera do 4 znaków) na liczbę całkowitą – metoda toInt() – i mamy już oś X
  • kasujemy/wyrzucamy z napisu pierwszą część do przcinka, przechodzimy do pozycji na osi Y
  • robimy podobnie, a potem
  • jeśli napis nie jest jeszcze pusty (bo ciągle kasowaliśmy informację o osi X i Y), to znaczy, że mamy jakieś przyciski
  • jeśli jest przecinek, to znaczy, że są nawet dwa (lub więcej) wciśniętych przycisków
  • tworzymy pierwszy podciąg aż do pierwszego przecinka, porównujemy czy jest to „zielony”, „czerwony” itd…
  • po odczytaniu przycisku kasujemy z napisu tą informację
  • jeśli napis niepusty, to są kolejne przyciski…

Proszę zwrócić uwagę, jakie to zagmatfane! Dlatego na kolejnych zajęciach będziemy wysyłać z nadajnika nie napisy (Stringi), ale bajty z informacjami. Dwa bajty wystarczą do podania osi X, kolejne dwa do osi Y, a jeszcze jeden – tylko jeden – do podania stanu wszystkich 7 przycisków na naszym shieldzie. Stworzymy własny protokół danych – podobny do tego, jakiego używaliśmy przy omawianiu oscyloskopu. Dlatego zachęcam do ponownego wczytania się w tamten wpis i opis protokołu danych. Właśnie to nas czeka na następnych zajęciach! Ekscytujące, nieprawdaż? 😉

Przypominam o spotkaniu w ten piątek 19-maja o 14:15 w sprawie XV Festiwalu, a kolejne zajęcia we wtorek 23 maja o godz. 16:15. Nie wiem, czy będziemy mieć siły na 22 więc od razu uprzedzam, że w poniedziałek 22 maja, podczas imprezy Festiwalowej, ustalimy termin kolejnego spotkania Fi-BOTa. Zapraszam!

 

komunikacja I2C oraz SPI — LCD i nRF24

Dziś sporo o sposobach komunikacji innej niż UART – poznajemy  I2C oraz SPI.

Powyżej „zrzut ekranu” naszych zajęć 😉

Komunikacja I2C

Przeniesiona tutaj.

Komunikacja SPI

Przeniesiona tutaj.

Co dalej?

Oczywiście nic nie stoi na przeszkodzie by połączyć oba poznane dziś urządzenia – i zamiast wyświetlania na monitorze PC-ta (przez port szeregowy) wyświetlać na LCD-ku 16×2…. My na nastepnych zajęciach zastąpimy sterowanie naszymi pojazdami z czujki na podczerwień na wspomnianą właśnie komunikację radiową.

Mam nadzieję, że te nowe „zabawki” (klocki) rozbudzą Waszą wyobraźnię 😉

Kolejne zajęcia w dniu 16-maja o godz. 16:15.  Zapraszam!

(c) K.G. 2017

P.S.

Wpis edytowany w listopadzie 2019: komunikacja I2C oraz SPI przeniesiona do dówch oddzielnych części, bo (jak się okazało) – studenci dość często z tego korzystali.

 

„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.