Серийни комуникации с обработка
Сериен клас
Операциите за използване на серийни комуникации в Обработване са определени в класа Serial
.Първата операция, която трябва да се извърши, за да ги използвате в програма (скица) ще бъде да го включите в кода с import processing.serial.*;
.
клас Serial
Има пет различни конструктора в зависимост от посочените параметри. Единственият задължителен параметър е родителският обект (родител), което обикновено съответства на основната програма (да речем прозореца на програмата) на класа PApplet
. Както обикновено, родителят ще бъде програмата, която се пише (the скица ток), стойността на този първи задължителен параметър ще бъде this
.
Другите пет параметъра, които могат да бъдат предадени на конструктора, са ① скоростта, ② името на серийния порт ③ паритет използвани в протокола, ④ битовете данни и ⑤ стоп битовете. Най-често предаваните параметри, в допълнение към необходимия родителски обект, са името на порта и скоростта.
La скорост на серийна комуникация е цяло число (int
) това по подразбиране е 9600 ако този параметър не е предаден на конструктора.
Налични серийни портове. Методът на списъка
El име на порт има формата, определена от системата, по този начин, например в Linux дистрибуции ще бъде нещо подобно /dev/ttyS4 / dev / ttyACM3 o /dev/ttyUSB1 (в зависимост от типа на порта), докато на Windows ще бъде нещо подобно COM12. Освен ако портът не е физически свързан с устройство, програмата обикновено няма да знае кой порт да използва. Често срещан начин за избор на порт е да получите списък с наличните, да го покажете на потребителя и да му позволите да избере този, който иска да използва. Методът Serial.list()
връща вектор от текстови низове (String
) с имената на портовете, налични в системата.
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());
}
|
Портът, използван по подразбиране от библиотеката Serial
е първият от върнатите от метода list
(със сигурност COM1 на Windows или /dev/ttyS0 en GNU / Linux). Освен в много ограничени контексти, в които хардуерът, с който се работи, е строго известен (като система в павилионен режим), той обикновено не се пропуска и целевият порт е изрично посочен.
Екранната снимка по-горе показва изхода на системата GNU / Linux който има четири серийни порта RS-232 (ttyS0 a ttyS3) и пет адаптера от два вида (ttyACM0 a ttyACM1 y ttyUSB0 a ttyUSB2).
За да има достъп до серийните портове, потребителят трябва да принадлежи към групата, към която системата ги присвоява, обикновено йу o диалог. В екранната снимка на изображението по-горе можете да видите, че серийните портове са изброени с ls /dev/tty[ASU]* -la
принадлежат към групата диалог който има разрешения за достъп за четене и запис върху тях.
Параметри на серийния протокол
La паритет на серийни комуникации се изразява в Обработване като герой (char
), който може да приема стойностите: ① N
(нито един), за да не откриете паритет, ② E
(дори), за да посочи, че бит за четност е четен, ③ O
(нечетен), за да посочи, че бит за четност е странно, ④ M
(марка), за да правите винаги бит за четност и ⑤ S
(пространство), за да правите винаги един бит за четност. Стойността по подразбиране, ако не е предадена на конструктора като параметър, е N
(без паритет).
Броят на битове данни, което е осем по подразбиране, показва броя на битовете, които съставляват полезния товар на нетните данни (наречен символ или понякога дума), който се предава във всяка основна единица на рамката. Параметърът, указващ броя на битовете данни, се изразява като цяло число (int
).
И накрая, петият възможен параметър показва продължителността на крайната маркировка, изразена като стоп битове (стоп битове), което е посочено като число, представено в плаваща запетая (float
), които могат да приемат стойностите 1.0
(стойността по подразбиране, ако параметърът не е предаден на конструктора), 1.5
или 2.0
.
Конструктори на клас Serial
Следващият списък показва различните комбинации от параметри, които могат да бъдат предадени на конструктора на класа Serial
:
Serial(padre)
Serial(padre,puerto)
Serial(padre,velocidad)
Serial(padre,puerto,velocidad)
Serial(padre,puerto,velocidad,paridad,bits_datos,bits_parada)
Край на серийните комуникации. Методът на спиране.
За освобождаване на серийния порт, зададен при инстанциране Serial
и че други системни приложения могат да го използват, комуникациите се прекратяват с метода stop
, който не получава параметри.
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
}
|
Изпратете данни през серийния порт. Методът write
За да изпратите данни, класът Serial
de Обработване включва метода write
с които могат да се предават ① текстови низове (String
), ② байта или ③ байт вектори (byte[]
). Интересно е да си припомним това byte
en Обработване (В Ява) представлява цяло число между -128 и 127 и по подразбиране низовете използват кодирането 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
}
|
Прочетете данни от сериен порт
За да може програмата да изпълнява други задачи, докато данните се получават през серийния порт, обикновено се съхранява в a буфер пристигащите данни и ги чете, когато е подходящо. Въпреки че обикновено не е много ефективно, можете да спрете приложението, за да зареди всички налични данни; Въпреки това, най-често срещаното нещо ще бъде да четете информацията, когато пристига, или във всяка итерация на draw
, когато е налично определено количество или е получен специален код.
Количество налични данни в буфера. Достъпният метод
За да разберете дали данните са пристигнали буфер серия, методът available
връща броя байтове, които вече са били съхранени в това буфер. И в двата случая операциите за четене могат да върнат специална стойност (като напр -1
o null
), когато се опитвате да заредите данни от буфер серия, когато е празна.
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”);
}
|
Зареждайте байт по байт. Методът на четене
Основните методи на класа Serial
които служат за четене на информацията, получена от сериен порт, са тези от тип " read
» които се различават помежду си главно по вида на данните, в които доставят получената информация.
read
се използва за доставяне на байтовете, получени от серийния порт като стойност между 0 и 255. Като тип данни byte
de Обработване представлява диапазона между -128 и 127, а не между 0 и 255, е необходимо да се използва int
за да представи диапазона, върнат от read
. Ако се опитате да четете с read
и буфер низът е празен, връща стойност -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());
}
}
|
Четете знаци от серийния порт. Методът readChar
Методът readChar
е подобно на read
но връща стойност във формат char
вместо a int
. Както вътрешно, char
en Обработване (В Ява) се съхраняват с два байта, стойността, избрана да се върне при четене с readChar
от буфер празна серия е 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());
}
}
|
Заредете текстов низ. Методите readString и readStringUntil.
Методът readString
връща обект String
формирана от всички налични данни в буфер серия към момента на консултиране с нея.
Методът readString
създава текстов низ, като приема, че байтовете, получени от серийния порт, са във формат ASCII така че този метод на четене не може да се използва за други кодировки.
Ако става дума за четене на буфер сериал с readString
когато е празно, връщаната стойност е null
.
Методът readStringUntil
добави към readString
възможността за връщане на информация, заредена в буфер серия, разделяща го със специален знак (код), който се предава като параметър. Този начин на четене на получената информация ни позволява да разграничаваме както разделителите, така и терминаторите, които помагат за интерпретирането на получената информация.
Методът readStringUntil
Върни null
когато в буфер серия не намира кода, посочен в подаден й аргумент (един байт).
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
}
}
}
|
В следния код за Arduino изпраща три съобщения през серийния порт. Първите две завършват с раздел, така че ще се появят в конзолата. Обработване, докато третият, въпреки че ще бъде изпратен през серийния порт, няма да бъде прочетен с readStringUntil(9)
тъй като не завършва с раздел (с код 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()
{
}
|
Четене на блокове с данни. Методите readBytes и readBytesUntil.
Методите, разгледани по-горе, се използват за четене на данни със специфични формати, за четене на блокове необработени данни или с формат, който не е предвиден в Обработване се използват методи readBytes
y readBytesUntil
Методът readBytes
опитайте се да прочетете наличните данни в буфер серия. Ако към метода не бъде предаден параметър readBytes
всички налични данни се четат и връщат във вектор (byte[]
). Ако като параметър се подаде цяло число, се чете максимум от броя байтове, посочени от това число, и те също се връщат като вектор.
Има и трети начин за използване readBytes
, по-ефективен, който приема като аргумент байтов вектор, в който съдържанието на буфер серия. Този начин на използване readBytes
връща цяло число (int
), което представлява броя на прочетените байтове.
Методът readBytesUntil
работи по подобен начин, но включва първи параметър, който представлява стойността на байта, който, ако бъде открит в буфер, ще покаже края на четенето. При този метод параметърът, който определя максималния брой байтове, които ще бъдат прочетени, няма смисъл, тъй като количеството ще се определя от специалния код.
За тестване на действието на метода readBytes
Нека приемем следния код за Arduino който изпраща текст през серийния порт.
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()
{
}
|
Следната примерна програма за Обработване чете текст от серийния порт в 32-байтови блокове (TOTAL_BYTES). За да провери дали работи, той го показва през конзолата като знаци, принуждавайки типа на получените байтове да 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]);
}
}
}
}
|
На следващата екранна снимка можете да видите как се показват в конзолата Обработване данните, които са били заредени в блокове от (максимум) 32 байта (TOTAL_BYTES) всеки път. Но има проблем, за който вече стана дума: Arduino изпраща стиховете на Федерико Гарсия Лорка от примера, кодиран като текст във формат UTF-8, което не е използваното Обработване (Ява), какво предпочитате UTF-16 така че тези, които не отговарят на ранга на ASCII за печат се тълкуват неправилно.
За да разрешите този проблем, наборите от символи могат да бъдат заредени (набор от знаци) и дефинирайте нов обект String
принуждавайки го да бъде представен с кодиране UTF-8 както е показано в следния примерен код.
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));
}
}
}
|
Прочетете последните получени данни. Методите last и lastChar.
Докато останалите методи за четене (тип read
») зареждат информацията на буфер серия в същия ред, в който е пристигнала (FIFO), с тези два метода последният байт, който е достигнал буфер серия. Методът last
връща стойността на последния байт като a int
y lastChar
връща стойността като a char
.
Управление на серийния буфер
Въпреки че методите, видяни досега, са напълно функционални, те не винаги представляват най-добрия начин за използване на достъпа до серийния порт. За да заредят данните, те трябва периодично да проверяват състоянието на буфер серия и прочетете наличните данни в повтаряща се част от кода. Като цяло по-ефективен начин е да четете данните само когато знаете, че са налични.
Прочетете серийния порт, когато се получат данни. Серийното събитие.
За достъп до буфер serial, когато данните бъдат получени, събитието Serial може да се използва чрез управлението му чрез дефиницията на метода serialEvent
. Този метод използва серийния порт, който го стартира като аргумент.
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());
}
|
Оразмерете серийния буфер. Буферният метод.
Ако знаете броя на байтовете, които съставят блок от полезни данни, можете допълнително да оптимизирате този стил на четене на данните. буфер серия през serialEvent
. Методът buffer
ви позволява да зададете броя байтове, които ще се съхраняват в буфер преди стартиране на серийно събитие. Методът очаква като параметър цяло число, което представлява броя на байтовете.
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());
}
}
|
Попълнете буфера, докато се получи стойност. Методът bufferUntil.
Вместо да зададете извикването на метода serialEvent
за количество данни в буфер, с метода bufferUntil
можете да конфигурирате да съхранявате данни, докато пристигне специална стойност и след това да повдигнете събитието Serial. Параметърът, предаван на този метод, е a int
което представлява стойността, произведена от извикването на 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
}
|
Изтрийте данните, съхранени в буфера. Ясният метод.
с метода clear
Можете да изтриете данните, които в момента са в буфер. Този метод може да се използва например за стартиране на нова сесия за получаване на данни, като се игнорират данните, останали от предишната.
Типично приложение за обработка за четене на данни през серийния порт
И накрая, удобно е да се повторят операциите на обекта Serial
de Обработване които се използват по-често, преминавайки през типичен пример за приемане на данни през серийния порт, за да начертаете графика с тях, в този случай на подредени области.
Импортирайте серийната библиотека
1
|
import processing.serial.*;
|
Определяне на протокол за данни (разделители)
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
|
Определете обекта на класа Serial
1
|
Serial conexion_sensores;
|
Създайте екземпляр на обекта от клас Serial, като зададете използвания сериен порт
1
|
conexion_sensores=new Serial(this,“/dev/ttyUSB1”,9600);
|
Конфигурирайте буфера на серийния порт
1
|
conexion_sensores.bufferUntil(TERMINADOR);
|
Внедрете манипулатор за серийното събитие
1
|
void serialEvent(Serial serie)
|
Прочетете сериен буфер
1
|
String[] texto_valor=serie.readString().split(SEPARADOR);
|
Кондиционирайте получените данни
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]);
}
|
Край на серийните комуникации
1
2
|
conexion_sensores.clear();
conexion_sensores.stop();
|
Примерният код по-долу илюстрира това резюме с функционално (макар и много просто) приложение, което генерира площна графика със стойностите, които се получават през серийния порт, нещо подобно на това, което показва следващата анимация.
За да не се изгубите в останалата част от програмата и да фокусирате вниманието си върху серийните комуникации с Обработване, редовете от код, които съответстват на предишните операции, са маркирани.
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];
}
}
|
Публикувай коментар