Послідовний зв'язок з обробкою
Серійний клас
Операції з використанням послідовного зв’язку в Обробка визначені в класі 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).
Щоб отримати доступ до послідовних портів, користувач повинен належати до групи, до якої система його призначає, зазвичай tty 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.method
Щоб надіслати дані, клас Serial
de Обробка включає в себе метод write
за допомогою якого ① можна передавати текстові рядки (String
), ② байтів або ③ байтових векторів (byte[]
). Цікаво це згадати byte
en Обробка (В Java) представляє ціле число від -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
es подібний a read
але він повертає значення у форматі char
замість a int
. Як внутрішньо, char
en Обробка (В Java) зберігаються з двома байтами, значенням, вибраним для повернення під час читання 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, яка не є використовуваною Обробка (Java), Що ви віддаєте перевагу 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 Обробка які частіше використовуються, переглядаючи типовий приклад отримання даних через послідовний порт, щоб намалювати з ними графік, у цьому випадку складених областей.
Імпорт бібліотеки Serial
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);
|
Реалізуйте обробник для події Serial
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];
}
}
|
Дати коментар