前編のESP32は、距離・温度・湿度・気圧を次のCSV形式でUSBシリアルへ送る。今回はCODESYS Control Win V3 x64で受信し、4つのREALへ変換してVisualizationに表示した。
5.3,33.3,73.3,994.5
使用した通信条件はCOM3、115200 baud、8データビット、パリティなし、ストップビット1。CODESYS側ではCAA SerialComを利用し、MainTaskはT#1msに設定した。
受信処理の流れ
COM.Readで1バイトずつ受信し、CRは無視する。LFを受け取った時点で1行のCSVとして確定し、4つの値へ変換する。
COM.Read
↓ 1 byteずつ
文字列バッファへ追加
↓ LF
CSV 1行を確定
↓
距離、温度、湿度、気圧のREALへ変換
↓
Visualizationへ表示
CSV解析では、先頭からカンマ位置を探し、値を切り出してSTRING_TO_REALへ渡す。3つのカンマと最後の値がそろうまで成功にしないことで、不完全な行を表示しないようにした。
iComma := FIND(sWork, ',');
IF iComma = 0 THEN
RETURN;
END_IF
sValue := LEFT(sWork, iComma - 1);
rDistance := STRING_TO_REAL(sValue);
sWork := DELETE(sWork, iComma, 1);
Visualizationには4つのテキストフィールドを配置し、たとえば距離はPLC_PRG.rDistanceを%.1f cmの形式で表示した。
最初の値から更新されなかった原因
最初のCSVは解析できたのに、ESP32側でセンサ値が変わってもCODESYSの表示が古いままになる現象が起きた。ESP32のOLEDとCSV先頭の値は一致していたため、問題は測定式やCSV解析ではなく、受信の消化速度にあると切り分けた。
COM.Readは1バイトごとに、受信のための周期と、Function Blockをリセットする周期を使う。MainTaskがT#10msだと、1バイトに約20msかかる。連続して届くCSVに追いつけず、COMバッファ内に古い行がたまっていた。
変更前: MainTask = T#10ms
変更後: MainTask = T#1ms
変更後は1バイトを約2msで処理でき、4項目がVisualizationで継続更新されることを確認した。
学習用実装から次へ
今回の1バイト受信方式は仕組みを理解するには分かりやすいが、実運用では複数バイト受信、リングバッファ、受信FBの専用化、ESP32の送信周期、PLC負荷とタスクジッタを検討する必要がある。
メインロジックをFBDで見通しよくしたい場合も、シリアル受信とCSV解析はSTのFunction Blockへ閉じ込め、FBD側は4つのREALを使う構成が扱いやすい。