Sarjaliikenne ja käsittely
Sarjaluokka
Toiminnot, joissa käytetään sarjaliikennettä Käsittely määritellään luokassa Serial
. Ensimmäinen toiminto, joka suoritetaan käyttääksesi niitä ohjelmassa (luonnos) on sisällyttää se koodiin import processing.serial.*;
.
Luokka Serial
Siinä on viisi eri konstruktoria ilmoitetuista parametreista riippuen. Ainoa vaadittu parametri on pääobjekti (vanhempi), joka yleensä vastaa luokan pääohjelmaa (esimerkiksi ohjelmaikkunaa). PApplet
. Kuten yleensä, vanhempi on kirjoitettava ohjelma ( luonnos nykyinen), tämän ensimmäisen pakollisen parametrin arvo on this
.
Muut viisi parametria, jotka voidaan välittää rakentajalle ovat ① nopeus, ② sarjaportin nimi ③ pariteetti protokollassa käytettävät ④ databitit ja ⑤ lopetusbitit. Useimmin välitetyt parametrit vaaditun yläobjektin lisäksi ovat portin nimi ja nopeus.
La sarjaliikenteen nopeus on kokonaisluku (int
) että oletusarvo on 9600 jos tätä parametria ei välitetä rakentajalle.
Sarjaportit saatavilla. Luettelomenetelmä
El portin nimi on järjestelmän määrittelemä muoto tällä tavalla, esimerkiksi sisään Linux-jakelut tulee olemaan jotain sellaista /dev/ttyS4 / dev / ttyACM3 o /dev/ttyUSB1 (riippuen portin tyypistä), kun taas Windowsissa se on jotain tällaista COM12. Ellei porttia ole fyysisesti liitetty laitteeseen, ohjelma ei yleensä tiedä mitä porttia käyttää. Yleinen tapa valita portti on hankkia luettelo käytettävissä olevista porteista, näyttää se käyttäjälle ja antaa hänen valita haluamasi portti. Menetelmä Serial.list()
palauttaa vektorin tekstimerkkijonoista (String
) ja järjestelmässä olevien porttien nimet.
1
2
3
4
5
6
7
8
9
|
// Mostrar los puertos serie disponibles en el sistema
import processing.serial.*;
void setup()
{
noLoop(); // No iterar (no llama a draw periódicamente)
println(Serial.list());
}
|
Kirjaston oletusarvoisesti käyttämä portti Serial
on ensimmäinen menetelmällä palautetuista list
(varmasti COM1 Windowsissa tai /dev/ttyS0 en GNU / Linux). Lukuun ottamatta hyvin rajoitettuja yhteyksiä, joissa työstettävä laitteisto on tiukasti tunnettu (kuten järjestelmä kioskitilassa), sitä ei yleensä jätetä pois ja kohdeportti ilmoitetaan nimenomaisesti.
Yllä oleva kuvakaappaus näyttää järjestelmän lähdön GNU / Linux jossa on neljä sarjaporttia RS-232 (ttyS0 a ttyS3) ja viisi kahden tyyppistä sovitinta (ttyACM0 a ttyACM1 y ttyUSB0 a ttyUSB2).
Päästäkseen sarjaportteihin käyttäjän tulee kuulua siihen ryhmään, johon järjestelmä ne määrittää, normaalisti tty o valintaikkuna. Yllä olevan kuvan kuvakaappauksessa näet, että luettelossa olevat sarjaportit ovat ls /dev/tty[ASU]* -la
kuuluvat ryhmään valintaikkuna jolla on luku- ja kirjoitusoikeudet.
Sarjaprotokollan parametrit
La pariteetti sarjaviestinnästä ilmaistaan Käsittely hahmona (char
), joka voi ottaa arvot: ① N
(ei mitään) jotta et havaitse pariteetti, ② E
(jopa) osoittamaan, että pariteetti bitti on parillinen, ③ O
(pariton) osoittamaan, että pariteetti bitti on outoa, ④ M
(Merkitse) tehdäksesi aina pariteetti bitti ja ⑤ S
(tila) tehdäksesi aina yhden pariteetti bitti. Oletusarvo, jos sitä ei välitetä rakentajalle parametrina, on N
(synti pariteetti).
Määrä databittejä, joka on oletuksena kahdeksan, osoittaa bittien määrän, jotka muodostavat nettodatan hyötykuorman (kutsutaan merkiksi tai joskus sanaksi), joka lähetetään kehyksen jokaisessa perusyksikössä. Databittien lukumäärää ilmaiseva parametri ilmaistaan kokonaislukuna (int
).
Lopuksi viides mahdollinen parametri ilmaisee viimeisen arvosanan keston ilmaistuna stop bitit (stop bitit), joka on merkitty numerolla, joka on edustettuna liukuluku (float
), joka voi ottaa arvot 1.0
(oletusarvo, jos parametria ei välitetä rakentajalle), 1.5
tai 2.0
.
Serial-luokan rakentajat
Seuraava luettelo näyttää eri parametrien yhdistelmät, jotka voidaan välittää luokan rakentajalle Serial
:
Serial(padre)
Serial(padre,puerto)
Serial(padre,velocidad)
Serial(padre,puerto,velocidad)
Serial(padre,puerto,velocidad,paridad,bits_datos,bits_parada)
Lopeta sarjaliikenne. Pysäytysmenetelmä.
Vapauttaaksesi sarjaportin, joka on määritetty luomisen yhteydessä Serial
, ja että muut järjestelmäsovellukset voivat käyttää sitä, viestintä lopetetaan menetelmällä stop
, joka ei vastaanota parametreja.
1
2
3
4
5
6
7
8
9
10
|
import processing.serial.*;
Serial serie;
void setup()
{
noLoop(); // No iterar
serie=new Serial(this,“/dev/ttyUSB0”,9600); // Usar un puerto USB con un adaptador UART
serie.stop(); // Detiene las comunicaciones serie y libera el puerto ttyUSB0 para otros usos
}
|
Lähetä tiedot sarjaportin kautta. Kirjoita.menetelmä
Voit lähettää tietoja, luokka Serial
de Käsittely sisältää menetelmän write
jolla voit lähettää ① tekstijonoja (String
), ② tavua tai ③ tavuvektoria (byte[]
). Se on mielenkiintoista muistaa byte
en Käsittely (At Jaava) edustaa kokonaislukua välillä -128 ja 127, ja oletusarvoisesti merkkijonot käyttävät koodausta UTF-16.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import processing.serial.*;
Serial serie;
String texto=“Ohm”;
void setup()
{
noLoop();
serie=new Serial(this,“/dev/ttyUSB0”,9600); // Usar un puerto USB con un adaptador UART
serie.write(texto); // Envía el texto “Ohm”
serie.write(10); // Envía un fin de línea \n que corresponde con el ASCII 10
serie.write(200); // Envía el valor -56 ¡Es un byte, va de -128 a 127! (200-256=-56)
serie.stop(); // Detiene las comunicaciones serie y libera el puerto ttyUSB0 para otros usos
}
|
Lue tiedot sarjaportista
Jotta ohjelma voi suorittaa muita tehtäviä, kun tietoja vastaanotetaan sarjaportin kautta, on tavallista tallentaa a puskuri saapuvat tiedot ja lue se tarvittaessa. Vaikka se ei yleensä ole kovin tehokasta, voit pysäyttää sovelluksen ladataksesi kaikki saatavilla olevat tiedot. Yleisin asia on kuitenkin lukea tiedot sen saapuessa, joko jokaisessa iteraatiossa draw
, kun tietty määrä on saatavilla tai erikoiskoodi on vastaanotettu.
Puskurissa käytettävissä olevan tiedon määrä. Käytettävissä oleva menetelmä
Tietää, onko tietoja saapunut puskuri sarja, menetelmä available
palauttaa tähän jo tallennettujen tavujen määrän puskuri. Kummassakin tapauksessa lukutoiminnot voivat palauttaa erityisen arvon (esim -1
o null
), kun yrität ladata tietoja kohteesta puskuri sarja tyhjänä.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import processing.serial.*;
Serial serie;
void setup()
{
frameRate(1); // Llama a draw una vez por segundo
serie=new Serial(this,“/dev/ttyUSB0”,9600);
}
void draw()
{
print(“Hay “);
print(serie.available());
println(” bytes en el buffer serie”);
}
|
Lataa tavu kerrallaan. Lukumenetelmä
Luokan päämenetelmät Serial
jotka palvelevat sarjaportin vastaanottamien tietojen lukemista, ovat "tyyppiä read
» jotka eroavat toisistaan pääasiassa sen mukaan, minkä tyyppisellä tiedolla he toimittavat vastaanottamansa tiedot.
read
käytetään toimittamaan sarjaportin vastaanottamat tavut arvona 0 - 255. Tietotyyppinä byte
de Käsittely edustaa aluetta -128 ja 127 välillä eikä välillä 0 ja 255, on tarpeen käyttää int
edustamaan palauttamaa aluetta read
. Jos yrität lukea kanssa read
ja puskuri merkkijono on tyhjä, palauttaa arvon -1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import processing.serial.*;
Serial serie;
void setup()
{
frameRate(10); // Llama a draw 10 veces por segundo
serie=new Serial(this,“/dev/ttyUSB0”,9600);
}
void draw()
{
if(serie.available()>0)
{
println(serie.read());
}
}
|
Lue merkit sarjaportista. ReadChar-menetelmä
Menetelmä readChar
es samanlainen a read
mutta se palauttaa arvon muodossa char
a sijasta int
. Kuten sisäisesti, char
en Käsittely (At Jaava) tallennetaan kahdella tavulla. Arvo valitaan palautettavaksi, kun sitä luetaan readChar
mukaan puskuri tyhjä sarja on 0xFFFF
o -1
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import processing.serial.*;
Serial serie;
void setup()
{
frameRate(10);
serie=new Serial(this,“/dev/ttyUSB0”,9600);
}
void draw()
{
if(serie.available()>0)
{
print(serie.readChar());
}
}
|
Lataa tekstimerkkijono. Menetelmät readString ja readStringUntil.
Menetelmä readString
palauttaa objektin String
muodostetaan kaikista saatavilla olevista tiedoista puskuri sarjaa sen kuulemisen yhteydessä.
Menetelmä readString
luo tekstimerkkijonon olettaen, että sarjaportin vastaanottamat tavut ovat muodossa ASCII joten tätä lukumenetelmää ei voi käyttää muille koodauksille.
Jos kyse on lukemisesta puskuri sarjan kanssa readString
tyhjänä palautusarvo on null
.
Menetelmä readStringUntil
lisätä readString
kyky palauttaa laitteeseen ladatut tiedot puskuri sarja jakaa sen erikoismerkillä (koodilla), joka välitetään parametrina. Tämä tapa lukea vastaanotettua tietoa mahdollistaa sekä erottimet että terminaattorit, jotka auttavat tulkitsemaan vastaanotettua tietoa.
Menetelmä readStringUntil
tuo takaisin null
kun sisällä puskuri sarja ei löydä sille välitetyssä argumentissa määritettyä koodia (yksi tavu).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import processing.serial.*;
Serial serie;
String mensaje;
void setup()
{
frameRate(5);
serie=new Serial(this,“/dev/ttyUSB0”,9600);
}
void draw()
{
if(serie.available()>1)
{
mensaje=serie.readStringUntil(9); // Lee los datos del buffer hasta encontrar un tabulador
if(mensaje!=null) // Si la respuesta no es null ya ha llegado el tabulador y el mensaje está completo
{
println(“Mensaje recibido: “+mensaje); // Mostrar el mensaje si ha llegado completo
}
}
}
|
Seuraavassa koodissa Työläs lähettää kolme viestiä sarjaportin kautta. Kaksi ensimmäistä päättyvät välilehteen, joten ne näkyvät konsolissa. Käsittely, kun taas kolmatta, vaikka se lähetetään sarjaportin kautta, ei lueta kanssa readStringUntil(9)
koska se ei pääty välilehteen (koodilla ASCII 9).
1
2
3
4
5
6
7
8
9
10
11
12
|
void setup()
{
Serial.begin(9600);
while(!Serial);
Serial.print(“Primer mensaje\t”);
Serial.print(“Segundo mensaje\t”);
Serial.print(“Tercer mensaje”); // Este mensaje no llega porque no termina en tabulador
}
void loop()
{
}
|
Lue tietolohkoja. ReadBytes- ja readBytesUntil-menetelmät.
Yllä nähtyjä menetelmiä käytetään tietojen lukemiseen tietyissä muodoissa, raakatietolohkojen lukemiseen tai sellaisessa muodossa, jota ei ole määrätty Käsittely menetelmiä käytetään readBytes
y readBytesUntil
Menetelmä readBytes
yritä lukea saatavilla olevat tiedot puskuri sarja. Jos menetelmälle ei välitetä parametria readBytes
kaikki saatavilla oleva data luetaan ja palautetaan vektorissa (byte[]
). Jos parametrina välitetään kokonaisluku, luetaan enintään tämän luvun osoittama tavumäärä ja ne palautetaan myös vektorina.
On olemassa kolmas tapa käyttää readBytes
, tehokkaampi, joka ottaa argumenttina tavuvektorin, johon sisältö on puskuri sarja. Tämä tapa käyttää readBytes
palauttaa kokonaisluvun (int
), joka edustaa luettujen tavujen määrää.
Menetelmä readBytesUntil
toimii samalla tavalla, mutta sisältää ensimmäisen parametrin, joka edustaa sen tavun arvoa, joka, jos se löytyy puskuri, osoittaa lukemisen päättymisen. Tässä menetelmässä parametrilla, joka määrittää luettavien tavujen enimmäismäärän, ei ole järkeä, koska määrä määräytyy erikoiskoodin avulla.
Testaa menetelmän toimintaa readBytes
Oletetaan seuraava koodi Työläs joka lähettää tekstin sarjaportin kautta.
1
2
3
4
5
6
7
8
9
10
|
void setup()
{
Serial.begin(9600);
while(!Serial);
Serial.println(“En Viena hay diez muchachas, un hombro donde solloza la muerte y un bosque de palomas disecadas. Hay un fragmento de la mañana en el museo de la escarcha. Hay un salón con mil ventanas.”);
}
void loop()
{
}
|
Seuraava esimerkkiohjelma Käsittely lukee tekstiä sarjaportista 32-tavuisina lohkoina (TOTAL_BYTES). Varmistaakseen, että se toimii, se näyttää sen konsolin kautta merkeinä ja pakottaa vastaanotettujen tavujen tyypin char
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
import processing.serial.*;
Serial serie;
byte bloque_datos[];
static byte TOTAL_BYTES=32;
void setup()
{
frameRate(10);
serie=new Serial(this,“/dev/ttyUSB0”,9600);
bloque_datos=new byte[TOTAL_BYTES];
}
void draw()
{
if(serie.available()>0)
{
bloque_datos=serie.readBytes(TOTAL_BYTES);
if(bloque_datos!=null)
{
for(byte numero_byte=0;numero_byte<bloque_datos.length;numero_byte++)
{
print((char)bloque_datos[numero_byte]);
}
}
}
}
|
Seuraavassa kuvakaappauksessa näet, kuinka ne näkyvät konsolissa Käsittely tiedot, jotka on ladattu (enintään) 32 tavun lohkoissa (TOTAL_BYTES) joka kerta. Mutta on ongelma, josta on jo puhuttu: Työläs on lähettänyt säkeitä Federico Garcia Lorca esimerkistä koodattu tekstiksi muodossa UTF-8, jota ei käytetä Käsittely (Jaava), mistä pidät UTF-16 joten ne, jotka eivät vastaa sijoitusta ASCII tulostettavat tulkitaan väärin.
Tämän ongelman ratkaisemiseksi merkistöjä voidaan ladata (charset) ja määritä uusi objekti String
pakottaa sen esittämään koodauksella UTF-8 kuten seuraavassa esimerkkikoodissa näkyy.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import processing.serial.*;
import static java.nio.charset.StandardCharsets.*;
Serial serie;
byte bloque_datos[];
static byte TOTAL_BYTES=32;
void setup()
{
frameRate(10);
serie=new Serial(this,“/dev/ttyUSB0”,9600);
bloque_datos=new byte[TOTAL_BYTES];
}
void draw()
{
if(serie.available()>0)
{
bloque_datos=serie.readBytes(TOTAL_BYTES);
if(bloque_datos!=null)
{
print(new String(bloque_datos,UTF_8));
}
}
}
|
Lue viimeisimmät vastaanotetut tiedot. Viimeinen ja lastChar menetelmä.
Kun taas muut lukutavat ("tyyppi read
») he lataavat tiedot puskuri sarja samassa järjestyksessä kuin se saapui (FIFO), näillä kahdella menetelmällä viimeinen tavu, joka on saavuttanut puskuri sarja. Menetelmä last
palauttaa viimeisen tavun arvon muodossa a int
y lastChar
palauttaa arvon muodossa a char
.
Sarjapuskurin hallinta
Vaikka tähän mennessä nähdyt menetelmät ovat täysin toimivia, ne eivät aina edusta parasta tapaa hyödyntää pääsyä sarjaporttiin. Tietojen lataamiseksi heidän on tarkistettava ajoittain laitteen tila puskuri sarjassa ja lue koodin toistuvassa osassa saatavilla olevat tiedot. Yleisesti tehokkaampi tapa on lukea tiedot vasta, kun tiedät sen olevan saatavilla.
Lue sarjaportti, kun tietoja vastaanotetaan. Sarjatapahtuma.
Päästäksesi puskuri serial, kun data vastaanotetaan, Serial-tapahtumaa voidaan hyödyntää hallitsemalla sitä menetelmän määrittelyn kautta serialEvent
. Tämä menetelmä käyttää argumenttina sarjaporttia, joka käynnistää sen.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import processing.serial.*;
Serial serie;
void setup()
{
serie=new Serial(this,“/dev/ttyUSB0”,9600);
}
void draw()
{
}
void serialEvent(Serial comunicaciones)
{
print(comunicaciones.readChar());
}
|
Aseta sarjapuskurin koko. Puskurimenetelmä.
Jos tiedät hyödyllisten tietojen lohkon muodostavien tavujen määrän, voit edelleen optimoida tätä tietojen lukutyyliä. puskuri sarjan läpi serialEvent
. Menetelmä buffer
voit määrittää tiedostoon tallennettavien tavujen määrän puskuri ennen sarjatapahtuman käynnistämistä. Menetelmä odottaa parametrina kokonaislukua, joka edustaa tavujen määrää.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import processing.serial.*;
Serial serie;
void setup()
{
//noLoop();
serie=new Serial(this,“/dev/ttyUSB0”,9600);
serie.buffer(32); // Esperar a recibir 32 bytes antes de lanzar el evento Serial
}
void draw()
{
}
void serialEvent(Serial comunicaciones)
{
while(comunicaciones.available()>0)
{
print(comunicaciones.readChar());
}
}
|
Täytä puskuri, kunnes saat arvon. BufferUntil-menetelmä.
Metodikutsun asettamisen sijaan serialEvent
tietylle datamäärälle puskuri, menetelmällä bufferUntil
voit määrittää tallentamaan tietoja, kunnes erityinen arvo saapuu, ja nostaa sitten sarjatapahtumaa. Tälle menetelmälle välitetty parametri on a int
joka edustaa kutsun tuottamaa arvoa serialEvent
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import processing.serial.*;
Serial serie;
void setup()
{
serie=new Serial(this,“/dev/ttyUSB0”,9600);
serie.bufferUntil(9); // Espera a recibir un tabulador (ASCII 9) antes de llamar a serialEvent
}
void draw()
{
}
void serialEvent(Serial comunicaciones)
{
println(comunicaciones.readString()); // Imprime en una línea diferente cada valor separado originalmente por tabuladores
}
|
Poista puskuriin tallennetut tiedot. Selkeä menetelmä.
menetelmän kanssa clear
Voit poistaa tiedostossa tällä hetkellä olevat tiedot puskuri. Tällä menetelmällä voidaan esimerkiksi aloittaa uusi datan vastaanottoistunto jättäen huomioimatta edellisestä jäljellä olevat tiedot.
Tyypillinen käsittelysovellus tietojen lukemiseen sarjaportin kautta
Lopuksi on kätevää toistaa kohteen toiminnot Serial
de Käsittely jotka ovat yleisemmin käytettyjä, käyvät läpi tyypillisen esimerkin datan vastaanotosta sarjaportin kautta piirtääkseen niiden kanssa kaavion, tässä tapauksessa pinotuista alueista.
Tuo sarjakirjasto
1
|
import processing.serial.*;
|
Määritä dataprotokolla (erottimet)
1
2
|
static final String SEPARADOR=“\t”; // Los datos de cada sensor se separan con un tabulador
static final char TERMINADOR=10; // Cada grupo de datos se termina con un código ASCII 10 → Nueva línea → \n
|
Määritä Serial-luokan objekti
1
|
Serial conexion_sensores;
|
Instantoi Serial class -objekti asettamalla käytetyn sarjaportin
1
|
conexion_sensores=new Serial(this,“/dev/ttyUSB1”,9600);
|
Määritä sarjaportin puskuri
1
|
conexion_sensores.bufferUntil(TERMINADOR);
|
Toteuta käsittelijä sarjatapahtumalle
1
|
void serialEvent(Serial serie)
|
Lue sarjapuskuri
1
|
String[] texto_valor=serie.readString().split(SEPARADOR);
|
Ehdoi vastaanotetut tiedot
1
2
3
4
5
|
float[] valor=new float[texto_valor.length];
for(int numero_valor=0;numero_valor<texto_valor.length;numero_valor++)
{
valor[numero_valor]=parseFloat(texto_valor[numero_valor]);
}
|
Lopeta sarjaliikenne
1
2
|
conexion_sensores.clear();
conexion_sensores.stop();
|
Alla oleva esimerkkikoodi havainnollistaa tätä yhteenvetoa toiminnallisella (vaikkakin hyvin yksinkertaisella) sovelluksella, joka luo aluekaavion sarjaportin kautta vastaanotetuista arvoista, jotain samanlaista kuin seuraavassa animaatiossa.
Jotta et eksy ohjelman muuhun osaan ja keskityisi sarjaviestintään Käsittely, edellisiä toimintoja vastaavat koodirivit on korostettu.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
import processing.serial.*;
static final byte ROJO=0,VERDE=1,AZUL=2,OPACIDAD=3;
static final int CANTIDAD_SENSORES=3;
static final int CANTIDAD_VALORES=20;
static final String NOMBRE_FONDO=“fondo.png”;
static final int[][] COLOR_LINEA={{0x44,0x88,0xCC,0xFF},{0xFF,0xAA,0x00,0xFF},{0xCC,0x44,0xAA,0xFF}};
static final int[][] COLOR_AREA={{0x44,0x88,0xCC,0x88},{0xFF,0xAA,0x00,0x88},{0xCC,0x44,0xAA,0x88}};
static final int[] COLOR_FONDO={0xFF,0xFF,0XFF};
static final float GROSOR_LINEA=2.0;
static final float DIAMETRO_MARCA=8.0;
static final float VALOR_MINIMO=0.0; // Valor mínimo de la suma de todos los componentes
static final float VALOR_MAXIMO=100.0; // Valor máximo de la suma de valores
static final String SEPARADOR=“\t”; // Los datos de cada sensor se separan con un tabulador
static final char TERMINADOR=10; // Cada grupo de datos se termina con un código ASCII 10 → Nueva línea → \n
Serial conexion_sensores;
float[][] valor_sensor=new float[CANTIDAD_SENSORES][CANTIDAD_VALORES];
float coeficiente_valor;
float[] vertical_area=new float[CANTIDAD_VALORES];
float[] vertical_marca=new float[CANTIDAD_VALORES];
PImage fondo;
void setup()
{
size(792,396,P2D); // El tamaño de la ventana no se puede establecer con variables en setup (usar settings)
surface.setResizable(false);
surface.setTitle(“consumo relativo comparado”);
noLoop();
smooth(4);
conexion_sensores=new Serial(this,“/dev/ttyUSB1”,9600);
conexion_sensores.bufferUntil(TERMINADOR);
for(int numero_sensor=0;numero_sensor<CANTIDAD_SENSORES;numero_sensor++)
{
for(int numero_valor=0;numero_valor<CANTIDAD_VALORES;numero_valor++)
{
valor_sensor[numero_sensor][numero_valor]=0.0;
}
}
fondo=loadImage(NOMBRE_FONDO);
coeficiente_valor=height/(VALOR_MAXIMO–VALOR_MINIMO);
//strokeCap(ROUND); // El modo del final de líneas por defecto es redondeado
//ellipseMode(CENTER); // Por defecto el modo de elipse es desde el centro
if(DIAMETRO_MARCA>GROSOR_LINEA) // Si la marca no es visible hay que configurar el tipo de esquina
{
strokeJoin(ROUND); // El modo de esquina por defecto es en ángulo
}
}
void draw()
{
for(int numero_valor=0;numero_valor<valor_sensor[0].length;numero_valor++)
{
vertical_area[numero_valor]=height;
for(int numero_sensor=0;numero_sensor<valor_sensor.length;numero_sensor++)
{
vertical_area[numero_valor]-=(valor_sensor[numero_sensor][numero_valor]–VALOR_MINIMO)*coeficiente_valor;
}
vertical_marca[numero_valor]=vertical_area[numero_valor];
}
if(fondo==null)
{
background(COLOR_FONDO[ROJO],COLOR_FONDO[VERDE],COLOR_FONDO[AZUL]);
}
else
{
image(fondo,0,0);
}
strokeWeight(GROSOR_LINEA);
for(int numero_sensor=0;numero_sensor<valor_sensor.length;numero_sensor++)
{
stroke
(
COLOR_LINEA[numero_sensor][ROJO],
COLOR_LINEA[numero_sensor][VERDE],
COLOR_LINEA[numero_sensor][AZUL],
COLOR_LINEA[numero_sensor][OPACIDAD]
);
fill
(
COLOR_AREA[numero_sensor][ROJO],
COLOR_AREA[numero_sensor][VERDE],
COLOR_AREA[numero_sensor][AZUL],
COLOR_AREA[numero_sensor][OPACIDAD]
);
beginShape();
for(int numero_valor=valor_sensor[numero_sensor].length–1;numero_valor>=0;numero_valor—)
{
vertex(numero_valor*width/(valor_sensor[numero_sensor].length–1),vertical_area[numero_valor]);
}
for(int numero_valor=0;numero_valor<valor_sensor[numero_sensor].length;numero_valor++)
{
vertical_area[numero_valor]+=(valor_sensor[numero_sensor][numero_valor]–VALOR_MINIMO)*coeficiente_valor;
vertex(numero_valor*width/(valor_sensor[numero_sensor].length–1),vertical_area[numero_valor]);
}
endShape(CLOSE);
if(DIAMETRO_MARCA>0)
{
noStroke();
fill
(
COLOR_LINEA[numero_sensor][ROJO],
COLOR_LINEA[numero_sensor][VERDE],
COLOR_LINEA[numero_sensor][AZUL],
COLOR_LINEA[numero_sensor][OPACIDAD]
);
for(int numero_valor=0;numero_valor<valor_sensor[numero_sensor].length;numero_valor++)
{
ellipse
(
numero_valor*width/(valor_sensor[numero_sensor].length–1),
vertical_marca[numero_valor],
DIAMETRO_MARCA,
DIAMETRO_MARCA
);
vertical_marca[numero_valor]=vertical_area[numero_valor];
}
}
}
}
void stop() // Al terminar un Applet. No hay garantía de que se ejecute y, como estas operaciones se realizan al terminar, en realidad no son necesarias y solo se incluyen para recordar el uso de clear y stop
{
conexion_sensores.clear(); // Solo para ilustrar la posibilidad de borrar los datos que queden en el buffer
conexion_sensores.stop(); // Solo para ilustrar la posibilidad de terminar las comunicaciones serie y liberar el puerto que se está usando
}
void serialEvent(Serial serie)
{
String[] texto_valor=serie.readString().split(SEPARADOR);
float[] valor=new float[texto_valor.length];
for(int numero_valor=0;numero_valor<texto_valor.length;numero_valor++)
{
valor[numero_valor]=parseFloat(texto_valor[numero_valor]);
}
nuevo_valor(valor_sensor,valor);
redraw();
}
void nuevo_valor(float[][] valor_sensor, float[] valor)
{
for(int numero_sensor=0;numero_sensor<valor_sensor.length;numero_sensor++)
{
for(int numero_valor=1;numero_valor<valor_sensor[0].length;numero_valor++)
{
valor_sensor[numero_sensor][numero_valor–1]=valor_sensor[numero_sensor][numero_valor];
}
valor_sensor[numero_sensor][valor_sensor[0].length–1]=valor[numero_sensor];
}
}
|
Post Comment