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.