カンマ区切りの文字列の定期送り出し

1.概要

カンマ区切りの文字列をファイルから読出し、一定期間で順次送り出すNode-REDフローを紹介します。用途としては、実験環境のテストなど、あらかじめ決まったデータが送られてくる環境を作成したい場合などが考えられます。新しい技術は、ファイルから読み込んだカンマ区切りのデータを配列に読み込むところです。配列に読み込んでからは、配列データの平均・分散・標準偏差乱数の生成の技術の組み合わせです。

2. 仕様

以下の様なカンマ区切りの60個のデータが記載されたファイルを読み込み、1秒毎にダッシュボードのチャートに送り出します。60個のデータをグラフ化します。スタートボタンを押すと画面がクリアされ、1秒ごとにデータを下記込んでいきます。60個読み込んだ時点で終了します。

C:\Users\hayak\data\SampleData01.csv

100,106,87,97,112,101,120,100,104,124,129,119,131,141,148,138,131,135,124,136,139,130,150,154,153,141,124,108,109,100,106,96,97,96,116,101,108,119,136,128,131,129,132,142,130,136,116,133,119,130,116,133,139,136,143,123,109,92,103,95

3. Node-REDのフロー

3-1. 全体像

Node-REDのフローの全体像を以下に示します。大きく4つのパートに分かれます。(1) 初期化、(2) csvファイル読込、(3) 配列定期読出、(4) グラフ表示の4つです。csvファイル読込部で、あらかじめカンマ区切りデータを配列に読み込みます。そこまでが終わったら、配列定期読出部でdelayノードに指定された時間で送り出していきます。丸字番号はLink outとLink inの接続を示しています。

3-2. flow変数

functionノードで使用しているflow変数をまとめます。

3-3. 初期化部のフロー

初期化部は、injectノードとダッシュボードのbuttonノードとfunctionノードで構成しています。injectのボタンを押すか、ダッシュボードでStartボタンを押すと処理が開始されると同時に、
ダッシュボードのチャートをクリアします。そして、flow変数の初期化を行います。

・injectノードは配置するだけで、プロパティ変更は無しです。
・button ノード
① ダッシュボードのタブとグループの設定を行います。 グループの幅は、12に設定します。
② Sizeを”3×1“に設定します。
③ “if msg arrives on input, emulate a button click.”にチェックを入れます。
・ functionノード
① 初期化処理を記載します。

// 配列の要素数
context.flow.length = 60;

// 配列作成
if (!context.flow.array) {
    context.flow.array = new Array(flow.get("length"));
}
// 配列の初期化:データを0で埋める
context.flow.array.fill(0);

// 処理実行カウンタ
flow.set("count", 0);
return msg;

3-4. csvファイル読込部のフロー

csvファイル読込部は、read fileノードとcsvノードとsplitノードとfunctionノードの4つで構成されています。read fileノードでカンマ区切りのデータを読み込み、csvノードでNode-REDのObject形式に変換します。その後、splitノードで1つずつのデータの分解し、後段に送ります。functionノードで送られてきたデータを配列に入力します。
flow.lengthで指定した数だけ読み込むまで、後段にデータを送りません。配列がいっぱいになったら、後段にmsgを送ります。ここで、csvノードとsplitノードは配置するだけで変更はありません。
・read fileノード
① ファイルのパスをファイル名欄に記載します。
・functionノード
① きたデータを配列にpushしていきます。
② こ送られてこで、splitノードから送られてくる情報”msg.parts.index“(データの数情報)を利用して、配列がいっぱいになったかどうかを判断しています。

// 1bit下位にシフト
var shifted = context.flow.array.shift();
// 乱数を配列の最上位に代入
context.flow.array.push(msg.payload);
// 後段への出力準備
msg.array = context.flow.array;
msg.length = context.flow.length;

// 配列がフルになったらmsgを返す
if (msg.parts.index == msg.length -1 ){
    return msg;
}

3-5. 配列定期読出し部のフロー

配列定期読出し部は、functionノードとdelayノードで構成されています。配列読出し部は、msgが送られてくるたびに、データを一つずつ送り出していきます。delayノードは1秒待って、msgをfunctionノードに送ります。このループで1秒毎の送り出しを実現しています。functionノードはflow.countで送り出したデータの数を管理しています。flow.lengthを超えない間送り出します。
・functionノード
① msg.payload = flow.array[count] で配列のデータを送り出しています。 countとlengthを比較してデータの数を管理しています。
・delayノード
① 遅延値を1秒に設定しています。この時間ごとにデータが送りだされます。

var count = flow.get("count");
var length = context.flow.length;

if (count < length){
    msg.payload = context.flow.array[count];
    flow.set("count", count + 1);
    return msg;
}

3-6. グラフ表示部のフロー

グラフ表示部は、buttonノードとchartノードで構成されています。
・buttonノード
① ダッシュボードのタブとグループの設定を行います。 グループの幅は、12に設定します。
② Sizeを”3×1“に設定します。
③ payload をjsonフォーマットにし、”[]”(空配列)を入力します。これで、チャートノードに空配列が送られ、チャートがクリアされます。
④ “if msg arrives on input, emulate a button click.”にチェックを入れます。
・chartノード
① ダッシュボードのタブとグループの設定を行います。 グループの幅は、12に設定します。
② Sizeを”12×6“に設定します。
③ データの最小値、最大値が分かっているのであれば、記入します。

4. グラフ表示動作確認

次に、ダッシュボード画面に移り、動作の確認を行います。
ダッシュボードでスタートボタンを押すと、チャートがクリアされ、データが1秒ごとに送られてきて表示されます。60個のデータを表示して止まります。

 

データの順次送り出しは、JSONファイルからも行うことができます。
JSON動作記述ファイルからアームロボットを動かす事例についてもご覧ください。