ローカル自律データ収集システム

この記事の続き

同社は、国内生産NEXT TechnologiesのNEXT-M監視ポストを購入しました。 ポンプユニットの動作の視覚化を確実にするために、

火災警報器、スターターの電圧、室温、緊急水位。 NEXT-Mの心臓部はATMEGA 1280であり、この事実は特定のニーズに合わせて独自のキットを作成する可能性という点で勇気づけられました。



このタスクは、完全に自律的なローカルディスパッチシステムを最短時間で、最低コストで作成するように設定されました。 基本はマイクロコントローラです。 開発、製造、すべてスタッフによる。



システムは、セルラーネットワーク、サーバー、インターネット、および無線周波数リソースの使用のためのライセンスシステムに依存せずに動作する必要があり、監視制御システムの作業でコンピューターまたはラップトップの最大定期使用を使用せず、長時間(6-9か月)オブジェクトにアクセスする必要はありません。 ネットワーク構成には放射状構造があります。 データはある時点で収集され、その後、従来の通信チャネルを介して、またはハードコピーとして処理のために送信されます。



システムは以下を提供する必要があります。





労働条件:





このような厳しい要件にもかかわらず、実装は問題に対する段階的な解決策で非常に簡単です。



これらすべてを念頭に置いて、Arduino Nano 3.0ボードは着想の「頭脳」になりました。 Robotdynショールには、必要な3.3V電圧レギュレーターであるATMEGA 328コントローラーがあります

800 mA電流およびCH340G UART-USBへのコンバーター。



まず、稼働時間カウンターが最も関連性の高いものとして作成されました。 トランスレス電源回路を備えたPICで収集された以前使用されていた工業用メーターは、運用年中の電力サージで故障しました。 5Vの電圧の自家製電源の助けを借りてのみ接続されたままでした。 設置と接続の普遍性を高速化するために、ユニットの状態に関する信号がスイッチングデバイスの端子から取得されます。 三相電源380Vによる電圧の第1相の存在の登録。 コントローラとの調整には、220V巻線を備えた中間リレー、またはLEDとフォトレジスタGL5516またはオプトカプラPC817で構成されるオプトカプラが使用されます。 すべてのオプションがテストされました。 LEDは、630Vの電圧用に設計された2つのCBB22コンデンサを使用した電流制限付きの整流電圧で駆動され、Megohmmeterで回路をランダムにチェックする際の安全のために直列に接続されます。

ST7735S LCDスクリーンを使用して動作時間を読み取り、2.4 MHzの周波数でE01-ML01DP05モジュールを使用してリアルタイムデータを無線で送信します。 このデバイスには、nRF24L01 +チップとRFX2401C受信/受信アンプが含まれています。

最大100 mWの出力。 サイトのオンライン計算機で望ましい範囲に設計されたスパイラルアンテナ。 アンテナの種類の選択は、周囲の金属構造からの一度反射した波の受信を除外するためです。 アンテナ部品は3Dプリンターで印刷されます。 カウンターの現在の状態はコントローラー自体のEEPROMに保存され、予期しない停電の場合に復元されます。 アカウントの時間間隔は、バックアップバッテリーを備えたモジュールの形でRTC DS3231チップによって提供されます。 電源ユニットには、3つのモジュール、HLK-PM01 600mAパルスソース220 / 5V自体、1-5Vから5VへのHW-553および03962Aコンバーターが使用され、短絡、過放電、および過充電に対する保護回路を備えバッテリーコントローラーです。 すべてのコンポーネントは、AliexpressのWebサイトで購入しました。



ブレッドボード
画像の代替






4チャンネルカウンター。 入力には、ツイストペア通信回線での干渉から保護するLCフィルターがあります。 制御対象の状態に関するデータは、1秒間に1回常に読み取られ、LCDにカラーで表示されます。 測定値は36秒ごとに更新され、不揮発性メモリに記録されます。 36秒1/100時間で、データが必要なのはこの形式です。 12秒ごと 情報は、各コントロールユニットの操作の秒数で送信されます。 EEPROMメモリーの書き込み消去サイクルの数は、製造元によると100,000回に制限されています。 最悪のオプションは、少なくとも1つのセルが常に更新されている場合です。 最初のカウンターのサイズは4バイトです。これは長い形式の数値で、4カウンターです。合計16バイトが1レコードを占有します。 チップメモリ​​の長さは1024バイトで、64エントリの4カウンターの後、記録が再開されます。 EEPROMライブラリでは、EEPROM.putメソッドは記録しません。セルの値と書き込まれている情報が一致する場合、セルの劣化はありません。 その結果、保証されたメモリ動作時間は7年以上になります。 可能ですが、不当な作業の時間ははるかに長くなる可能性があります。



回路図
画像の代替






Arduino IDEのプログラム
// 12 328バイト(38%)



#include <Adafruit_GFX.h> //コアグラフィックスライブラリ

#include <Adafruit_ST7735.h> //ハードウェア固有のライブラリ

#include <SPI.h>

#include <EEPROM.h>

#include <Wire.h>

#include <nRF24L01.h>

#include <RF24.h>

RF24無線(9、10); // RF24ライブラリを操作するためのラジオオブジェクト、

//およびピン番号nRF24L01 +(CE、CSN)

#include <DS3231.h>

DS3231 rtc(SDA、SCL);

時間t;



//#TFT_CS 10を定義

#define TFT_CS 8

#define TFT_RST -1 //これをArduinoリセットに接続することもできます

//その場合、この#defineピンを-1に設定します!

//#TFT_DC 9を定義// DC = RS = A0-コマンドまたはデータのレジスタの選択の出力を指定するためのオプション。

#define TFT_DC 3



Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS、TFT_DC、TFT_RST);



//オプション2:任意のピンを使用しますが、少し遅いです!

#define TFT_SCLK 13 //これらを任意のピンに設定します!

#define TFT_MOSI 11 //これらを好きなピンに設定してください!

// Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS、TFT_DC、TFT_MOSI、TFT_SCLK、TFT_RST);

#include <avr / wdt.h>



バイトシフト= 52;

バイトpinState;

unsigned long pump [4]; // 4秒カウントの配列

float m = 3600.0;

unsigned int address = 0;

int rc; //カウンターの変数

符号なしlong sumprim = 0;

符号なしlong sumsec = 0;

バイトi = 0;

バイトk = 34;

unsigned int z = 0;

バイトb = B00000001;

バイトpumrcounter [4]; //オブジェクトの状態を保存する配列、1-オフ、0-オン

int start = 0; //



void setup(){



rtc.begin();

radio.begin(); // nRF24L01操作を開始します+

radio.setChannel(120); //データ送信チャネル(0〜127)。

radio.setDataRate(RF24_250KBPS); //データ転送速度(RF24_250KBPS、RF24_1MBPS、RF24_2MBPS)。

radio.setPALevel(RF24_PA_MAX); //送信機電力(RF24_PA_MIN = -18dBm、RF24_PA_LOW = -12dBm、

// RF24_PA_HIGH = -6dBm、RF24_PA_MAX = 0dBm)

radio.openWritingPipe(0xAABBCCDD11LL); //データ転送用の識別子でパイプを開きます



//時刻を設定するには、必要な行のコメントを外します

//rtc.setDOW(1); //曜日

//rtc.setTime(21、20、0); // 24時間形式の時間。

//rtc.setDate(29、10、2018); //日付、2018年10月29日



tft.initR(INITR_BLACKTAB); // ST7735Sチップを初期化、黒タブ

// 1.44 "TFTを使用している場合、このイニシャライザを使用(コメント解除)

//tft.initR(INITR_144GREENTAB); // ST7735Sチップ、RED rcBタブを初期化します

tft.setTextWrap(false); //テキストを右端からはみ出させます

tft.setRotation(2); // BLACK PCBおよびRED tft.setRotation(0)かどうか。

tft.fillScreen(ST7735_BLACK); //画面をクリアします



DDRD = DDRD | B00000000;

PORTD = PORTD | B11110000; //ソフトウェア締め付け作業、高レベル-

//監視対象オブジェクトは「動作しません」、Dの4つのシニアポートすべてに「1」が書き込まれ、アカウントは移動しません。



for(rc = 0; rc <4; rc ++)

{

tft.setCursor(3、rc * 10 + shift); //制御対象の位置の数を出力します

tft.print(rc + 1);

}



tft.setCursor(12、0); // 3行のテキストを出力します

tft.println( "DEVELOPERS&BUILD"); //愛する人をほめる

tft.setCursor(24、10); //または悪の著作権

tft.print( "DEVELOPER MM");

tft.setCursor(28、20);

tft.print( "BUILD-ER DD");



//データリカバリ/////////////////////////////////////////////// ////////////



for(z = 0; z <1023; z + = 16){//業界のすべてのセルを反復処理する

// 4つの変数pumpの配列に書き込みます。各カウンタは4バイトです。

//変数unsigned long。 カウンター4、4つすべてのレコードのうち1つは16バイトです。

EEPROM.get(z、ポンプ[0]); //そのため、forループなしで、より少ないボリューム

EEPROM.get(z + 4、ポンプ[1]);

EEPROM.get(z + 8、ポンプ[2]);

EEPROM.get(z + 12、ポンプ[3]);



// 4-xカウンタの合計の新しい次の値の割り当て

sumprim =(ポンプ[0] +ポンプ[1] +ポンプ[2] +ポンプ[3]);



//変数sumprimの4つのカウンターの合計の新しい値を変数の前の値と比較します

// sumsecおよび前の金額が新しい金額以下の場合、新しい金額以上が割り当てられます

// sumsec値。



if(sumsec <= sumprim){

sumsec = sumprim; //



//および現在の値zがアドレス変数に割り当てられます。zは4つの値からの16バイトのブロックの先頭のアドレスです

//同時に記録されるカウンタ(ポートをポーリングするとき、その8ビットすべてが同時に記録されるため

//必要なポート4の上位4ビットを含む)。

アドレス= z;

}

}



//繰り返しますが、ブロックの開始アドレスのeprompromメモリへのアクセスは、記録された4つのカウンタ値から16バイトです

//最後、つまり ハングのためにシャットダウンまたはリブートする前の値。 最後に記録

// 4つの変数ポンプの配列へのカウンターの値。



EEPROM.get(アドレス、ポンプ[0]);

EEPROM.get(アドレス+ 4、ポンプ[1]);

EEPROM.get(アドレス+ 8、ポンプ[2]);

EEPROM.get(アドレス+ 12、ポンプ[3]);



アドレス+ = 16; //最後のレコードのデータを上書きせずに次のブロックを書き込むためのアドレスを増やします



//データリカバリの終了///////////////////////////////////////////// ////////////////////



attachInterrupt(0、カウント、RISING); // D2ピン、割り込み操作を有効にし、1秒ごとに到着

// SQW出力からRTC DS3231からパルス



wdt_enable(WDTO_8S); //ウォッチドッグタイマーを開始し、ハングした場合にコントローラーを再起動します、時間、

// wdt_reset timer resetコマンドを送信する必要がある(そして通常の操作中の再起動を避ける-8秒。

//テストの場合、値を8秒未満に設定することは推奨されません。この場合、タイマーは

//掘り、そして毎秒。



}



void loop(){

//空のサイクル、ここでは電気モーターの位相外れ動作モードを制御します

}



無効カウント(){



tft.setTextColor(ST7735_WHITE); //フォントの色を設定します

t = rtc.getTime(); //読み取り時間

tft.setCursor(5、120); //カーソルの位置を設定します

tft.fillRect(5、120、50、7、ST7735_BLACK); //時間出力領域をクリアします

tft.print(rtc.getTimeStr()); //時間を表示します



wdt_reset(); //ウォッチドッグタイマーをサイクルごと、つまり1秒ごとにリセットします



for(rc = 0; rc <4; rc ++)//入力状態をチェックするためのループの開始

//ポートDビットの以前の読み取りステータスへのポートビット

{

pinState =(PIND >> 4)&(b << rc);



if(pumrcounter [rc]!= pinState){//そうでない場合は、

pumrcounter [rc] = pinState; //ポートビットのステータス変数を新しい値1/0に割り当てます

}

//カラーコントロールのオブジェクトのステータスの表示

// BLUEは既存の画面(またはライブラリ?)の小さな不具合であり、RGBとBGRが混在しています。

if(pinState ==(b << rc)){

tft.fillRect(15、((rc * 10 + shift))、7、7、ST7735_BLUE); //低レベルアカウントの場合、GREENをBLUEに変更します

} else {

tft.fillRect(15、((rc * 10 + shift))、7、7、ST7735_GREEN); //低レベルアカウントの場合、BLUEをGREENに変更します

ポンプ[rc] + = 1; //ランタイムカウンターに1秒を追加します

}

}



k ++;

if(k == 36){

kは0です。



tft.fillRect(30、shift、97、40、ST7735_BLACK); //ランタイム出力領域をクリアします

tft.fillRect(60、120、73、7、ST7735_BLACK); //および日付



tft.setCursor(60、120); //カーソルの位置を設定します

tft.print(rtc.getDateStr()); // LCD画面に日付を表​​示します



for(rc = 0; rc <4; rc ++)//稼働時間を整数、10分の1、

{

tft.setCursor(30、rc * 10 + shift); //画面上で10ピクセル下にシフトした100分の1時間

tft.println(ポンプ[rc] / m);

}



//「生の」稼働時間(秒単位)をEEPROMに記録します////////////////////////////



for(rc = 0; rc <4; rc ++)

{

EEPROM.put(アドレス、ポンプ[rc]);

アドレス+ = sizeof(float); //レコードアドレス変数をインクリメントします

}

}



//送信するバイト数を示すデータから無線でデータを送信します。

if((k == 6)||(k == 18)||(k == 30)){



符号なしの長いデータ。



radio.write(&start、sizeof(start));



for(i = 0; i <4; i ++){

データ=ポンプ[i];

radio.write(&data、sizeof(data));

}

}

}



最後にいくつかのコメント。 アカウントは入力で低論理レベルになります。

GL5516フォトレジスタを備えたバージョンのサスペンション抵抗R2-R5 36 kOhm。 フォトトランジスターオプトカプラーおよびリレーの場合、4.7-5.1 kOhmを供給します。 Arduino Nano v3.0ブートローダーは、正しいウォッチドッグ操作のためにTL866Aプログラマーを使用してArduino Unoに置き換えられました。 ヒューズは、4.3 Vを超える電圧で動作するように修正されています。外部リセット回路R6 C3は使用されていません。 プログラム例では、トランスミッタ周波数はライセンスのない範囲に対応していません; 2.4 MHzの範囲は2400.0〜2483.5 MHzの周波数に制限されています。

E01-ML01DP05の送信機の範囲は2400-2525 MHzです。 速度を「RF24_2MBPS」に設定すると、指定されたradio.setChannel(120)チャネルと次のチャネル、つまり1つのチャネルの帯域幅は1 MHzです。 帯域は2 MHzです。

継続



All Articles