リングバッファの使い方 (2/2)
CSVファイルへ出力
ここでは以下のデータをCSVファイルへ書き出すときにリングバッファを使って書き出す手順を説明します
書き出すタイミングは実行フラグがONしている間で、10ms周期で1行のデータを書き出します
| 変数名 | データ型 | 内容 |
|---|---|---|
| index | UDINT | 連番 |
| Data | STRING[256] | 書込み文字列 |
手順1:リングバッファの作成
1-1. リングバッファ用構造体の作成
ファイル出力したいデータはsData構造体に入れるのでデータ型を合わせて作成します
そのData構造体をリングバッファ用の構造体に入れるのですが、その時にバッファリングに必要なサイズだけ配列を設定します
この配列の数がバッファサイズになります
| 名称 | データ型 | 内容 | ||
|---|---|---|---|---|
| sRingBuffer | ||||
| Top | UINT | 追加位置 | ||
| Bottom | UINT | 読出し位置 | ||
| Count | UINT | 格納数 | ||
| Data | sData[1000] | バッファ | ||
| Index | DINT | |||
| Data | STRING[256] | |||
1-2. サンプルからファンクションをコピー
ファンクションにRingBufPutファンクションとRingbufGetファンクションをリングバッファのサンプルからコピーしておきます
手順2:リングバッファへ格納
2-1. プログラム作成
データをリングバッファに入れるタイミングはここではスキャンタイムを数えてplsフラグをONして作ります
ファイルに書き出したいデータはPutData(sData構造体)のIndexに連番をDataにはダミーの文字列をセットします
RingButPutファンクションを使ってリングバッファにPutDataを追加します
2-2. エラーが出たら
'SRINGBUFFERからST_STRING_LITERALに変換できません。'のようなエラーが出る場合はファンクションの変数テーブルを開いて入出力タブのRingBufのデータ型を一度削除してからもう一度sRingBuffer型を設定し直してください
手順3:リングバッファからファイルへ
3-1. リングバッファにデータがあればファイルへ書き込み
- 2行目:リングバッファのCountをチェックしてデータがあればデータあり(DataExists)をONします
- 3~4行目:データ書込み中(Write)フラグをONしてファイルをオープンします
- 5行目:リングバッファからデータを1件読み出してGetData(sData構造体)に格納しGetData.Indexを文字列にしてGetData.Dataの文字列と繋げて書き込み文字列(WriteString)にセットします
- 6行目:FilePut命令で書込み文字列(WriteString)をSDに書き込みます
- 7行目:書き込み完了したらリングバッファのCountをチェックしてデータがあれば次のデータを5行目からもう一度実行するためにNextLineフラグをONにします データがなければ一旦クローズするためにCloseフラグをONにします
- 8~9行目:ファイルをクローズします FilePutで異常が起きた時もCloseすることを忘れずに
- 10行目:正常終了OKフラグまたは、異常終了NGフラグをONします
手順4. 動作確認
プログラムが完成したので動作確認します
RunフラグをONしている間はデータを10ms周期でバッファリングしながらSDの'testRing.csv'ファイルに追加書込みしていきます
正常動作
Ringbuffer.Countの数値をモニタして値が増え続けずに低い数値で安定していればバッファ処理は間に合っているので正常の動作してます
オーバーフロー
Countの値が配列の要素数まで増えてしまうとバッファオーバーフローとなり歯抜けができてしまいます
そのときは保存対象のデータ数を変えたり5行目の処理で複数行をひとつのWriteStringにまとめて書き込むと処理時間は短くなります
これでリングバッファの手順は終わりです
ここでは簡単なバッファリングを紹介しました
ファイルに書き出したいデータは数値型やREAL型や日付時刻型など色々なデータの組合せになると思います
取りたいデータに合わせてsData構造体の内容を変更してください
