チャートおよびグラフのArduinoデータ

さまざまなセンサーから詳細な情報を読み取らずに、システムの現在の状態と一定期間にわたるその状態のダイナミクスを単純に評価することが必要な場合があります。 そこで、モバイルデバイスのブラウザーウィンドウまたはローカルネットワークに接続されたコンピューターで表示できる小さな図の美しい写真の形式で、センサーからのデータの変化を示すデバイスを作成したかったのです。 決定要因は、最小コストと実装の容易さでした。



この問題のさまざまな解決策を列挙した後、Arduinoマイクロコントローラーに注目しました。 これらのデバイスの利点は、要素を接続するだけで必要な「鉄」機能を簡単に取得できることです。 たとえば、ローカルネットワークに接続できるようにするには、ネットワークアダプタカードをメインボードの上に置くだけで十分です。 主なことは、対応するコネクタが一致することです。



画像



センサーからの信号は、マイクロコントローラーのアナログ入力に到着し、処理されます。たとえば、事前に設定された必要な時間間隔で平均化されます。 マイクロコントローラーには、httpサーバーを実装するソフトウェアが含まれています。クライアントのブラウザーからの要求に応じて、センサーからローカルネットワークへの情報を含むhtmlページを提供します。 そのため、スマートフォンなどのローカルネットワークに接続されたWebブラウザを備えたデバイスは、グラフを表示できます。



コンバーターのハードウェアは、Atmega328プロセッサーを含むArduino Unoボードとイーサネットシールドの2つの部分で構成されています。 ENC28j60およびW5100のArduinoファミリで利用可能な両方のタイプのイーサネットシールドがテストされました。



Webサーバーの機能は、Arduinoボードの利用可能なメモリのサイズとネットワークボードのアーキテクチャによって非常に制限されていますが、両方のイーサネットシールドで機能するスケッチを作成することができました。



arduinoのソフトウェア(スケッチ)は、2つの異なる使用条件向けに設計されています。 最初のケースでは、データを要求するクライアントがインターネットアクセスを持っていると想定されていたため、視覚化のために外部ライブラリを使用できます。 Googleからヒストグラムを作成するためにライブラリを使用する場合、Arduinoから取得したページの外観は次のようになります。



画像



W5100チップに基づくイーサネットシールドを使用して、このような図の形式でデータを出力するためのスケッチを以下に示します。 ENC28J60チップを搭載したボードを使用する場合は、1行のコメントを解除して、スケッチの次の2行をコメントアウトするだけです。 プログラムはメソッドを使用して、プロセッサメモリの使用を最適化し、空きメモリを最大化し、両方のタイプのネットワークアダプタでプログラムの信頼性の高い動作を実現します。



棒グラフスケッチ
// Webサーバーをヒストグラムとして使用してデータを出力します

//著者A. Konovalov 2015

//#<UIPEthernet.h>を含む// ENC28J60を操作するため

#include <Ethernet.h>

#include <SPI.h

バイトmac [] = {0xDE、0xAD、0xBE、0xEF、0xFE、0xED};

IPAddress ip(192,168,26,15);



EthernetServerサーバー(80);

const char str1 [] PROGMEM = "<!DOCTYPE html>";

const char str2 [] PROGMEM = "";

const char str12 [] PROGMEM = "";



const char * const string_table [] PROGMEM = {str1、str2、str3、str4、str5、str6、str7};

const char * const string_table2 [] PROGMEM = {str8、str9、str10、str11、str12};

char myChar;

文字バッファ[80];



unsigned long previousMillis1 = 0; //最後の時点

unsigned long previousMillis2 = 1; //最後の時点

unsigned long previousMillis3 = 1; //最後の時点



long OnTime2 = 60000; //分

long OnTime3 = 1800000; // 30分

int In_sec = 0; // 1秒あたりのカウントダウン

int In_min = 0; //最小カウント

int In_half = 0; // 30分カウント



long Sum_min = 0; //毎分

long Sum_half = 0; //半時間

float Sum_base_min = 0;

float Sum_base_half = 0;

int i、j、k = 0;



ボイド設定()

{

//イーサネット接続とサーバーを開始します:

Ethernet.begin(mac、ip);

server.begin();



}

//符号なしlong begMillis = millis(); //ミリ秒単位の開始時間

ボイドループ()

{

unsigned long currentMillis = millis(); //現在の時間(ミリ秒)



In_sec = analogRead(0);

Sum_min = Sum_min +(currentMillis-previousMillis1)* In_sec;

In_min =(Sum_min + Sum_base_min)/(OnTime2 * i + currentMillis-previousMillis2);

Sum_half = Sum_half +(currentMillis-previousMillis1)* In_sec;

In_half =(Sum_half + Sum_base_half)/(OnTime3 * j + currentMillis-previousMillis3);

previousMillis1 = currentMillis; //瞬間を覚える



if(currentMillis-previousMillis2> = OnTime2)

{i = 1;

Sum_base_min = Sum_min;

previousMillis2 = currentMillis; //瞬間を覚える

Sum_min = 0;

}

if(currentMillis-previousMillis3> = OnTime3)

{j = 1;

Sum_base_half = Sum_half;

previousMillis3 = currentMillis; //瞬間を覚える

Sum_half = 0;

}



EthernetClientクライアント= server.available();

if(クライアント){

boolean currentLineIsBlank = true;

while(client.connected()){

if(client.available()){

char c = client.read();

if(c == '\ n' && currentLineIsBlank){

for(int i = 0; i <7; i ++)

{

strcpy_P(buffer、(char *)pgm_read_word(&(string_table [i])));

client.print(バッファ);

遅延(500);

}

client.print( "['Enter 1'、");

client.print(In_sec);

client.print( "、");

client.print(In_min);

client.print( "、");

client.print(In_half);

client.print( "]、]);");



for(int i = 0; i <5; i ++)

{

strcpy_P(buffer、(char *)pgm_read_word(&(string_table2 [i])));

client.print(バッファ);

遅延(500);

}

休憩;

}

if(c == '\ n'){

}

else if(c!= '\ r'){



}

}

}

遅延(1);

client.stop();

}

}









このスケッチでは、データはゼロアナログ入力から読み取られ、30分および1分間隔で平均化されます。 192.168.26.15のクライアントのhttpから要求されると、このデータはヒストグラムとして表示されます。 もちろん、このプログラムをダウンロードする前に、ローカルネットワークの目的のアドレスを入力する必要があります。



オプションで、折れ線グラフの形式でarduinoからデータを出力することもできます。



画像



このようなデータプレゼンテーションのスケッチを以下に示します。



折れ線グラフのスケッチ
// Webサーバーを使用してグラフ形式でデータを出力します

//著者A. Konovalov 2015

//#<UIPEthernet.h>を含める

#include <Ethernet.h>

#include <SPI.h>

//以下にコントローラーのMACアドレスとIPアドレスを入力します。

// IPアドレスはローカルネットワークに依存します。

バイトmac [] = {0xDE、0xAD、0xBE、0xEF、0xFE、0xED};

IPAddress ip(192,168,26,15);



//イーサネットサーバーライブラリを初期化します

//使用するIPアドレスとポート

//(ポート80はHTTPのデフォルトです):

EthernetServerサーバー(80);

const char str1 [] PROGMEM = "<!DOCTYPE html> <script src =";

const char str2 [] PROGMEM = "\" www.google.com/jsapi?autoload= {'modules':[{'name': ";

const char str3 [] PROGMEM = "'visualization'、 'version': '1'、 'packages':['corechart']}]} \"> ";

const char str4 [] PROGMEM = "";

const char str12 [] PROGMEM = "";



const char * const string_table [] PROGMEM = {str1、str2、str3、str4、str5、str6、str7};

const char * const string_table2 [] PROGMEM = {str8、str9、str10、str11、str12};

char myChar;

文字バッファ[80];



unsigned long previousMillis1 = 0; //最後の時点

unsigned long previousMillis2 = 1; //最後の時点

unsigned long previousMillis3 = 1; //最後の時点



long OnTime2 = 60000; //分

long OnTime3 = 600000; // 30分

int In_sec = 0; // 1秒あたりのカウントダウン

int In_min = 0; //最小カウント

int In_half = 0; // 30分カウント



long Sum_min = 0; //毎分

long Sum_half = 0; //半時間

float Sum_base_min = 0;

float Sum_base_half = 0;

int i、j、k = 0;



ボイド設定()

{

//イーサネット接続とサーバーを開始します:

Ethernet.begin(mac、ip);

server.begin();



}

//符号なしlong begMillis = millis(); //ミリ秒単位の時間

ボイドループ()

{

unsigned long currentMillis = millis(); //現在の時間(ミリ秒)



In_sec = analogRead(0);

Sum_min = Sum_min +(currentMillis-previousMillis1)* In_sec;

In_min =(Sum_min + Sum_base_min)/(OnTime2 * i + currentMillis-previousMillis2);

Sum_half = Sum_half +(currentMillis-previousMillis1)* In_sec;

In_half =(Sum_half + Sum_base_half)/(OnTime3 * j + currentMillis-previousMillis3);

previousMillis1 = currentMillis; //瞬間を覚える



if(currentMillis-previousMillis2> = OnTime2)

{i = 1;

Sum_base_min = Sum_min;

previousMillis2 = currentMillis; //瞬間を覚える

Sum_min = 0;

}

if(currentMillis-previousMillis3> = OnTime3)

{j = 1;

Sum_base_half = Sum_half;

previousMillis3 = currentMillis; //瞬間を覚える

Sum_half = 0;

}



/ *

In_sec = 990;

In_min = 500;

In_half = 90;



* /

//着信クライアントをリッスンします

EthernetClientクライアント= server.available();

if(クライアント){

// HTTPリクエストは空白行で終了します

boolean currentLineIsBlank = true;

while(client.connected()){

if(client.available()){

char c = client.read();

if(c == '\ n' && currentLineIsBlank){



for(int i = 0; i <7; i ++)

{

strcpy_P(buffer、(char *)pgm_read_word(&(string_table [i]))); //必要なキャストとデリファレンス、コピーのみ。

client.print(バッファ);

遅延(500);

}



client.print( "['Now'、");

client.print(660);

client.print( "、");

client.print(1120);

client.print( "]、]);");





for(int i = 0; i <5; i ++)

{

strcpy_P(buffer、(char *)pgm_read_word(&(string_table2 [i]))); //必要なキャストとデリファレンス、コピーのみ。

client.print(バッファ);

遅延(500);

}



休憩;

}

if(c == '\ n'){

//新しい行を開始しています

currentLineIsBlank = true;

}

else if(c!= '\ r'){

//現在の行でキャラクターを取得しました

currentLineIsBlank = false;

}

}

}

// Webブラウザにデータを受信する時間を与えます

遅延(1);

//接続を閉じます:

client.stop();

}

}





さらに、Googleライブラリを使用する可能性の調査の一環として、 好奇心から、アナログ測定デバイスの形式で情報を表示できるスケッチが作成されました。 これにより、現在の信号値をすばやく評価できます。



画像



デバイスでスケッチする
// Webサーバーを使用してデバイスの形式でデータを出力します

//著者A. Konovalov 2015

//#<UIPEthernet.h>を含める

#include <Ethernet.h>

#include <SPI.h>



バイトmac [] = {0xDE、0xAD、0xBE、0xEF、0xFE、0xED};

IPAddress ip(192,168,26,15);



EthernetServerサーバー(80);

const char str1 [] PROGMEM = "<!DOCTYPE html>";

const char str2 [] PROGMEM = "";

const char str12 [] PROGMEM = "";



const char * const string_table [] PROGMEM = {str1、str2、str3、str4、str5、str6、str7};

const char * const string_table2 [] PROGMEM = {str8、str9、str10、str11、str12};

char myChar;

文字バッファ[80];



int In_sec = 0; // 1秒あたりのカウントダウン

int i、j、k = 0;



ボイド設定()

{

//イーサネット接続とサーバーを開始します:

Ethernet.begin(mac、ip);

server.begin();



}

//符号なしlong begMillis = millis(); //ミリ秒単位の時間

ボイドループ()

{

In_sec = analogRead(0);

EthernetClientクライアント= server.available();

if(クライアント){

// HTTPリクエストは空白行で終了します

boolean currentLineIsBlank = true;

while(client.connected()){

if(client.available()){

char c = client.read();

if(c == '\ n' && currentLineIsBlank){



for(int i = 0; i <7; i ++)

{

strcpy_P(buffer、(char *)pgm_read_word(&(string_table [i]))); //必要なキャストとデリファレンス、コピーのみ。

client.print(バッファ);

遅延(500);

}



client.print(In_sec);

client.print( "]]);");



for(int i = 0; i <5; i ++)

{

strcpy_P(buffer、(char *)pgm_read_word(&(string_table2 [i]))); //必要なキャストとデリファレンス、コピーのみ。

client.print(バッファ);

遅延(500);

}



休憩;

}

if(c == '\ n'){

//新しい行を開始しています

currentLineIsBlank = true;

}

else if(c!= '\ r'){

//現在の行でキャラクターを取得しました

currentLineIsBlank = false;

}

}

}

// Webブラウザにデータを受信する時間を与えます

遅延(1);

//接続を閉じます:

client.stop();

}

}







インターネットに接続されたデバイスを使用してセンサーからデータを読み取ることができない場合、Scalable Vector Graphic(SVG)の使用に基づいて、Arduinoでダイアグラムを構築する別の方法が試されています。



なぜなら arduinoからデータをリクエストする際の以下のスケッチの結果として、パラメーターの変更のダイナミクスを評価する必要がある場合、ブラウザー画面に次の図が表示されます。



画像



ダイアグラムを一目見れば、以前に定義した時間間隔でのパラメーター変更のダイナミクスを理解できます。



スケッチは次のとおりです。



スケッチsvgチャート
// Webサーバーをヒストグラムとして使用してデータを出力します

//著者A. Konovalov 2015



//#<UIPEthernet.h>を含める

#include <Ethernet.h>

#include <SPI.h>



バイトmac [] = {0xDE、0xAD、0xBE、0xEF、0xFE、0xED};

IPAddress ip(192,168,26,15);



EthernetServerサーバー(80);

const char str1 [] PROGMEM = "";

const char str2 [] PROGMEM = "/>";

const char str4 [] PROGMEM = "";

char myChar;

int out;



unsigned long previousMillis1 = 0; //最後の時点

unsigned long previousMillis2 = 1; //最後の時点

unsigned long previousMillis3 = 1; //最後の時点



long OnTime2 = 60000; //分

long OnTime3 = 600000; // 30分

int In_sec = 0; // 1秒あたりのカウントダウン

int In_min = 0; //最小カウント

int In_half = 0; // 30分カウント



long Sum_min = 0; //毎分

long Sum_half = 0; //半時間

float Sum_base_min = 0;

float Sum_base_half = 0;

int i、j、k = 0;



ボイド設定()

{



Ethernet.begin(mac、ip);

server.begin();



}

//符号なしlong begMillis = millis(); //ミリ秒単位の時間

ボイドループ()

{

unsigned long currentMillis = millis(); //現在の時間(ミリ秒)



In_sec = analogRead(0);

Sum_min = Sum_min +(currentMillis-previousMillis1)* In_sec;

In_min =(Sum_min + Sum_base_min)/(OnTime2 * i + currentMillis-previousMillis2);

Sum_half = Sum_half +(currentMillis-previousMillis1)* In_sec;

In_half =(Sum_half + Sum_base_half)/(OnTime3 * j + currentMillis-previousMillis3);

previousMillis1 = currentMillis; //瞬間を覚える



if(currentMillis-previousMillis2> = OnTime2)

{i = 1;

Sum_base_min = Sum_min;

previousMillis2 = currentMillis; //瞬間を覚える

Sum_min = 0;

}

if(currentMillis-previousMillis3> = OnTime3)

{j = 1;

Sum_base_half = Sum_half;

previousMillis3 = currentMillis; //瞬間を覚える

Sum_half = 0;

}



EthernetClientクライアント= server.available();

if(クライアント){

// HTTPリクエストは空白行で終了します

boolean currentLineIsBlank = true;

while(client.connected()){

if(client.available()){

char c = client.read();

if(c == '\ n' && currentLineIsBlank){



for(k = 0; k <strlen(str1); k ++)

{

myChar = pgm_read_byte_near(str1 + k);

client.print(myChar);

}



for(k = 0; k <strlen(str2); k ++)

{

myChar = pgm_read_byte_near(str2 + k);

client.print(myChar);

}

out = 200-In_sec / 3;

client.print(out);

client.print( "100、");

client.print(out);

client.print( "250、");

out = 200-In_min / 3;

client.print(out);

client.print( "300、");

out = 200-In_half / 3;

client.print(out);



for(k = 0; k <strlen(str3); k ++)

{

myChar = pgm_read_byte_near(str3 + k);

client.print(myChar);

}

client.println();

client.print(In_sec);

client.println();

client.print(In_min);

client.println();

client.print(In_half);

for(k = 0; k <strlen(str4); k ++)

{

myChar = pgm_read_byte_near(str4 + k);

client.print(myChar);

}

休憩;

}



if(c == '\ n'){

//新しい行を開始しています

currentLineIsBlank = true;

}

else if(c!= '\ r'){

//現在の行でキャラクターを取得しました

currentLineIsBlank = false;

}

}

}

// Webブラウザにデータを受信する時間を与えます

遅延(1);

//接続を閉じます:

client.stop();

}

}











上記のスケッチは、最も簡単な手段を使用して、Webサーバーやサーバー側のデータ処理アプリケーションなどの追加の機器やソフトウェアを使用せずに、動作条件下でセンサーから許容可能なタイプの情報を表示する方法を示しています。 もちろん、このデータ転送方法では、ローカルネットワークが必要です。モバイルデバイスの場合は、このネットワークへのWi-Fiアクセスが必要です。



スケッチを書くとき、 開発者のガイドとHabrの記事「SVGグラフィックスに関する知識」が大いに役立ちました。



UIPライブラリは標準スイートの一部ではありませんが、 ここからダウンロードできます



スケッチの例と、私があなたに提供したトレーニング資料へのリンクに基づいて、Arduinoがあなたが一番好きな形でグラフィックを表示するのが簡単になることを願っています。

PS判明したように、Habraのネタバレは容赦なくスケッチからhtmlコードを断片化しました。 したがって、読者をがっかりさせないために、かみ傷の断片を写真の形で追加しました。
最もおいしい
Svg



アプライアンス



行



棒グラフ






All Articles