Az ATMega8 által a soros porton keresztül érkező adatokat akarjuk grafikusan megjeleníteni. Ehhez először azt kell kideríteni, hogy az általam használt USB-TTL átalakító által létrehozott COM17-es virtuális soros porthoz a Processing milyen sorszámot rendelt. Az alábbi kis Processing program kilistázza az elérhető soros portokat:
Processing kód:
import processing.serial.*;
Serial myPort; // Create object from Serial class
println(Serial.list()); // This will print a lisi of serial ports
A képről látható, hogy a COM17 sorszáma a [2]. A Processing kódban, amikor létrehozzuk a soros kapcsolatot, akkor ezzel a sorszámmal tudunk hivatkozni a COM17-es portra.
Grafikus adatábrázoló rutin Processing-gel
Azért, hogy az AVR-t ne nagyon terheljük le, csak a nyers mérési eredményeket küldjük a PC-re, az adatok feldolgozása (amelyekkel az AVR csak igen lassan boldogulna) a Processing-gel történik majd. Nézzük meg, hogyan!
Amint azt korábban már láthattuk, az AVR kódja elég egyszerű: a soros porton keresztül kapott parancs után (`m` karakter) beolvassa a gyorsulásmérő analóg kimeneteit, majd az eredményt UART-on keresztül elküldi a PC-re. Ezt felhasználhatjuk a Processing-gel történő szinkronizálásra egy ún. call-and-response módszert használva. Az AVR nem méri és küldi magától folyamatosan a gyorsulásmérő jeleit a Processing-nek. Mert nem akarjunk azt feleslegesen leterhelni. Az AVR csak akkor végez el egy mérést és továbbítja annak eredményét a PC felé, ha előtte a Processing-től erre utasítást kap.
Ennek megfelelően a Processing programunk főbb lépései a következők lesznek:
- egy `m` karakter küldésével arra utasítja az AVR-en futó kódot, hogy végezzen el egy mérést
- a mérés eredményét UART-on keresztül küldje el a PC-re, a Processing-nek
- a Processing a soros porton beérkező adatokat egy pufferbe olvassa mindaddig amíg egy “újsor” `\n` karaktert nem kap
- a beérkezett adatokat a vesszőknél szétválasztja, majd újra számokká alakítja
- a számokat a Processing kód grafikusan megjeleníti
A program futása közben az `x` , `y` vagy `z` billentyűt lenyomva kiválaszthatjuk hogy melyik tengely mentén mért értékeket jelenítse meg a program.
Az alábbi ábra az X tengely értékeit mutatja. A gyorsulásmérőt vízszintes helyzetből indítva, először balra, majd jobbra döntöttem, majd ismét vissza a vízszintes helyzetbe.
(a videóhoz kattints a képre)
Az alábbi ábra az Y tengely értékeit mutatja. A gyorsulásmérőt vízszintes helyzetből indítva, először előre, majd hátra döntöttem, majd ismét vissza a vízszintes helyzetbe.
(a videóhoz kattints a képre)
Az alábbi ábra a Z tengely értékeit mutatja. A gyorsulásmérőt vízszintesen tartva, először gyorsan felfelé, majd lefelé mozgattam.
(a videóhoz kattints a képre)
A fent látható grafikus adatábrázoló Processing kódja:
/* Grafikus adatabrazolas Processing-gel
- az x billentyu lenyomasakor az X tengelyen mert adatok lesznek abrazolva a grafikonon
- az y billentyu lenyomasakor az Y tengelyen mert adatok lesznek abrazolva a grafikonon
- az z billentyu lenyomasakor az Z tengelyen mert adatok lesznek abrazolva a grafikonon */
import processing.serial.*;
Serial myPort;
int[] serialInArray = new int[3];
int i = 1;
int xpos, ypos, zpos = 0;
boolean firstContact = false;
void setup ()
{
size(400, 300); // ablak merete
// elerheto soros portok kilistazasa
println(Serial.list());
// azUSB-TTL atalakito COM17 port sorszama: [2]
myPort = new Serial(this, Serial.list()[2], 9600);
// a soros porton beerkezo adatokat "ujsor" karakterig puffereljuk
myPort.bufferUntil('\n');
// fekete hatterszin :
background(0);
// `m` karakter kuldese az AVR-nek, hogy vegezzen el egy uj merest
myPort.write('m');
}
void draw ()
{
// ha az AVR-tol nem erkezik valasz, akkor addig kuldjuk ujra az `m`-et, amig valasz nem erkezik
if (firstContact == false)
{
delay(300);
myPort.write('m');
}
}
void drawGraph ()
{
int valueToGraph = 0;
// kivalasztjuk, hogy melyik tengely erteket abrazoljuk
if (keyCode == 88) //x billentyu: x tengely
{
valueToGraph = xpos;
stroke(255,0,0);
}
if (keyCode == 89) //y billentyu: y tengely
{
valueToGraph = ypos;
stroke(0,255,0);
}
if (keyCode == 90) //z billentyu: z tengely
{
valueToGraph = zpos;
stroke(0,0,255);
}
// fuggoleges vonal megrajzolasa:
line(i, height, i, height - valueToGraph);
// a kepernyo szelenek ekeersekor visszaugras az elejere
if (i >= width-2)
{
i = 0;
background(0);
}
else
{
i++;
}
}
void serialEvent(Serial myPort)
{
firstContact = true;
// a bejovo adatokat beolvassuk egy pufferbe, amig egy ujsor karakter nem erkezik:
String myString = myPort.readStringUntil('\n');
// ha a bejuvo karakterek az ujsor karaktertol kulonbozoek, akkor a bejovo adatot a vesszoknel szetvalasztjuk es ujra szamma alakitjuk vissza
if (myString != null)
{
myString = trim(myString);
int sensors[] = int(split(myString, ','));
// ha mindharom tengely eredmenye megerkezett, akkor kivalasztjuk a megfelelot es abrazoljuk
if (sensors.length >= 3)
{
xpos = (sensors[0]*3)/8;
ypos = (sensors[1]*3)/8;
zpos = (sensors[2]*3)/8;
drawGraph(); // grafikon kirajzolasa
myPort.write('m'); // `m` karakter kuldese az AVR-nek, hogy vegezzen el egy uj merest
}
}
}
A cikk még nem ért véget, lapozz!
Értékeléshez bejelentkezés szükséges!