Comunicații seriale cu procesare
Clasa Serial
Operațiunile de utilizare a comunicațiilor seriale în Prelucrare sunt definite în clasă Serial
.Prima operație de efectuat pentru a le folosi într-un program (schiţă) va fi să-l încorporăm în cod cu import processing.serial.*;
.
Clasă Serial
Are cinci constructori diferiți în funcție de parametrii indicați. Singurul parametru necesar este obiectul părinte (mamă) care corespunde de obicei programului principal (să zicem, fereastra programului) al clasei PApplet
. Ca de obicei, părintele va fi programul care se scrie ( schiţă curent), valoarea acestui prim parametru obligatoriu va fi this
.
Ceilalți cinci parametri care pot fi transferați constructorului sunt ① viteza, ② numele portului serial ③ paritate utilizați în protocol, ④ biții de date și ⑤ biții de oprire. Parametrii transmisi cel mai frecvent, pe lângă obiectul părinte necesar, sunt numele portului și viteza.
La viteza comunicațiilor seriale este un număr întreg (int
) care implicit la valoarea 9600 dacă acest parametru nu este transmis constructorului.
Porturi seriale disponibile. Metoda listei
El numele portului are forma determinată de sistem, în acest fel, de exemplu în Distribuții Linux va fi ceva de genul /dev/ttyS4 / dev / ttyACM3 o /dev/ttyUSB1 (în funcție de tipul portului), în timp ce pe Windows va fi ceva de genul COM12. Cu excepția cazului în care un port este asociat fizic cu un dispozitiv, programul nu va ști în mod normal ce port să folosească. O modalitate obișnuită de a selecta portul este de a obține o listă a celor disponibile, de a o arăta utilizatorului și de a-i permite să aleagă pe cel pe care doresc să-l folosească. Metoda Serial.list()
returnează un vector de șiruri de text (String
) cu numele porturilor disponibile pe sistem.
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());
}
|
Portul folosit implicit de bibliotecă Serial
este primul dintre cele returnate prin metoda list
(cu siguranţă COM1 pe Windows sau /dev/ttyS0 en GNU / Linux). Cu excepția unor contexte foarte limitate în care hardware-ul cu care se lucrează este strict cunoscut (cum ar fi un sistem în modul chioșc), acesta nu este de obicei omis și portul de destinație este indicat în mod expres.
Captura de ecran de mai sus arată rezultatul unui sistem GNU / Linux care are patru porturi seriale RS-232 (ttyS0 a ttyS3) și cinci adaptoare de două tipuri (ttyACM0 a ttyACM1 y ttyUSB0 a ttyUSB2).
Pentru a accesa porturile seriale, utilizatorul trebuie să aparțină grupului căruia îi atribuie sistemul, în mod normal tty o apelare telefonică. În captura de ecran din imaginea de mai sus puteți vedea că porturile seriale enumerate cu ls /dev/tty[ASU]* -la
aparțin grupului apelare telefonică care are permisiuni de acces de citire și scriere asupra lor.
Parametrii protocolului serial
La paritate a comunicaţiilor seriale se exprimă în Prelucrare ca personaj (char
) care poate lua valorile: ① N
(nici unul) pentru a nu detecta paritate, ② E
(chiar) pentru a indica faptul că bit de paritate este par, ③ O
(ciudat) pentru a indica faptul că bit de paritate este impar, ④ M
(marca) pentru a face întotdeauna bit de paritate și ⑤ S
(spaţiu) pentru a face întotdeauna unul bit de paritate. Valoarea implicită, dacă nu este transmisă constructorului ca parametru, este N
(fără paritate).
Numărul de biți de date, care este opt implicit, indică numărul de biți care alcătuiesc sarcina netă de date (numită caracter sau uneori cuvânt) care este transmisă în fiecare unitate de bază a cadrului. Parametrul care indică numărul de biți de date este exprimat ca un număr întreg (int
).
În cele din urmă, al cincilea parametru posibil indică durata notei finale, exprimată ca biți de oprire (biți de oprire), care este indicat ca un număr reprezentat în punctul de plutire (float
) care poate lua valorile 1.0
(valoarea implicită dacă parametrul nu este transmis constructorului), 1.5
sau 2.0
.
Constructorii clasei Serial
Următoarea listă arată diferitele combinații de parametri care pot fi transmise constructorului de clasă Serial
:
Serial(padre)
Serial(padre,puerto)
Serial(padre,velocidad)
Serial(padre,puerto,velocidad)
Serial(padre,puerto,velocidad,paridad,bits_datos,bits_parada)
Opriți comunicațiile seriale. Metoda opririi.
Pentru a elibera portul serial, atribuit la instanțiere Serial
, și că alte aplicații de sistem îl pot folosi, comunicațiile sunt încheiate cu metoda stop
, care nu primește parametri.
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
}
|
Trimiteți date prin portul serial. Metoda de scriere
Pentru a trimite date, clasa Serial
de Prelucrare încorporează metoda write
cu care pot fi transmise ① șiruri de text (String
), ② octeți sau ③ vectori octeți (byte[]
). Este interesant de reținut că byte
en Prelucrare (în Java) reprezintă un număr întreg între -128 și 127 și, implicit, șirurile folosesc codificarea 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
}
|
Citiți datele de pe portul serial
Pentru ca programul să poată efectua alte sarcini în timp ce datele sunt primite prin portul serial, este de obicei stocat într-un tampon datele care ajung și citiți-le când este cazul. Deși de obicei nu este foarte eficient, puteți opri aplicația pentru a încărca toate datele disponibile; Cu toate acestea, cel mai obișnuit lucru va fi să citiți informațiile pe măsură ce sosesc, fie în fiecare iterație de draw
, când este disponibilă o anumită cantitate sau a fost primit un cod special.
Cantitatea de date disponibilă în tampon. Metoda disponibilă
Pentru a ști dacă au ajuns datele la tampon seria, metoda available
returnează numărul de octeți care au fost deja stocați în acesta tampon. În ambele cazuri, operațiunile de citire pot returna o valoare specială (cum ar fi -1
o null
) când încercați să încărcați date de la tampon serie când este goală.
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”);
}
|
Încărcați câte un octet. Metoda citirii
Principalele metode ale clasei Serial
care servesc la citirea informațiilor primite de un port serial sunt cele de „tip read
» care diferă între ele, în principal, prin tipul de date în care furnizează informațiile primite.
read
este folosit pentru a livra octeții primiți de portul serial ca valoare între 0 și 255. Ca tip de date byte
de Prelucrare reprezintă intervalul între -128 și 127 și nu între 0 și 255, este necesar să se folosească un int
pentru a reprezenta intervalul returnat de read
. Dacă încerci să citești cu read
și tampon șirul este gol, returnează valoare -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());
}
}
|
Citiți caractere din portul serial. Metoda readChar
Metoda readChar
este similar a read
dar returnează o valoare în format char
în loc de a int
. Ca și pe plan intern, cel char
en Prelucrare (în Java) sunt stocate cu doi octeți, valoarea aleasă să revină la citirea cu readChar
o tampon seria goală este 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());
}
}
|
Încărcați un șir de text. Metodele readString și readStringUntil.
Metoda readString
returnează un obiect String
format din toate datele disponibile în tampon serie la momentul consultării acesteia.
Metoda readString
creează șirul de text presupunând că octeții primiți de portul serial sunt în format ASCII deci această metodă de citire nu poate fi folosită pentru alte codificări.
Dacă este vorba despre citirea tampon serie cu readString
când este gol, valoarea returnată este null
.
Metoda readStringUntil
adaugă la readString
capacitatea de a returna informațiile încărcate în tampon serie împărțind-o printr-un caracter special (cod) care este transmis ca parametru. Acest mod de citire a informațiilor primite ne permite să distingem atât separatorii, cât și terminatorii care ajută la interpretarea informațiilor primite.
Metoda readStringUntil
adu inapoi null
când în tampon serie nu găsește codul specificat în argumentul transmis acestuia (un octet).
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
}
}
}
|
În următorul cod pentru Arduino trimite trei mesaje prin portul serial. Primele două se termină într-o filă, așa că vor apărea în consolă. Prelucrare, în timp ce al treilea, deși va fi trimis prin portul serial, nu va fi citit cu readStringUntil(9)
deoarece nu se termină într-o filă (cu cod 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()
{
}
|
Citiți blocuri de date. Metodele readBytes și readBytesUntil.
Metodele prezentate mai sus sunt folosite pentru a citi date cu formate specifice, pentru a citi blocuri de date brute sau cu un format care nu este prevăzut în Prelucrare sunt folosite metode readBytes
y readBytesUntil
Metoda readBytes
încercați să citiți datele disponibile în tampon serie. Dacă nu se transmite niciun parametru metodei readBytes
toate datele disponibile sunt citite și returnate într-un vector (byte[]
). Dacă un număr întreg este transmis ca parametru, se citește maximum din numărul de octeți indicat de acest număr și sunt returnați și ca vector.
Există o a treia modalitate de utilizare readBytes
, mai eficient, care ia ca argument un vector de octeți în care se află conținutul tampon serie. Acest mod de utilizare readBytes
returnează un număr întreg (int
) care reprezintă numărul de octeți care au fost citiți.
Metoda readBytesUntil
funcționează într-un mod similar, dar include un prim parametru care reprezintă valoarea octetului care, dacă se găsește în tampon, va indica sfârșitul lecturii. În această metodă, parametrul care determină numărul maxim de octeți care vor fi citiți nu are sens deoarece cantitatea va fi determinată de codul special.
Pentru a testa funcționarea metodei readBytes
Să presupunem următorul cod pentru Arduino care trimite un text prin portul serial.
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()
{
}
|
Următorul exemplu de program pentru Prelucrare citește textul de pe portul serial în blocuri de 32 de octeți (TOTAL_BYTES). Pentru a verifica dacă funcționează, îl arată prin consolă ca caractere, forțând tipul de octeți primiți 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]);
}
}
}
}
|
În următoarea captură de ecran puteți vedea cum sunt afișate în consolă Prelucrare datele care au fost încărcate în blocuri de (maximum) 32 de octeți (TOTAL_BYTES) de fiecare dată. Dar există o problemă despre care s-a vorbit deja: Arduino a trimis versurile din Federico Garcia Lorca a exemplului codificat ca text în format UTF-8, care nu este cea folosită Prelucrare (Java), ce preferi UTF-16 deci cei care nu corespund rangului de ASCII imprimabile sunt interpretate incorect.
Pentru a rezolva această problemă, seturile de caractere pot fi încărcate (set de caractere) și definiți un nou obiect String
obligând-o să fie reprezentată prin codificare UTF-8 așa cum se arată în următorul exemplu de cod.
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));
}
}
}
|
Citiți cele mai recente date primite. Metodele last și lastChar.
În timp ce restul metodelor de citire („tip read
») încarcă informațiile din tampon seria în aceeași ordine în care a sosit (FIFO), cu aceste două metode ultimul octet care a ajuns la tampon serie. Metoda last
returnează valoarea ultimului octet ca a int
y lastChar
returnează valoarea ca a char
.
Gestionarea tamponului serial
Deși metodele văzute până acum sunt perfect funcționale, ele nu reprezintă întotdeauna cea mai bună modalitate de a exploata accesul la portul serial. Pentru a încărca datele, trebuie să verifice periodic starea tampon serie și citiți datele disponibile într-o parte repetată a codului. O modalitate în general mai eficientă este să citiți datele numai atunci când știți că sunt disponibile.
Citiți portul serial când sunt primite datele. Evenimentul Serial.
Pentru a accesa tampon serial atunci când datele sunt primite, evenimentul Serial poate fi exploatat prin gestionarea lui prin definirea metodei serialEvent
. Această metodă folosește portul serial care îl lansează ca argument.
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());
}
|
Dimensiunea tamponului serial. Metoda tamponului.
Dacă cunoașteți numărul de octeți care formează un bloc de date utile, puteți optimiza și mai mult acest stil de citire a datelor. tampon serie prin serialEvent
. Metoda buffer
vă permite să setați numărul de octeți care vor fi stocați în tampon înainte de a lansa un eveniment serial. Metoda așteaptă ca parametru un număr întreg care reprezintă numărul de octeți.
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());
}
}
|
Umpleți tamponul până când se primește o valoare. Metoda bufferUntil.
În loc să setați apelul la metodă serialEvent
pentru o cantitate de date în tampon, cu metoda bufferUntil
puteți configura să stocați date până când ajunge o valoare specială și apoi să ridicați evenimentul Serial. Parametrul transmis acestei metode este a int
care reprezintă valoarea produsă de apelul la 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
}
|
Ștergeți datele stocate în buffer. Metoda clară.
cu metoda clear
Puteți șterge datele care se află în prezent în tampon. Această metodă poate fi folosită, de exemplu, pentru a începe o nouă sesiune de recepție a datelor ignorând datele rămase din cea anterioară.
Aplicație tipică de procesare pentru citirea datelor prin portul serial
În cele din urmă, este convenabil să recapitulăm operațiile obiectului Serial
de Prelucrare care sunt mai frecvent utilizate, trecând printr-un exemplu tipic de recepție a datelor prin portul serial pentru a desena un grafic cu ele, în acest caz de zone stivuite.
Importați biblioteca Serial
1
|
import processing.serial.*;
|
Determinați protocolul de date (separatoare)
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
|
Determinați obiectul clasei Serial
1
|
Serial conexion_sensores;
|
Instanciați obiectul clasei Serial setând portul serial utilizat
1
|
conexion_sensores=new Serial(this,“/dev/ttyUSB1”,9600);
|
Configurați bufferul portului serial
1
|
conexion_sensores.bufferUntil(TERMINADOR);
|
Implementați un handler pentru evenimentul Serial
1
|
void serialEvent(Serial serie)
|
Citiți tampon serial
1
|
String[] texto_valor=serie.readString().split(SEPARADOR);
|
Condiționează datele primite
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]);
}
|
Opriți comunicațiile seriale
1
2
|
conexion_sensores.clear();
conexion_sensores.stop();
|
Exemplul de cod de mai jos ilustrează acest rezumat cu o aplicație funcțională (deși foarte simplă) care generează un grafic de zonă cu valorile care sunt primite prin portul serial, ceva asemănător cu ceea ce arată animația următoare.
Pentru a nu vă pierde în restul programului și concentrați atenția asupra comunicațiilor seriale cu Prelucrare, sunt evidențiate liniile de cod care corespund operațiilor anterioare.
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];
}
}
|
Posteaza un comentariu