Mga Serial na Komunikasyon na may Pagproseso
Ang Serial class
Ang mga operasyon upang magamit ang mga serial na komunikasyon sa Pagproseso ay tinukoy sa klase Serial
.Ang unang operasyon na gagawin upang magamit ang mga ito sa isang programa (gumuhit ng plano) ay upang isama ito sa code na may import processing.serial.*;
.
Klase Serial
Mayroon itong limang magkakaibang mga konstruktor depende sa mga parameter na ipinahiwatig. Ang tanging kinakailangang parameter ay ang parent object (magulang) na karaniwang tumutugma sa pangunahing programa (sabihin, ang window ng programa) ng klase PApplet
. Gaya ng karaniwan, ang magulang ang magiging programang isinusulat (ang gumuhit ng plano kasalukuyang), ang halaga ng unang mandatoryong parameter na ito ay this
.
Ang iba pang limang parameter na maaaring ipasa sa constructor ay ① ang bilis, ② ang pangalan ng serial port ③ ang pagkakapantay-pantay ginamit sa protocol, ④ ang mga bit ng data at ⑤ ang mga stop bit. Ang pinakamadalas na ipinapasa na mga parameter, bilang karagdagan sa kinakailangang bagay ng magulang, ay ang pangalan ng port at bilis.
La bilis ng serial communications ay isang integer (int
) Iyon default sa value na 9600 kung ang parameter na ito ay hindi naipasa sa constructor.
Available ang mga serial port. Ang paraan ng listahan
El pangalan ng port ay ang form na tinutukoy ng system, sa ganitong paraan, halimbawa sa Mga pamamahagi ng Linux ito ay magiging isang katulad /dev/ttyS4 / dev / ttyACM3 o /dev/ttyUSB1 (depende sa uri ng port), habang sa Windows ito ay magiging katulad nito COM12. Maliban kung pisikal na nauugnay ang isang port sa isang device, karaniwang hindi malalaman ng program kung aling port ang gagamitin. Ang isang karaniwang paraan upang piliin ang port ay upang makakuha ng isang listahan ng mga magagamit, ipakita ito sa user at payagan silang pumili ng isa na gusto nilang gamitin. Ang paraan Serial.list()
nagbabalik ng vector ng mga string ng teksto (String
) na may mga pangalan ng mga port na magagamit sa system.
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());
}
|
Ang port na ginagamit ng library bilang default Serial
ay ang una sa mga ibinalik ng pamamaraan list
(sigurado COM1 sa Windows o /dev/ttyS0 en GNU / Linux). Maliban sa napakalimitadong mga konteksto kung saan ang hardware na pinagtatrabahuhan ay mahigpit na kilala (tulad ng isang sistema sa kiosk mode), hindi ito karaniwang inaalis at ang destinasyong port ay hayagang ipinapahiwatig.
Ipinapakita ng screenshot sa itaas ang output ng isang system GNU / Linux na mayroong apat na serial port RS-232 (ttyS0 a ttyS3) at limang adapter ng dalawang uri (ttyACM0 a ttyACM1 y ttyUSB0 a ttyUSB2).
Upang ma-access ang mga serial port, ang user ay dapat na kabilang sa pangkat kung saan sila itinalaga ng system, sa karaniwan tty o dialogout. Sa screenshot ng larawan sa itaas makikita mo na nakalista ang mga serial port na may ls /dev/tty[ASU]* -la
kabilang sa grupo dialogout na may mga pahintulot sa pag-access sa pagbasa at pagsulat sa kanila.
Mga parameter ng serial protocol
La pagkakapantay-pantay ng mga serial na komunikasyon ay ipinahayag sa Pagproseso bilang isang karakter (char
) na maaaring kunin ang mga halaga: ① N
(wala) upang hindi matukoy ang pagkakapantay-pantay, ② E
(kahit na) upang ipahiwatig na ang parity bit ay pantay, ③ O
(kakaiba) upang ipahiwatig na ang parity bit ay kakaiba, ④ M
(markahan) para laging gawin ang parity bit at ⑤ S
(puwang) para laging gawin ang isa parity bit. Ang default na halaga, kung hindi naipasa sa constructor bilang isang parameter, ay N
(nang wala pagkakapantay-pantay).
Ang bilang ng mga data bits, na walo bilang default, ay nagpapahiwatig ng bilang ng mga bit na bumubuo sa net data payload (tinatawag na character o kung minsan ay isang salita) na ipinapadala sa bawat pangunahing yunit ng frame. Ang parameter na nagpapahiwatig ng bilang ng mga bit ng data ay ipinahayag bilang isang integer (int
).
Sa wakas, ang ikalimang posibleng parameter ay nagpapahiwatig ng tagal ng huling marka, na ipinahayag bilang stop bits (stop bits), na ipinahiwatig bilang isang numero na kinakatawan sa lumulutang na punto (float
) na maaaring kunin ang mga halaga 1.0
(ang default na halaga kung ang parameter ay hindi naipasa sa tagabuo), 1.5
o 2.0
.
Mga konstruktor ng Serial na klase
Ipinapakita ng sumusunod na listahan ang iba't ibang kumbinasyon ng mga parameter na maaaring ipasa sa tagabuo ng klase Serial
:
Serial(padre)
Serial(padre,puerto)
Serial(padre,velocidad)
Serial(padre,puerto,velocidad)
Serial(padre,puerto,velocidad,paridad,bits_datos,bits_parada)
Tapusin ang mga serial communication. Ang paraan ng paghinto.
Upang i-release ang serial port, na itinalaga kapag nag-instantiate Serial
, at na magagamit ito ng ibang mga application ng system, ang mga komunikasyon ay winakasan gamit ang pamamaraan stop
, na hindi tumatanggap ng mga parameter.
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
}
|
Magpadala ng data sa pamamagitan ng serial port. Ang pagsulat.paraan
Upang magpadala ng data, ang klase Serial
de Pagproseso isinasama ang pamamaraan write
kung saan ① text string ay maaaring ipadala (String
), ② byte o ③ byte vectors (byte[]
). Nakakatuwang alalahanin iyon byte
en Pagproseso (Sa Java) ay kumakatawan sa isang integer sa pagitan ng -128 at 127 at, bilang default, ginagamit ng mga string ang encoding 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
}
|
Basahin ang data mula sa serial port
Upang ang programa ay makapagsagawa ng iba pang mga gawain habang ang data ay natanggap sa pamamagitan ng serial port, karaniwan nang mag-imbak sa isang nagpapahina ng lakas ang data na dumating at basahin ito kung naaangkop. Bagama't kadalasan ay hindi masyadong mahusay, maaari mong ihinto ang application upang i-load ang lahat ng magagamit na data; Gayunpaman, ang pinakakaraniwang bagay ay ang basahin ang impormasyon sa pagdating nito, alinman sa bawat pag-ulit ng draw
, kapag ang isang tiyak na dami ay magagamit o isang espesyal na code ay natanggap.
Dami ng data na available sa buffer. Ang magagamit na pamamaraan
Upang malaman kung ang data ay dumating sa nagpapahina ng lakas serye, ang pamamaraan available
ibinabalik ang bilang ng mga byte na naimbak na dito nagpapahina ng lakas. Sa alinmang kaso, ang mga read operation ay maaaring magbalik ng isang espesyal na halaga (tulad ng -1
o null
) kapag sinusubukang i-load ang data mula sa nagpapahina ng lakas serye kapag walang laman.
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”);
}
|
Mag-load ng isang byte sa isang pagkakataon. Ang paraan ng pagbasa
Ang mga pangunahing pamamaraan ng klase Serial
na nagsisilbing basahin ang impormasyong natanggap ng isang serial port ay ang mga "uri read
» na naiiba sa pagitan nila, pangunahin, ayon sa uri ng data kung saan inihahatid nila ang impormasyong natanggap.
read
ay ginagamit upang ihatid ang mga byte na natanggap ng serial port bilang isang halaga sa pagitan ng 0 at 255. Bilang uri ng data byte
de Pagproseso kumakatawan sa hanay sa pagitan ng -128 at 127 at hindi sa pagitan ng 0 at 255, kinakailangang gumamit ng int
upang kumatawan sa hanay na ibinalik ni read
. Kung susubukan mong basahin kasama read
at nagpapahina ng lakas walang laman ang string, nagbabalik ng halaga -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());
}
}
|
Basahin ang mga character mula sa serial port. Ang paraan ng readChar
Ang pamamaraan readChar
ay katulad sa read
ngunit nagbabalik ito ng halaga sa format char
sa halip na a int
. Bilang panloob, ang char
en Pagproseso (Sa Java) ay naka-imbak na may dalawang byte, ang halaga na piniling ibalik kapag nagbabasa kasama readChar
isang nagpapahina ng lakas walang laman ang serye 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());
}
}
|
Mag-load ng text string. Ang mga pamamaraan ng readString at readStringUntil.
Ang pamamaraan readString
nagbabalik ng isang bagay String
nabuo mula sa lahat ng datos na makukuha sa nagpapahina ng lakas serye sa oras ng pagkonsulta dito.
Ang pamamaraan readString
lumilikha ng text string sa pag-aakalang ang mga byte na natanggap ng serial port ay nasa format ASCII kaya hindi magagamit ang paraan ng pagbabasa na ito para sa iba pang pag-encode.
Kung ito ay tungkol sa pagbabasa ng nagpapahina ng lakas serye na may readString
kapag walang laman, ang return value ay null
.
Ang pamamaraan readStringUntil
Idagdag sa readString
ang kakayahang ibalik ang impormasyong na-load sa nagpapahina ng lakas serye na hinahati ito ng isang espesyal na karakter (code) na ipinasa bilang isang parameter. Ang paraan ng pagbabasa ng impormasyong natanggap ay nagbibigay-daan sa amin na makilala ang parehong mga separator at terminator na tumutulong sa pagbibigay kahulugan sa impormasyong natanggap.
Ang pamamaraan readStringUntil
ibalik mo null
kapag nasa nagpapahina ng lakas serye ay hindi mahanap ang code na tinukoy sa argument na ipinasa dito (isang byte).
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
}
}
}
|
Sa sumusunod na code para sa Arduino nagpapadala ng tatlong mensahe sa pamamagitan ng serial port. Ang unang dalawa ay nagtatapos sa isang tab, kaya lalabas ang mga ito sa console. Pagproseso, habang ang pangatlo, bagama't ipapadala ito sa pamamagitan ng serial port, ay hindi babasahin readStringUntil(9)
dahil hindi ito nagtatapos sa isang tab (na may code 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()
{
}
|
Basahin ang mga bloke ng data. Ang mga pamamaraan ng readBytes at readBytesUntil.
Ang mga pamamaraan na nakikita sa itaas ay ginagamit upang basahin ang data na may mga partikular na format, upang basahin ang mga bloke ng raw data o may isang format na hindi ibinigay para sa Pagproseso ginagamit ang mga pamamaraan readBytes
y readBytesUntil
Ang pamamaraan readBytes
subukan mong basahin ang data na makukuha sa nagpapahina ng lakas serye. Kung walang parameter na ipinasa sa pamamaraan readBytes
lahat ng magagamit na data ay binabasa at ibinalik sa isang vector (byte[]
). Kung ang isang integer ay ipinasa bilang isang parameter, ang maximum ng bilang ng mga byte na ipinahiwatig ng numerong ito ay mababasa at ang mga ito ay ibinalik din bilang isang vector.
May pangatlong paraan para magamit readBytes
, mas mahusay, na kumukuha bilang argumento ng isang byte vector kung saan ang mga nilalaman ng nagpapahina ng lakas serye. Ang ganitong paraan ng paggamit readBytes
nagbabalik ng integer (int
) na kumakatawan sa bilang ng mga byte na nabasa.
Ang pamamaraan readBytesUntil
gumagana sa katulad na paraan ngunit may kasamang unang parameter na kumakatawan sa halaga ng byte na, kung makikita sa nagpapahina ng lakas, ay magsasaad ng pagtatapos ng pagbabasa. Sa pamamaraang ito, ang parameter na tumutukoy sa maximum na bilang ng mga byte na babasahin ay walang saysay dahil ang halaga ay matutukoy ng espesyal na code.
Upang subukan ang pagpapatakbo ng pamamaraan readBytes
Ipagpalagay natin ang sumusunod na code para sa Arduino na nagpapadala ng text sa pamamagitan ng serial port.
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()
{
}
|
Ang sumusunod na halimbawa ng programa para sa Pagproseso nagbabasa ng teksto mula sa serial port sa 32-byte na mga bloke (TOTAL_BYTES). Upang i-verify na gumagana ito, ipinapakita ito sa console bilang mga character, na pinipilit ang uri ng mga byte na natanggap 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]);
}
}
}
}
|
Sa sumusunod na screenshot makikita mo kung paano ipinapakita ang mga ito sa console Pagproseso ang data na na-load sa mga bloke ng (maximum) 32 bytes (TOTAL_BYTES) sa bawat oras. Ngunit mayroong isang problema na napag-usapan na: Arduino ay nagpapadala ng mga talata ng Federico Garcia Lorca ng halimbawang naka-encode bilang teksto sa format UTF-8, na hindi ang ginamit Pagproseso (Java), ano ang mas gusto mo Utf-16 kaya ang mga hindi tumutugma sa ranggo ng ASCII napi-print ay mali ang interpretasyon.
Upang malutas ang problemang ito, maaaring i-load ang mga set ng character (charset) at tukuyin ang isang bagong bagay String
pinipilit itong irepresenta ng encoding UTF-8 tulad ng ipinapakita sa sumusunod na halimbawang code.
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));
}
}
}
|
Basahin ang pinakabagong data na natanggap. Ang huli at hulingChar na mga pamamaraan.
Habang ang natitirang mga pamamaraan sa pagbabasa (ang "uri read
») nilo-load nila ang impormasyon ng nagpapahina ng lakas serye sa parehong pagkakasunud-sunod ng pagdating nito (FIFO), gamit ang dalawang pamamaraang ito ang huling byte na umabot sa nagpapahina ng lakas serye. Ang paraan last
ibinabalik ang halaga ng huling byte bilang a int
y lastChar
ibinabalik ang halaga bilang a char
.
Pamamahala ng serial buffer
Bagama't ang mga pamamaraan na nakikita sa ngayon ay ganap na gumagana, hindi ito palaging kumakatawan sa pinakamahusay na paraan upang pagsamantalahan ang pag-access sa serial port. Upang mai-load ang data, kailangan nilang pana-panahong suriin ang katayuan ng nagpapahina ng lakas serye at basahin ang data na magagamit sa paulit-ulit na bahagi ng code. Ang isang mas mahusay na paraan sa pangkalahatan ay basahin lamang ang data kapag alam mong available ito.
Basahin ang serial port kapag natanggap ang data. Ang Serial na kaganapan.
Upang ma-access ang nagpapahina ng lakas serial kapag ang data ay natanggap, ang Serial na kaganapan ay maaaring pinagsamantalahan sa pamamagitan ng pamamahala nito sa pamamagitan ng kahulugan ng pamamaraan serialEvent
. Ginagamit ng paraang ito ang serial port na naglulunsad nito bilang argumento.
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());
}
|
Sukatin ang serial buffer. Ang paraan ng buffer.
Kung alam mo ang bilang ng mga byte na bumubuo sa isang bloke ng kapaki-pakinabang na data, maaari mong higit pang i-optimize ang istilong ito ng pagbabasa ng data. nagpapahina ng lakas serye sa pamamagitan ng serialEvent
. Ang paraan buffer
ay nagbibigay-daan sa iyong itakda ang bilang ng mga byte na maiimbak sa nagpapahina ng lakas bago maglunsad ng Serial na kaganapan. Inaasahan ng pamamaraan bilang isang parameter ang isang integer na kumakatawan sa bilang ng mga byte.
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());
}
}
|
Punan ang buffer hanggang sa matanggap ang isang halaga. Ang paraan ng bufferUntil.
Sa halip na itakda ang tawag sa pamamaraan serialEvent
para sa isang dami ng data sa nagpapahina ng lakas, sa pamamaraan bufferUntil
maaari mong i-configure upang mag-imbak ng data hanggang sa dumating ang isang espesyal na halaga at pagkatapos ay itaas ang Serial na kaganapan. Ang parameter na ipinasa sa paraang ito ay a int
na kumakatawan sa halaga na ginawa ng tawag sa 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
}
|
Tanggalin ang data na nakaimbak sa buffer. Ang malinaw na pamamaraan.
gamit ang pamamaraan clear
Maaari mong tanggalin ang data na kasalukuyang nasa nagpapahina ng lakas. Maaaring gamitin ang paraang ito, halimbawa, upang magsimula ng bagong sesyon ng pagtanggap ng data na hindi pinapansin ang natitirang data mula sa nauna.
Karaniwang Application sa Pagproseso para sa pagbabasa ng data sa pamamagitan ng serial port
Sa wakas, ito ay maginhawa upang i-recapitulate ang mga pagpapatakbo ng bagay Serial
de Pagproseso na mas karaniwang ginagamit, na dumaraan sa isang tipikal na halimbawa ng pagtanggap ng data sa pamamagitan ng serial port upang gumuhit ng graph kasama nila, sa kasong ito ng mga nakasalansan na lugar.
I-import ang Serial library
1
|
import processing.serial.*;
|
Tukuyin ang protocol ng data (mga separator)
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
|
Tukuyin ang object ng Serial class
1
|
Serial conexion_sensores;
|
I-instantiate ang Serial class object sa pamamagitan ng pagtatakda ng serial port na ginamit
1
|
conexion_sensores=new Serial(this,“/dev/ttyUSB1”,9600);
|
I-configure ang serial port buffer
1
|
conexion_sensores.bufferUntil(TERMINADOR);
|
Magpatupad ng handler para sa Serial na kaganapan
1
|
void serialEvent(Serial serie)
|
Basahin ang serial buffer
1
|
String[] texto_valor=serie.readString().split(SEPARADOR);
|
Kundisyon ang data na natanggap
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]);
}
|
Tapusin ang mga serial communication
1
2
|
conexion_sensores.clear();
conexion_sensores.stop();
|
Ang halimbawang code sa ibaba ay naglalarawan ng buod na ito gamit ang isang functional (bagaman napakasimple) na application na bumubuo ng isang area graph na may mga halaga na natanggap sa pamamagitan ng serial port, isang bagay na katulad ng ipinapakita ng sumusunod na animation.
Upang hindi mawala sa natitirang bahagi ng programa at ituon ang pansin sa mga serial na komunikasyon sa Pagproseso, ang mga linya ng code na tumutugma sa mga nakaraang operasyon ay naka-highlight.
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 Komento