#menuh{float:none;} body{behavior:url(csshover.htc); font-size:75%;} #menuh ul li{float:left; width: 100%;} #menuh a{height:1%;font:bold 1.1em/1.4em helvetica, arial, sans-serif;}


Soros átvitel – adat továbbítás


Idáig már volt szó az adatfogadásról, most nézzük meg, hogy oldható meg az adatok küldése arduinora. Mint a fogadás úgy a küldés is a soros átvitellel kivitelezhető. Az arduino-ra a következő progi kerül fel:

char val;
void setup() {
pinMode(13,OUTPUT);
Serial.begin(9600);
}
void loop() {
if(Serial.available()){
val = Serial.read();
}
if (val == '1')
digitalWrite(13,HIGH);
else
digitalWrite(13,LOW);
delay(10);
}


Sok mindent nem kell magyarázni a programról. A beépített ledet használjuk a (13 kimenet) visszajelzésre.

if(Serial.available()) – sor figyeli a soros porton történő változásokat, ha adat érkezik azt beolvassa a val változóba. Ha val változó az 1-es karaktert tárolja akkor a 13-as kimenet magas állapotba kerül, a led világít. Ha viszont más karaktert olvas be akkor alacsony állapotba kapcsolja a kimenetet.

Most nézzük a processing kódunkat:

import processing.serial.*;
Serial myPort;

void setup(){
size(200,200);
String portName = Serial.list()[2];
myPort = new Serial(this, portName, 9600);
}
void draw(){
if (mousePressed == true){
myPort.write('1');
println('1');
}else{
myPort.write('0');
println('0');
}
}

A soros port kezelését már át tárgyaltuk az előző leckékben, még egyszer azért elmondom a Serial.list()[2]; -es hely az én COM4-es portomra vonatkozik. Ez mindenkinél egyéni, figyeljétek meg melyik port-ra csatlakozik az arduino alaplap és ezt a port-ot írjátok be, vagyis azt a helyet ahányadikként az arduino IDE port listájába feltűnik.

A size(200,200); – paranccsal nyitunk egy ablakot és majd ezt figyeljük az
if (mousePressed == true) sorral. Ha egérgomb lenyomás történik (mindegy, hogy jobb vagy bal) akkor a soros portra kiíratunk egy 1-es karaktert, ha felengedjük a gombot akkor egy nulla továbbítódik.
A soros kiíratással párhuzamosan a konzolra is kikerül az elküldött karakter.

Ha elindítjuk a sketchet és az ablak területén belül lenyomjuk bármelyik egérgombot akkor az arduino beépített ledje világítani fog, egérgomb felengedése után elalszik. Evvel meg is valósítottunk egy adattovábbítást a pc-ről az alaplap felé.

Készítettem ehhez a leckéhez egy grafikus felületet, ahol három gomb segítségével lehet különböző értékeket küldeni az arduinora.

Először a processing kód:

import processing.serial.*;
Serial myPort;
int state = 1;
int[] rectX = {30,30,30};
int[] rectY = {30,70,110};
int[] ellip = {40,80,120};
String[] led = {"Led ON","Led Off","Blink"};

void setup(){
myPort = new Serial(this, "COM4", 9600);
size(250,150);
background(#2E641F);
}

void draw(){
fill(#30FA38);
textSize(16);
text("LED KAPCSOLÓK", 30,17);
stroke(#031F09);
strokeWeight(3);
fill(255);
for(int i=0;i<3;i++){
rect(rectX[i],rectY[i],100,20);
fill(0);
text(led[i],rectX[i]+10,rectY[i]+17);
fill(255);
ellipse(150,ellip[i],20,20);
}


if(mousePressed && (mouseButton == LEFT))
gomb(mouseX,mouseY);
if(state<3){
fill(#FA1258);
ellipse(150,ellip[state],20,20);
fill(255);
myPort.write(state);
}
}


void gomb(int x, int y){
int i=0;
while(i<3){
if(mouseX >=rectX[i] && mouseX <= rectX[i]+100 &&
mouseY >= rectY[i] && mouseY <= rectY[i]+20)
state = i;
i++;
}
}


A változók deklarálásánál létrehozunk négy tömböt is ami majd a kirajzolást könnyíti meg. A tömbök alapból fix értékekkel feltöltöttek.
int[] rectX = {30,30,30};
int[] rectY = {30,70,110};
int[] ellip = {40,80,120};
String[] led = {"Led ON","Led Off","Blink"};


Ezt a négy tömböt majd úgy tudjuk hasznosítani, hogy a tömbök adott számú elemei összetartoznak. Pl.: rectX[0], rectY[0], ellip[0], led[0] az első gomb kirajzolásához kellenek. Az 1-es számú elemek a második gomb, a 2-es számú elemek a harmadik gomb kirajzolását segítik.

A draw törzs első három sora az ablak név kiíratását segíti

fill(#30FA38);
textSize(16);
text("LED KAPCSOLÓK", 30,17);

A következő két utasítás az alakzatok keret színét és keret vastagságát adják meg:
stroke(#031F09);
strokeWeight(3);

Az ablak kirajzoltatása:
for(int i=0;i<3;i++){
rect(rectX[i],rectY[i],100,20);
fill(0);
text(led[i],rectX[i]+10,rectY[i]+17);
fill(255);
ellipse(150,ellip[i],20,20);
}

ahogy a tömböknél elmondtam, i=0 akkor kirajzolja az első nyomógombot feliratozza az első szöveg sztringgel és kirajzol mellé egy jelző lámpát. Aztán jön a második gomb amikor az i értéke egy lesz.
A kirajzolás után életbe lép a gomb területek figyelése, ezt a következő két sor valósítja meg:

if(mousePressed && (mouseButton == LEFT))
gomb(mouseX,mouseY);

Az első sor figyeli az egér változásait és a bal egérgomb lenyomását, ha ez igazzá válik (lenyomjuk a bal egérgombot) akkor meghívjuk a gomb nevű függvényt és átadjuk számára az egér pozíciós értékeit. A függvény leellenőrzi, hogy hol történt az egérművelet, ha gomb terület felett egy globális változót átállít a megfelelő értékre.

if(state<3){
fill(#FA1258);
ellipse(150,ellip[state],20,20);
fill(255);
myPort.write(state);
}

A feltétel ellenőrzi az adott globális változó értékét, ha ez a három gomb értékei közül valamelyikkel azonos, akkor végrehajtja a következő utasításokat: az adott gombhoz tartozó jelzőlámpa fényét átállítja és a soros portra kiírja az adott gombhoz tartozó értéket.

Az utolsó pár sor a gomb függvény:

void gomb(int x, int y){
int i=0;
while(i<3){
if(mouseX >=rectX[i] && mouseX <= rectX[i]+100 &&
mouseY >= rectY[i] && mouseY <= rectY[i]+20)
state = i;
i++;
}
}

Ami itt lényeges a feltételben megvizsgálja az egérpozíciója bent-e van
valamelyik gomb területén belül, ha igen akkor a gomb azonosítója bekerül a state globális változóba.
Amit aztán a főprogramtörzsben lévő feltétel feldolgoz.
Evvel végig is értünk a processing kódon, most jöjjön az arduino progi:

int adat;
long ido=0;

void setup() {
Serial.begin(9600);
pinMode(13,OUTPUT);
}

void loop() {
if(Serial.available())
adat = Serial.read();
switch (adat){
case 0:{
digitalWrite(13,HIGH);
break;
}
case 1:{
digitalWrite(13,LOW);
break;
}
case 2:{
if(ido+500 <= millis())
digitalWrite(13,LOW);
if(ido+1000 <= millis()){
digitalWrite(13,HIGH);
ido = millis();
break;
}
}
}
}


Itt is megint csak a 13-as kimenet beépített ledét hasznosítjuk.
Figyeljük a soros port változásait és adat továbbítás esetén beolvassuk azt az adat változóba:

if(Serial.available())
adat = Serial.read();

Aztán egy esetválasztó segítségével az adott értéknek megfelelő dolgot hajtatjuk végre az alaplapunkkal.

switch (adat){
case 0:{
digitalWrite(13,HIGH);
break;
}
case 1:{
digitalWrite(13,LOW);
break;
}
case 2:{
if(ido+500 <= millis())
digitalWrite(13,LOW);
if(ido+1000 <= millis()){
digitalWrite(13,HIGH);
ido = millis();
break;
}
}

az adat változó értéke 0 , akkor bekapcsoljuk a ledet, ha 1 akkor kikapcsoljuk, illetve ha 2, akkor félpercenként villogtatjuk. A villogtatás nem oldható meg delay() utasítással, ezért az eltelt időt kell figyelnünk egy segéd változó segítségével.

if(ido+500 <= millis())
digitalWrite(13,LOW);
if(ido+1000 <= millis()){
digitalWrite(13,HIGH);
ido = millis();


Nézzük alaphelyzet az ido változó értéke 0 ehhez hozzáadódik a +500, ha millis() értéke ennél nagyobb (több idő telt el) akkor végrehajtja az első utasítást kikapcsolja a ledet. Ha millis() értéke 1000-rel több mint az idő változóban tárolt érték akkor bekapcsolja a ledet, és az ido változó értékét egyenlővé teszi a millis() aktuális értékével.

Aztán kezdődik előröl az egész, és a ledünk villog.



Valahol itt van az alapja egy grafikus vezérlő felület készítésének, hogy hol van a felső határ azt mindenki döntse el önmaga, remélem ennél csak jobb dolgok születnek :)