Przetwarzanie i wizualizacja danych z Arduino
Projektując jakieś urządzenie za pomocą Arduino, często zachodzi konieczność obserwowania różnych odczytów i wyników działania naszego programu. Pierwsze co przychodzi nam do głowy to skorzystanie z możliwości monitorowania portu szeregowego do którego "wyrzucamy" nasze dane. Metoda ta jest bardzo wygodna, jednak bywa niewystarczająca.
Jak wiemy port szeregowy pozwoli nam tylko na obserwację wyników jedynie w trybie tekstowym - prezentując je linijka po linijce. Co jednak w przypadku, gdybyśmy chcieli widzieć odczyty temperatury na ładnym wykresie albo zaprezentować działanie akcelerometru? Z pomocą przyjdzie nam program Processing 2.
Przetwarzanie i wizualizacja wyników.
Processing 2 to program napisany w języku Java (podobnie jak IDE do Arduino) wspomagający nas w wizualizacji odbieranych danych na porcie szeregowym (ale i nie tylko). Program dostępny jest za darmo zarówno dla platformy Windows, Linux jak i MacOS. Wystarczy go tylko pobrać, rozpakować i uruchomić. Jego wygląd bardzo przypomina znane nam już IDE od Arduino.
Zanim jednak przystąpimy do wizualizacji naszych danych, wypadałoby w odpowiedni sposób wysłać nasze dane z Arduino na port szeregowy. Jak to zrobić?
Joystick
Jako przykład, posłużymy się odczytem położenia w osi X/Y drążka joysticka analogowego. Jego konstrukcja jest banalnie prosta - drążek osadzony jest na dwóch potencjometrach, zmieniających swoją rezystancję w zależności od wychylania w wybranej osi. Podłączenie ogranicza się jedynie do podpięcia zasilania, masy oraz wyjść X i Y. Przedstawiona wersja joysticka posiada jeszcze przycisk, który uaktywnia stan niski na odpowiedni pin po wciśnięciu drążka.
Prosty program dla Arduino
Program jest banalnie prosty - będziemy odczytywać pomiar z dwóch wejść analogowych i jednego wejścia cyfrowego. Następnie wyślemy wyniki do portu szeregowego:
- int xValue = 0; // wartość odczytu osi X
- int yValue = 0; // wartość odczytu osi Y
- int bValue = 0; // wartość odczytu przycisku
- void setup()
- {
- Serial.begin(9600); // Otwieramy port szeregowy
- pinMode(2, INPUT); // Konfigurujemy Pin 2 jako wejście
- }
- void loop()
- {
- // Odczytujemy wartości portu analogowego A0 i A1
- xValue = analogRead(A0);
- yValue = analogRead(A1);
- // Odczytujemy wartość stanu logicznego na pinie 2
- bValue = digitalRead(2);
- // Wyświetlamy nasze dane, oddzielając je przecinkiem
- Serial.print(xValue,DEC);
- Serial.print(",");
- Serial.print(yValue,DEC);
- Serial.print(",");
- Serial.print(!bValue,DEC);
- // Kończymy znakiem nowej linii ułatwiającym późniejszą analizę
- Serial.print("\n");
- // Małe opóźnienie przed następnym pomiarem
- delay(2);
- }
Na porcie szeregowym otrzymamy dane, które będziemy mogli odebrać w Processing 2 i odpowiednio przetworzyć.
Wizualizacja w Processing 2
Kiedy mamy już działający projekt, a dane wysyłane są już na port szeregowy, możemy przystapić do odebrania ich w Processing 2 i pokazać w zupełnie inny sposób. Jako, że przykładem jest joystick, będziemy chcieli pokazać położenie naszego drążka oraz wyświetlić odebrane wyniki. Zobaczmy jak będzie wyglądał nasz program tym razem:
- import processing.serial.*; // importujemy bibliotekę serial
- Serial myPort; // definiujemy port
- int x; // zmienna przechowująca wartość z A0
- int y; // zmienna przechowująca wartość z A1
- int b; // zmienna przechowująca wartość z cyfrowego pinu 2
- PFont f; // defincja zmiennej czcionki
- String portName;
- void setup()
- {
- size(512, 512); // rozmiar okna
- // portName = Serial.list()[0]; // wybieramy nazwę portu 0 z listy dostępnych
- portName = "/dev/ttyACM0"; // lub jeśli znamy jego nazwę
- // otwieramy port
- myPort = new Serial(this, portName, 9600);
- // wybieramy czcionkę i rozmiar
- f = createFont("Arial", 16, true); // Arial, 16px, anti-aliasing
- textFont(f, 16); // rozmiar 16px
- }
- // pętla rysująca
- void draw()
- {
- fill(0); // ustawiamy kolor wypełnienia na czarny
- clear(); // czyścimy ekran
- fill(255); // ustawiamy kolor wypełnienia na biały
- if (b == 1) // sprawdzamy czy wciśnięto przycisk
- {
- // rysujemy okrąg większy o określonych współrzędnych
- ellipse(x/2, 512-(y/2), 50, 50);
- } else
- {
- // rysujemy okrąg mnieszy o określonych współrzędnych
- ellipse(x/2, 512-(y/2), 25, 25);
- }
- // wyświetlamy dane
- text("AnalogX="+(1023-x)+" AnalogY="+(1023-y),10,20);
- }
- // obsługa danych z portu szeregowego
- void serialEvent(Serial port)
- {
- // odczytujemy dane do momentu wystąpienia znaku nowej linii n
- String input = port.readStringUntil(10);
- if (input != null)
- {
- // rozbijamy odczyt po przecinku i nowej linii
- int[] vals = int(splitTokens(input, "\n"));
- // przypisujemy do zmiennych
- x = vals[0];
- y = vals[1];
- b = vals[2];
- }
- }
Po uruchomieniu programu, możemy już obserwować co się dzieje w naszym projekcie:
Git? Git :)
Dodatkowe informacje:
Przykłady, dokumentację oraz sam program, znajdziecie na stronie domowej: https://processing.org/
Reklama
Komentarze
Witam.
Mam problem z tym programem. Program Processing wyrzuca mi taki błąd: "Error, disabling serialEvent() for COM5
null"
W programie ustawiłem wybór portu na automatyczny.
Co może być nie tak?
Czy automatycznie wybrany prot COM5 zgadza się z faktycznym portem?
A w jakim sposób mogę to sprawdzić? Podpinałem kabel pod każdy z portów USB i taki sam błąd wywala.
Port powinien być taki sam jaki widnieje Ci przy flashowaniu pod IDE
U mnie "płytka" jest na com 7, a w processingu ustawiam na 1
i wszystko gra :)
Niestety u mnie ten sam błąd w Arduino IDE mam podany COM7 i w Processingu też podaję COM7 i ten błąd: "Error, disabling serialEvent() for COM10
null"Być może to wina Windowsa... Sprawdzę później na Linuxie jak to działa.
i jak rozwiązałeś ten problem z tym błedem Error, disabling serialEvent() for COM3
null"
bo u mnie tez sie pojawia i program nie pokazuje nic???
poniewaz jest blad w programie ,w lini 57 powinno byc :
int[] vals = int(splitTokens(input, ","));
i zeby dzialal dobrze przycisk w programie na arduino dopisac w linie 26 : Serial.print(",");
Thank you ,very usefull blog