Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8691

Arduinoの測定値をNode.jsで受けてSocket.ioとchart.jsでリアルタイムにグラフ表示

$
0
0

概要

Arduinoの測定値をリアルタイムにグラフ表示してみたかったので、Node.js諸々を用いてブラウザ上にグラフ表示してみました。
今回はひとまず光センサーを測定対象にしました。光センサーの抵抗値の変化を電圧としてArduinoのアナログ入力で測定しています。

普段コーディングしない人間のコードなので変な箇所が多々あるかもしれません。その辺はご了承ください。

構成

ハードウェアとソフトウェアの構成を示します。Arduino周りの回路はDEVICE PLUSの記事を参考にしてください。

ハードウェア

  • PC (Mac)
  • Arduino UNO (PCとUSB接続)
  • 光センサー回路
    • ブレッドボード
    • 光センサー
    • 抵抗(1kΩくらい)
    • ジャンパー線

ソフトウェア

  • Node.jsのフレームワークであるExpress
  • Arduinoとシリアル通信するためのserialportライブラリ
  • リアルタイム通信するためのSocket.ioライブラリ
  • グラフ表示するためのchart.jsライブラリ

ソースコード

ソースコードは以下の4つです。

  • Arduino
    • serialCom.ino
  • サーバ側
    • app.js
  • クライアント(ブラウザ)側
    • index.html
    • index.js

Arduino

serialCom.ino
intanalogPin=A3;doubleaval=0;doubleval=0;voidsetup(){Serial.begin(9600);}voidloop(){aval=analogRead(analogPin);val=5*aval/1024;Serial.println(val);delay(100);}

アナログ入力のA3ピンと5V出力を使用しています。(使用する端子は回路によって変わります。)
analogReadで得られる数値は10bitのA/Dコンバータの出力コードなので、電圧に変換しています。測定間隔は100msにしました。

サーバ側

app.js
varexpress=require('express');varapp=express();varhttp=require('http').Server(app);vario=require('socket.io')(http);constSerialPort=require('serialport');constReadline=require('@serialport/parser-readline');constport=newSerialPort('/dev/cu.usbmodem141101',{baudRate:9600});constparser=newReadline();port.pipe(parser);app.use(express.static('public'));app.get('/',function(req,res){res.sendFile(__dirname+'/index.html');});// ブラウザ側とのコネクション確立io.on('connection',(socket)=>{console.log('a user connected');socket.on('disconnect',()=>{console.log('user disconnected');});});//サーバ起動http.listen(3000,function(){console.log('listening on *:3000');});//Arduinoからデータを受信したらクライアントへ送信parser.on('data',(data)=>{io.emit('graph update',(data));});

必要なモジュールをインポートしてそれぞれ設定します。
Arduinoからのデータをシリアルポートで待ち受けます。(ポート名は環境によって変わります。)
httpサーバのポート3000で待ち受けます。
socket.ioでクライアントのブラウザと接続します。
Ardionoからシリアルポート経由でデータを受信したらブラウザへデータを送信します。

クライアント側

index.html
<!doctype html><html><head><title>グラフテスト</title><script src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.min.js'></script><script src='//code.jquery.com/jquery-3.2.1.min.js'></script><script src='http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.2/moment.min.js'></script><script src='//cdn.socket.io/socket.io-1.4.5.js'></script></head><body><canvasid="canvas"width="500"height="500"></canvas><script src='index.js'></script></body></html>

jquery, chart.js, moment.js, socket.ioを読み込んでいます。
(moment.jsをバンドルしたchart.jsもあるみたいですが、今回はそのまま。)
canvasタグ内にchart.jsでグラフが描画されます。
script部分は別ファイルにしています。

index.js
constsocket=io.connect();varctx=document.getElementById('canvas').getContext('2d');// グラフの作成varmyChart=newChart(ctx,{type:'line',data:{labels:[],datasets:[{label:'data-label1',data:[],backgroundColor:'rgba(0,0,225,1)',borderColor:'rgba(0,0,225,1)',borderWidth:1,lineTension:0,fill:false}]},options:{title:{display:true,text:'CHART TITLE'},scales:{xAxes:[{ticks:{//autoSkip: true,maxTicksLimit:10}}],yAxes:[{ticks:{// beginAtZero:true,// autoSkip: true,// maxTicksLimit: 10,min:0,max:5,stepSize:1}}]},// グラフサイズ固定responsive:false,//maintainAspectRatio: false}});$(()=>{// サーバから値を受け取った時の処理socket.on('graph update',(recievedData)=>{// 現在時刻の取得consttime=moment();constoutputTime=time.format('HH:mm:ss');// 追加するデータのラベルに時間を追加myChart.data.labels.push(outputTime);// グラフにデータを追加myChart.data.datasets[0].data.push(recievedData);// データ数が100以上なら一番古い要素を削除if(myChart.data.datasets[0].data.length>100){myChart.data.labels.shift();myChart.data.datasets[0].data.shift();};// グラフの表示を更新myChart.update();})});

myChartがグラフの設定です。
その後に続くのがサーバからデータを受け取った時の処理です。
moment.jsでラベルに現在時刻を追加しています。
無限にデータが増え続けるので、データ数100を上限にしています。

結果

ArduinoをUSBで接続してから、ターミナルでnode app.jsと叩いてサーバを起動、ブラウザで127.0.0.1:3000へアクセスするとこんな感じのグラフが表示されます。
ダウンロード.png
光センサーの上で手で光を遮ったりしたグラフになります。光を遮ると光センサーの抵抗値が上がるので電圧も上がります。
横軸がなぜか均等にならないのですが、気が向いたら改善します。


Viewing all articles
Browse latest Browse all 8691

Trending Articles