処理付きシリアル通信
シリアルクラス
シリアル通信を使用するための操作 処理 クラスで定義されている Serial
プログラムでそれらを使用するために実行する最初の操作 (スケッチ)それをコードに組み込むことになります import processing.serial.*;
.
クラス Serial
指定されたパラメーターに応じて XNUMX つの異なるコンストラクターがあります。 唯一の必須パラメータは親オブジェクト (親) これは通常、クラスのメイン プログラム (プログラム ウィンドウなど) に対応します。 PApplet
。 通常どおり、親は作成中のプログラムになります ( スケッチ 現在)、この最初の必須パラメータの値は次のようになります。 this
.
コンストラクターに渡すことができる他の XNUMX つのパラメーターは、①速度、②シリアル ポートの名前、③ パリティ プロトコルで使用される、④データビットと⑤ストップビットです。 必須の親オブジェクトに加えて、最も頻繁に渡されるパラメータは、ポート名と速度です。
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の シリアルポートがXNUMXつある RS-232 (ttyS0 a ttyS3) と XNUMX 種類のアダプター XNUMX 個 (ttyACM0 a ttyACM1 y ttyUSB0 a ttyUSB2).
シリアル ポートにアクセスするには、ユーザーはシステムが割り当てたグループに属している必要があります。通常、 TTY o ダイヤルアウト。 上の画像のスクリーンショットでは、シリアル ポートが ls /dev/tty[ASU]* -la
pertenecen al グルポ ダイヤルアウト これには読み取りおよび書き込みアクセス許可が与えられます。
シリアルプロトコルパラメータ
La パリティ シリアル通信の で表現されます 処理 キャラクターとして(char
) 値を取ることができます: ① N
(なし) を検出しないようにするには、 パリティ、② E
(さらに) であることを示します。 パリティビット 偶数、③ O
(奇数) であることを示します。 パリティビット 奇数です、④ M
(マーク) 常に パリティビット そして⑤ S
(スペース) 常に XNUMX つを作成します パリティビット。 コンストラクターにパラメーターとして渡されない場合のデフォルト値は、 N
(それなし パリティ).
数 データビットデフォルトでは XNUMX ですが、フレームの各基本単位で送信される正味データ ペイロード (文字または単語と呼ばれる) を構成するビット数を示します。 データのビット数を示すパラメータは整数で表現されます(int
).
最後に、XNUMX 番目の可能なパラメータは、次のように表現される最終マークの長さを示します。 ストップビット (ストップビット)で表される数値で示されます。 浮動小数点 (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 処理 (中 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
}
|
シリアルポートからデータを読み取る
シリアル ポート経由でデータを受信している間にプログラムが他のタスクを実行できるように、通常はデータを バッファ 受信したデータを必要に応じて読み取ります。 通常はあまり効率的ではありませんが、アプリケーションを停止して、利用可能なデータをすべてロードすることができます。 ただし、最も一般的なのは、各反復のいずれかで、情報が到着したときに情報を読み取ることです。 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”);
}
|
一度に XNUMX バイトずつロードします。 読み取り方法
クラスの主なメソッド Serial
シリアルポートによって受信された情報を読み取るために機能するものは、「タイプ」のものです。 read
» これらの違いは、主に、受信した情報を配信するデータの種類によって異なります。
read
シリアル ポートで受信したバイトを 0 ~ 255 の値として配信するために使用されます。データ型として byte
de 処理 は、128 ~ 127 の範囲ではなく、-0 ~ 255 の範囲を表します。 int
によって返される範囲を表すために read
。 で読み取ろうとすると read
Y·エル バッファ 文字列が空です、値を返します -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
の代わりに int
。 内部的には、 char
en 処理 (中 Java) は XNUMX バイトで保存され、読み取り時に返される値が選択されます。 readChar
A バッファ 空のシリーズは 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
にいるとき バッファ series は、渡された引数で指定されたコード (XNUMX バイト) を見つけません。
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の シリアル ポート経由で XNUMX つのメッセージを送信します。 最初の XNUMX つはタブで終わるため、コンソールに表示されます。 処理、一方、XNUMX 番目はシリアル ポート経由で送信されますが、 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 printable は正しく解釈されません。
この問題を解決するには、文字セットをロードすることができます (文字セット) そして新しいオブジェクトを定義します 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)、これら XNUMX つの方法では、到達した最後のバイトが バッファ シリーズ。 方法 last
最後のバイトの値を int
y lastChar
値を次のように返します char
.
シリアルバッファ管理
これまでに確認した方法は完全に機能しますが、シリアル ポートへのアクセスを悪用する最良の方法を常に表しているわけではありません。 データをロードするには、定期的にステータスをチェックする必要があります。 バッファ 一連のデータを読み取って、コードの繰り返し部分にあるデータを読み取ります。 一般に、より効率的な方法は、データが利用可能であることがわかっている場合にのみデータを読み取ることです。
データ受信時にシリアルポートを読み取ります。 シリアルイベント。
にアクセスするには、 バッファ データを受信したときにシリアル イベントをメソッド定義で管理することで、シリアル イベントを悪用できます。 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 イベントを発生させるように構成できます。 このメソッドに渡されるパラメータは、 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);
|
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];
}
}
|
コメントを投稿