Soros átvitel – adat fogadás


Kezdjünk bele: miért fontos nekünk a processing?

Mert grafikus felületet készíthetünk vele, ami segítségével PC-ről vagy akár androidról is adatokat küldhetünk és fogadhatunk arduinonkról.
Például egy lakásban elhelyezett hőmérők adatait jeleníthetjük meg a PC
kijelzőjén vagy termosztátokat kapcsolgathatjuk az adott felületről.
Soros adatátvitelt használunk, ezt az usb portok valósítják meg az usb kábelen keresztül.

Első fordulóban a processing soros portos adatfogadását vizsgáljuk meg.
Ehhez kell egy PC-hez kapcsolt arduino board amire egy soros portos kiíratást végző kis programot töltünk fel. Ez így néz ki:



void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("Itt vagy?");
delay(300);
}

Ehhez a processing felületén is kell egy rövid sketch-et írnunk ami majd fogadja a beérkező soros adatokat.
A processing megnyitása után először a soros könyvtárat kell beilleszteni:
Sketch menü /Import Library/Serial almenü pontot jelöljük meg.

Hatására a következő sor jelenik meg a sketch elején:

import processing.serial.*; //evvel importáljuk a soros könyvtárat.


Ha ez megvan írjuk be a következő programot:

import processing.serial.*;
Serial Port;
String adat;

void setup(){
String portName = Serial.list()[2];
Port = new Serial(this, portName,9600);
}

void draw(){
if(Port.available() > 0)
adat = Port.readStringUntil('\n');
println(adat);

}

Fussunk végig a sketch-en:
Serial Port; – létrehozunk egy Port nevű objektumot a Serial könyvtárban
String adat; – egy szöveg típusú adat nevű változó létrehozása, ez globális
változó ami a program teljes területéről elérhető.

A setup-ba lévő sorok:

String portName = Serial.list()[2]; – létrehozunk egy portName nevű szöveg típusú változót amibe az aktuális port lista elemeiből kiválasztjuk a nekünk kellőt.

Az aktuális port kiválasztása lista szerint a következő: az arduino IDE
Tools menü / Port almenüjében szerepel a megfelelő soros port amin keresztül kommunikál az alaplapunk. Nekem ez a COM4-es port, de a listában a harmadik helyen szerepel. Mivel a programozásban a számozás nullával kezdődik ezért az első elem a null számú, a második elem az egyes, a harmadik a kettes számozású. Nekem ezért lett a listába a kettes szám beírva.

Persze megoldhatjuk máshogy is ezt, ha kihagyjuk ezt a sort és csak a következőbe írjuk be a port nevét (COM4).

A progi szerinti port kezelés, portName változóval:
Port = new Serial(this, portName,9600); -- ezzel a sorral a Port objektumhoz hozzárendeljük a megfelelő fizikai portot és beállítjuk a soros átvitel bitsebességét.

A portName változó nélküli megoldás:
Port = new Serial(this, ”COM4”, 9600);


Nézzük a főciklust, a draw utasításait:

if(Port.available() > 0)
adat = Port.readStringUntil('\n'); – az első sor feltétel a Port objektum változásait figyeli, ha az objektum értéke nem nulla, vagyis adat érkezik a soros porton akkor az adat változóba bekerül a porton érkező értékek.

Mivel sztringekről beszélünk a '\n' jelzéssel jelöli az utasítás hogy csak egy sort( a sor törésig) olvasson be változónkba.

println(adat); – az utolsó utasítással kiíratjuk a konzol mezőbe az adat változó tartalmát.


Tehát az arduino-ra feltöltjük az arduino progit.
A processing-be beállítjuk az arduino soros portját.
Elindítjuk a processing kódot a start jelre kattintva.
Ha minden jól megy pár sec múlva elkezdenek megjelenni az üzenetek, ha figyelünk láthatjuk, hogy először null kiírat jelenik meg aztán ezt írja felül az arduino-s üzenetünk. Ha ezt kiakarjuk küszöbölni akkor a következő sorral bővítsük a sketch-et a println(adat) sor helyet :

if(adat != null)
println(adat);

Így csak akkor íródik ki az adat változó ha értéke nem nulla.


Fontos! Amíg fut a processing kód addig nem elérhető az arduino más alkalmazás számára a soros porton, az Arduino IDE számára se!

Ha módosítani akarjuk az arduino kódját, feltöltés előtt mindig le kell állítani a processing kód futását a stop gombbal.


Most nézzünk példát számbeli adatok fogadására.
Az arduino A0-s bemenetét használjuk, amire rákötünk egy potenciométert
A következő kódot töltsük fel az arduinora:

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

void loop() {
int analog_ertek = analogRead(A0)/4;
Serial.write(analog_ertek);
}


Azt hiszem mindenki számára érthető az analóg érték bekérése, itt fennakadást csak a néggyel való osztás okozhat. Ezt azért kell megtennünk mert a soros port csak 1byte-os értékeket képes így egyszerre átküldeni, ez pedig max.: 255 (1024/4). De most pillanatnyilag nem is kell több.


Serial.write(analog_ertek); – soros adat küldés (íratás), csak binárisan küld értékeket ezért is a 0-255 közé eső érték.


Nézzük a processing fogadó sketch-ét:

import processing.serial.*;
Serial myPort;

void setup(){
String portName = Serial.list()[2];
myPort = new Serial(this, portName, 9600);
}
void draw(){
int szam = myPort.read();
println(szam);
}


A soros port tulajdonságait beállító utasításokat már megbeszéltük, újdonság csak myPort.read() utasítás. Ezt 1byte-os adatfogadás (beolvasásra) használjuk.
A println(); kiírja az értéket a konzolra.


Ha elindítjuk a program futását azt vehetjük észre, hogy hiába forgatjuk a potenciométert nem fog változni a konzolra kiírt érték. Miért van ez?
A beolvasásnál a legelső érték (ahol indításnál a potid áll) eltárolódik a pufferbe és ez onnan nem tűnik el. Ezt látod folyamatosan kiíródni.

Kiküszöbölésére egy hurokkal kell kiegészítenünk a draw függvényt a következő módon:

void draw(){
while (myPort.available() > 0) {
int szam = myPort.read();
println(szam);
}
}

Evvel a módszerrel a poti változásaira azonnal reagálnak a processing kiíratott értékei is.


Nézzünk egy másik változatot igazi ablakban kiíratva:

import processing.serial.*;
Serial myPort;
int adat;

void setup() {
size(400,200);
myPort = new Serial(this, Serial.list()[2], 9600);
}

void draw() {
background(0);
text("Received: " + adat, 10, 50);
}

void serialEvent(Serial myPort) {
adat = myPort.read();
}


Változások az előzőhöz képest:

size(400,200); – nyít egy 400 pixel széles 200 pixel magas ablakot.

Text(”Receiver: ” + adat, 10, 50); – szöveget íratunk ki az ablakunkba, fixen a Receiver: feliratot és hozzáfűzve az adat változó tartalmát. A két szám adat első tagja a szöveg X kezdő koordinátája, a második tag az Y koordináta.

Számunkra igazán a következő függvény az érdekes:

void serialEvent(Serial myPort) {
adat = myPort.read();
}

ez figyeli a soros port változásait, és esemény esetén az adat változóba beolvassa a soros porton küldött adatott.


Evvel lezárult a második lecke, folytatjuk a következőkben.