Dziś opiszę ostatni element mojego projektu z NodeMCU i modułem KAmodLSM303, czyli aplikację na PC, która odbiera dane z akcelerometru za pośrednictwem modułu NodeMCU oraz sieci WiFi i wyświetla na ekranie model modułu KAmodLSM303 obrócony zgodnie z odczytami z czujnika LSM303.
Pozostałe części cyklu:
Do napisania aplikacji użyłem środowiska Processing, które umożliwia pisanie aplikacji na PC w sposób przypominający ten z Arduino, dodatkową zaletą jest to, że pisząc jeden kod tworzymy aplikację działającą od razu w systemach Windows, OS X oraz Linuksa. To znaczy – jak to zwykle bywa – prawie tak jest, w filmie chciałem pokazać aplikację działającą na Raspberry Pi, ale niestety problem z obsługą grafiki w aplikacjach Processing uruchamianych w Raspbianie ostudził mój zapał (możliwe jest ominięcie tego problemu, ale znalazłem ciekawsze rozwiązanie do łatwego generowania grafiki 3D na RPi, w miarę możliwości postaram się coś o tym napisać). No ale do rzeczy, środowisko Processing można pobrać ze strony jego twórców, ze względu na użycie biblioteki Object Loader musiałem użyć wersji 2.2.1, ponieważ biblioteka nie działa jeszcze prawidłowo z wersjami 3.0+.
import processing.net.*; import saito.objloader.*;
W pierwszej linii zaimportowana zostaje biblioteka pozwalająca programowi korzystać z połączeń sieciowych, objloader to biblioteka, która umożliwia importowanie modeli 3D w formacie obj.
Dalej deklarowane są zmienne globalne:
Client c; OBJModel model; int x, y, z;
Pierwsza zmienna to klient połączenia TCP, druga zmienna przechowuje zaimportowany model 3D, zmienne x, y i z będą zawierać wartości odczytane z akcelerometru modułu KAmodLSM303.
Kod funkcji setup wygląda następująco:
void setup() { size(640, 360, P3D); // wielkosc okna - 640x360 pikseli, P3D - uruchamiamy renderer 3D noStroke(); // wylaczamy widocznosc siatki w modelach 3D frameRate(30); // 30 ramek na sekunde model = new OBJModel(this, "KAmodLSM303.obj", "absolute", TRIANGLES); // importujemy plik obj z modelem 3D model.scale(10); // skalowanie modelu model.translateToCenter(); // przesuniecie modelu do srodka ukladu wspolrzednych c = new Client(this, "192.168.1.1", 111); // nawiazujemy polaczenie z NodeMCU pod adresem 192.168.1.1 na porcie 111 }
Do odczytu danych z modułu KAmodLSM303 za pośrednictwem modułu NodeMCU napisałem funkcję readKAmodLSM303, funkcja wysyła znak „A” do modułu (może to być dowolny inny znak), następnie odczytuje 6 bajtów. Bajty są sklejane z sobą w liczby 16-bitowe, następnie, jeśli liczba ma najstarszy bajt o wartości 1, odejmujemy od niej liczbę 65536, ta operacja ma na celu odczytanie liczb w kodowaniu U2. Na koniec odczytane wartości są uśredniane z poprzednio odczytanymi wartościami, ma to na celu zniwelowanie drgań, oczywiście można tu zastosować bardziej zaawansowaną technikę, ale do moich celów taki sposób w zupełności wystarcza.
void readKAmodLSM303() { byte coordsBytes[]; int xn, yn, zn; coordsBytes = new byte[6]; // wyślij zapytanie c.write("A"); // czekaj na odpowiedź while (c.available() < 6) delay(10); c.readBytes(coordsBytes); // przelicz bajty na U2 xn = coordsBytes[0] + (coordsBytes[1] << 8); if (xn > 32767) xn -= 65536; yn = coordsBytes[2] + (coordsBytes[3] << 8); if (yn > 32767) yn -= 65536; zn = coordsBytes[4] + (coordsBytes[5] << 8); if (zn > 32767) zn -= 65536; // usrednij odczytana wartosc z poprzednia wartoscia x = (x + xn)/2; y = (y + yn)/2; z = (z + zn)/2; }
Teraz zostaje tylko napisać funkcję draw, która na podstawie odczytów rysuje odpowiednio obrócony model.
void draw() { float roll, pitch; // odczytaj dane z akcelerometru readKAmodLSM303(); // oblicz obrot modelu roll = atan2(y, z); pitch = atan2(-x, sqrt(y*y + z*z)); // rysuj tlo background(30); // wlacz domyslne swiatla lights(); // dodatkowe swiatlo directionalLight(128, 128, 128, 0, 0, -1); // przesuniecie srodka ukladu wspolrzednych 3D na srodek ekranu translate(width/2, height/2, 0); // obrot o wyliczone katy rotateX(pitch + PI/2); rotateY(roll); // rysowanie modelu model.draw(); }
Płytki NodeMCU oraz KAmodLSM303 dostarczył sklep internetowy dla elektroników Kamami.pl.