Serijske komunikacije z obdelavo
Serijski razred
Operacije za uporabo serijskih komunikacij v Obravnavano so definirani v razredu Serial
.Prva operacija za njihovo uporabo v programu (skica) bo vključitev v kodo z import processing.serial.*;
.
razred Serial
Ima pet različnih konstruktorjev glede na navedene parametre. Edini zahtevani parameter je nadrejeni objekt (od staršev), ki običajno ustreza glavnemu programu (recimo oknu programa) razreda PApplet
. Kot običajno bo nadrejeni program, ki se piše (the skica trenutni), bo vrednost tega prvega obveznega parametra this
.
Ostalih pet parametrov, ki jih je mogoče posredovati konstruktorju, so ① hitrost, ② ime serijskih vrat ③ pariteta uporabljeni v protokolu, ④ podatkovni biti in ⑤ stop bitovi. Najpogosteje posredovana parametra sta poleg zahtevanega nadrejenega objekta ime vrat in hitrost.
La hitrost serijske komunikacije je celo število (int
) To privzeta vrednost je 9600 če ta parameter ni posredovan konstruktorju.
Na voljo so serijska vrata. Metoda seznama
El ime pristanišča ima obliko, ki jo določa sistem, tako denimo v Distribucije Linuxa bo nekaj takega /dev/ttyS4 / dev / ttyACM3 o /dev/ttyUSB1 (odvisno od vrste vrat), medtem ko bo v sistemu Windows nekaj podobnega COM12. Če vrata niso fizično povezana z napravo, program običajno ne bo vedel, katera vrata uporabiti. Pogost način izbire vrat je pridobitev seznama razpoložljivih vrat, ki ga pokažete uporabniku in mu omogočite, da izbere tistega, ki ga želi uporabiti. Metoda Serial.list()
vrne vektor besedilnih nizov (String
) z imeni vrat, ki so na voljo v sistemu.
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());
}
|
Vrata, ki jih privzeto uporablja knjižnica Serial
je prvi od tistih, ki jih vrne metoda list
(zagotovo COM1 v sistemu Windows oz /dev/ttyS0 en GNU / Linux). Razen v zelo omejenih kontekstih, v katerih je strojna oprema, s katero se dela, natančno znana (kot je sistem v načinu kioska), se običajno ne izpusti in ciljna vrata so izrecno navedena.
Zgornji posnetek zaslona prikazuje izhod sistema GNU / Linux ki ima štiri serijska vrata RS-232 (ttyS0 a ttyS3) in pet adapterjev dveh vrst (ttyACM0 a ttyACM1 y ttyUSB0 a ttyUSB2).
Za dostop do serijskih vrat mora uporabnik pripadati skupini, ki ji jih sistem dodeli, običajno tty o klicanje. Na posnetku zaslona zgornje slike lahko vidite, da so serijska vrata navedena z ls /dev/tty[ASU]* -la
pripadajo skupini klicanje ki ima na njih dovoljenja za dostop za branje in pisanje.
Parametri serijskega protokola
La pariteta serijskih komunikacij je izraženo v Obravnavano kot lik (char
), ki ima lahko vrednosti: ① N
(none), da ne zazna pariteta, ② E
(celo), ki označuje, da je paritetni bit je sodo, ③ O
(čudno), ki označuje, da je paritetni bit je liho, ④ M
(znamka) vedno narediti paritetni bit in ⑤ S
(prostor), da bo vedno ena paritetni bit. Privzeta vrednost, če ni posredovana konstruktorju kot parameter, je N
(brez pariteta).
Število podatkovnih bitov, ki je privzeto osem, označuje število bitov, ki sestavljajo neto podatkovno obremenitev (imenovano znak ali včasih beseda), ki se prenaša v vsaki osnovni enoti okvira. Parameter, ki označuje število podatkovnih bitov, je izražen kot celo število (int
).
Končno, peti možni parameter označuje trajanje končne ocene, izraženo kot stop bitov (stop bitov), ki je označeno kot število, predstavljeno v plavajočo vejico (float
), ki lahko sprejme vrednosti 1.0
(privzeta vrednost, če parameter ni posredovan konstruktorju), 1.5
ali 2.0
.
Konstruktorji razreda Serial
Naslednji seznam prikazuje različne kombinacije parametrov, ki jih je mogoče posredovati konstruktorju razreda Serial
:
Serial(padre)
Serial(padre,puerto)
Serial(padre,velocidad)
Serial(padre,puerto,velocidad)
Serial(padre,puerto,velocidad,paridad,bits_datos,bits_parada)
Končaj serijsko komunikacijo. Metoda zaustavitve.
Za sprostitev serijskih vrat, dodeljenih ob instanciranju Serial
in da ga lahko uporabljajo druge sistemske aplikacije, se komunikacije prekinejo z metodo stop
, ki ne sprejema parametrov.
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
}
|
Pošlji podatke prek serijskih vrat. Metoda pisanja
Za pošiljanje podatkov razred Serial
de Obravnavano vključuje metodo write
s katerim lahko prenašate ① besedilne nize (String
), ② bajtov ali ③ bajtnih vektorjev (byte[]
). Zanimivo se je tega spomniti byte
en Obravnavano (Ob Java) predstavlja celo število med -128 in 127 in nizi privzeto uporabljajo kodiranje 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
}
|
Branje podatkov iz serijskih vrat
Da lahko program med prejemanjem podatkov prek serijskih vrat izvaja druge naloge, je običajno shranjevanje v a varovalni prispele podatke in jih prebere, ko je to primerno. Čeprav običajno ni zelo učinkovito, lahko aplikacijo ustavite, da naloži vse razpoložljive podatke; Vendar pa bo najpogostejša stvar branje informacij, ko prispejo, bodisi v vsaki ponovitvi draw
, ko je določena količina na voljo ali je prejeta posebna koda.
Količina podatkov, ki so na voljo v medpomnilniku. Razpoložljiva metoda
Če želite vedeti, ali so podatki prispeli na varovalni serija, metoda available
vrne število bajtov, ki so že bili shranjeni v tem varovalni. V obeh primerih lahko operacije branja vrnejo posebno vrednost (kot npr -1
o null
), ko poskušate naložiti podatke iz varovalni serija, ko je prazna.
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”);
}
|
Nalagajte en bajt naenkrat. Metoda branja
Glavne metode razreda Serial
ki služijo za branje informacij, ki jih prejmejo serijska vrata, so tiste tipa " read
» ki se med seboj razlikujejo predvsem po vrsti podatkov, v katerih posredujejo prejete informacije.
read
se uporablja za dostavo bajtov, ki jih prejmejo serijska vrata, kot vrednost med 0 in 255. Kot podatkovni tip byte
de Obravnavano predstavlja obseg med -128 in 127 in ne med 0 in 255, je treba uporabiti int
da predstavlja obseg, ki ga vrne read
. Če poskušate brati z read
in varovalni niz je prazen, vrne vrednost -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());
}
}
|
Branje znakov iz serijskih vrat. Metoda readChar
Metoda readChar
je podobno kot read
vendar vrne vrednost v formatu char
namesto a int
. Tako kot interno, char
en Obravnavano (Ob Java) so shranjeni z dvema bajtoma, izbrano vrednostjo za vrnitev pri branju readChar
po varovalni prazna serija je 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());
}
}
|
Naloži besedilni niz. Metodi readString in readStringUntil.
Metoda readString
vrne predmet String
oblikovana iz vseh podatkov, ki so na voljo v varovalni serije v času posvetovanja z njo.
Metoda readString
ustvari besedilni niz ob predpostavki, da so bajti, ki jih prejmejo serijska vrata, v formatu ASCII zato te metode branja ni mogoče uporabiti za druga kodiranja.
Če gre za branje varovalni serija z readString
ko je prazen, je vrnjena vrednost null
.
Metoda readStringUntil
dodati k readString
možnost vrnitve informacij, naloženih v varovalni serija, ki jo razdeli s posebnim znakom (kodo), ki se posreduje kot parameter. Ta način branja prejetih informacij nam omogoča, da ločimo tako ločila kot terminatorje, ki pomagajo interpretirati prejete informacije.
Metoda readStringUntil
prinesi nazaj null
ko v varovalni serija ne najde kode, podane v argumentu, ki ji je bil posredovan (en bajt).
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
}
}
}
|
V naslednji kodi za Arduino pošlje tri sporočila prek serijskih vrat. Prva dva se končata z zavihkom, zato se bosta prikazala v konzoli. Obravnavano, medtem ko tretji, čeprav bo poslan prek serijskih vrat, ne bo prebran z readStringUntil(9)
ker se ne konča z zavihkom (s kodo 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()
{
}
|
Branje podatkovnih blokov. Metodi readBytes in readBytesUntil.
Zgoraj prikazane metode se uporabljajo za branje podatkov v določenih oblikah, za branje blokov neobdelanih podatkov ali z obliko, ki ni predvidena v Obravnavano uporabljajo se metode readBytes
y readBytesUntil
Metoda readBytes
poskusite prebrati podatke, ki so na voljo v varovalni serije. Če metodi ni posredovan noben parameter readBytes
vsi razpoložljivi podatki so prebrani in vrnjeni v vektorju (byte[]
). Če je kot parameter posredovano celo število, se prebere največje število bajtov, ki jih označuje to število, in so tudi vrnjeni kot vektor.
Obstaja še tretji način uporabe readBytes
, učinkovitejši, ki kot argument vzame bajtni vektor, v katerega je vnesena vsebina varovalni serije. Ta način uporabe readBytes
vrne celo število (int
), ki predstavlja število prebranih bajtov.
Metoda readBytesUntil
deluje na podoben način, vendar vključuje prvi parameter, ki predstavlja vrednost bajta, ki je, če ga najdete v varovalni, označuje konec branja. Pri tej metodi parameter, ki določa največje število prebranih bajtov, ni smiseln, saj bo količino določila posebna koda.
Za preizkus delovanja metode readBytes
Predpostavimo naslednjo kodo za Arduino ki pošlje besedilo skozi serijska vrata.
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()
{
}
|
Naslednji primer programa za Obravnavano bere besedilo iz serijskih vrat v 32-bajtnih blokih (TOTAL_BYTES). Da bi preveril, ali deluje, ga prek konzole prikaže kot znake, pri čemer prisili vrsto prejetih bajtov v 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]);
}
}
}
}
|
Na naslednjem posnetku zaslona lahko vidite, kako so prikazani v konzoli Obravnavano podatki, ki so bili naloženi v blokih (največ) 32 bajtov (TOTAL_BYTES) vsakič. Vendar obstaja problem, o katerem je bilo že govora: Arduino je pošiljal verze Federico García Lorca primera, kodiranega kot besedilo v formatu UTF-8, ki ni uporabljena Obravnavano (Java), kaj imaš raje UTF-16 torej tisti, ki ne ustrezajo rangu ASCII natisljive se nepravilno razlagajo.
Za rešitev te težave je mogoče naložiti nabor znakov (črtico) in definirajte nov predmet String
prisili, da je predstavljen s kodiranjem UTF-8 kot je prikazano v naslednjem primeru kode.
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));
}
}
}
|
Preberite zadnje prejete podatke. Metodi last in lastChar.
Medtem ko ostale metode branja ("tip read
») naložijo informacije o varovalni serija v istem vrstnem redu, kot je prispela (FIFO), s tema dvema metodama zadnji bajt, ki je dosegel varovalni serije. Metoda last
vrne vrednost zadnjega bajta kot a int
y lastChar
vrne vrednost kot a char
.
Upravljanje serijskega medpomnilnika
Čeprav so doslej videne metode popolnoma funkcionalne, ne predstavljajo vedno najboljšega načina za izkoriščanje dostopa do serijskih vrat. Za nalaganje podatkov morajo občasno preveriti stanje varovalni serije in preberite podatke, ki so na voljo v ponavljajočem se delu kode. Na splošno je učinkovitejši način branje podatkov le, če veste, da so na voljo.
Preberite serijska vrata, ko so podatki prejeti. Serijski dogodek.
Za dostop do varovalni serial, ko so podatki prejeti, lahko serijski dogodek izkoristite tako, da ga upravljate prek definicije metode serialEvent
. Ta metoda kot argument uporablja serijska vrata, ki jo zaženejo.
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());
}
|
Velikost serijskega medpomnilnika. Puferska metoda.
Če poznate število bajtov, ki sestavljajo blok uporabnih podatkov, lahko dodatno optimizirate ta slog branja podatkov. varovalni serija skozi serialEvent
. Metoda buffer
omogoča nastavitev števila bajtov, ki bodo shranjeni v varovalni pred zagonom serijskega dogodka. Metoda pričakuje kot parameter celo število, ki predstavlja število bajtov.
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());
}
}
|
Polnite medpomnilnik, dokler ne prejmete vrednosti. Metoda bufferUntil.
Namesto nastavitve klica metode serialEvent
za količino podatkov v varovalni, z metodo bufferUntil
lahko konfigurirate tako, da shranjujete podatke, dokler ne prispe posebna vrednost in nato dvignete serijski dogodek. Parameter, posredovan tej metodi, je a int
ki predstavlja vrednost, ki jo ustvari klic 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
}
|
Izbrišite podatke, shranjene v medpomnilniku. Jasna metoda.
z metodo clear
Izbrišete lahko podatke, ki so trenutno v varovalni. To metodo je mogoče uporabiti na primer za začetek nove seje sprejema podatkov, pri čemer se ne upoštevajo podatki, ki so ostali iz prejšnje.
Tipična aplikacija za obdelavo za branje podatkov prek serijskih vrat
Končno je priročno povzeti delovanje objekta Serial
de Obravnavano ki se pogosteje uporabljajo, skozi tipičen primer prejemanja podatkov prek serijskih vrat, da se z njimi nariše graf, v tem primeru zloženih območij.
Uvozite serijsko knjižnico
1
|
import processing.serial.*;
|
Določite podatkovni protokol (ločila)
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
|
Določite objekt razreda Serial
1
|
Serial conexion_sensores;
|
Instanciirajte objekt razreda Serial tako, da nastavite uporabljena serijska vrata
1
|
conexion_sensores=new Serial(this,“/dev/ttyUSB1”,9600);
|
Konfigurirajte medpomnilnik serijskih vrat
1
|
conexion_sensores.bufferUntil(TERMINADOR);
|
Implementirajte obravnavo za serijski dogodek
1
|
void serialEvent(Serial serie)
|
Branje serijskega medpomnilnika
1
|
String[] texto_valor=serie.readString().split(SEPARADOR);
|
Pogojujte prejete podatke
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]);
}
|
Končaj serijsko komunikacijo
1
2
|
conexion_sensores.clear();
conexion_sensores.stop();
|
Spodnji primer kode ponazarja ta povzetek s funkcionalno (čeprav zelo preprosto) aplikacijo, ki generira ploščinski graf z vrednostmi, prejetimi prek serijskih vrat, nekaj podobnega temu, kar prikazuje naslednja animacija.
Da se ne izgubite v preostalem delu programa in pozornost usmerite na serijsko komunikacijo z Obravnavano, so označene vrstice kode, ki ustrezajo prejšnjim operacijam.
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];
}
}
|
po Komentar