本地自主資料採集系統

該公司購買了Next Technologies 國產的NEKST-M 監控樁。 為了確保抽油機運作的可視化,
火災和安全警報、啟動器電壓、室溫、緊急水位。 NEKST-M 的核心是 ATMEGA 1280,這一事實令人鼓舞,因為您可以根據特定需求創建自己的套件。

任務是在最短的時間內以最低的成本創建一個完全自主的本地調度系統,以滿足特定需求。 其基礎是微控制器。 由員工自己開發、製造、創造。

該系統必須在不依賴蜂窩網路、伺服器、互聯網和射頻資源使用許可系統的情況下運行,在監控和控制系統的運行中不得使用計算機,或者最多定期使用筆記型電腦,而無需訪問長期對象(6- 9 個月)。 網路配置具有放射狀結構。 資料在某一點收集,然後透過常規通訊管道或作為硬拷貝發送進行處理。

系統必須提供:

  • 監控抽油機的運作
  • 技術自動化
  • 免受緊急情況後果的影響
  • 緊急訊號
  • 運行時間計算
  • 計算消耗的電量
  • 設備溫度控制
  • 安全和火災警報
  • 定期遠端記錄資訊
  • 未來需求未知

工作環境:

  • 覆蓋面積1平方公里。
  • 物體間的直接可見性
  • 溫度從+50℃到-50℃
  • 濕度高達 100%
  • 生物活性沉積物(黴菌、硫酸鹽還原菌)
  • 根據 GOST ISO 1-2-10816,1-97 級機器的振動,僅此而已
  • 電磁環境 - 使用 KT 6053 接觸器切換電動馬達、RVS-DN 軟啟動設備、SIEMENS MICROMASTER PID 控制設備、根據這些設備的要求在 ISM 和 GSM 範圍內的輻射、現場手工電弧焊
  • 6-10kV配電網中電網電壓過高、供電短時中斷、雷擊過電壓、架空線斷線時的相位不平衡等。

儘管要求如此嚴格,但一步一步解決問題時,實施起來卻相當簡單。

綜合考慮,「Arduino Nano 3.0」板成為了該計劃的「大腦」。 Robotdyn 板有一個 ATMEGA 328 控制器,這是必要的 3,3V 穩壓器
電流 800 mA 和 CH340G UART-USB 轉換器。

首先,運行時間計數器被創建為最新的。 先前使用的安裝在具有無變壓器電源電路的 PIC 上的工業儀表在運行一年內會因電壓突波而發生故障。 只有使用自製 5V 電源連接的部分保持完好。 為了加速安裝和連接的多功能性,從開關設備的端子獲取有關單元狀態的訊號,即使用 1V 三相電源記錄第一相電壓的存在。 為了與控制器配合,採用380V繞組的中間繼電器或由LED和GL220光敏電阻或PC5516光耦組成的光耦。 所有選項均經過測試。 LED 由具有電流限制的整流電壓供電,使用兩個串聯連接的 SVV817​​22 電容器設計用於 630V 電壓,以確保在使用兆歐表意外測試電路時的安全性。
使用 ST7735S LCD 螢幕讀取運行時間讀數,使用 E01-ML01DP05 模組以 2,4 MHz 的頻率透過無線電進行即時資料傳輸。 此元件包含 nRF24L01+ 晶片和 RFX2401C 發送/接收放大器,
輸出功率高達 100 mW。 螺旋天線專為在線計算器中所需的範圍而設計 сайта。 天線類型的選擇取決於排除從周圍金屬結構接收單一反射波的情況。 天線零件是在 3D 列印機上列印的。 計數器的當前狀態儲存在控制器本身的 EEPROM 中,並在意外斷電時恢復。 計數的時間間隔由帶有備用電池的模組形式的RTC晶片DS3231提供。 電源採用3個模組,實際脈衝源220/5V HLK-PM01 600mA,1-5V轉5V轉換器 HW-553 и 03962A - 電池控制器 方案 防止短路、過放電和過充電。 所有組件均在 Aliexpress 網站上購買。

麵包板本地自主資料採集系統
4通道計數器。 輸入端有 LC 濾波器,可防止雙絞線通訊線路受到干擾。 控制物件狀態的資料每秒持續讀取一次,並以彩色顯示在 LCD 上。 讀數每 1 秒更新一次並記錄在非揮發性記憶體中。 36 秒是一小時的 36/1,這是資料所需的格式。 每 100 秒一次。 傳送有關每個控制單元的操作秒數的資訊。 EEPROM 記憶體的寫入-擦除循環次數有限,根據製造商的說法,為 12 次。 最糟糕的選擇是至少有一個單元不斷更新。 第一個計數器的容量為100000個位元組,這是一個長格式的數字,1個計數器,一筆記錄總共佔用4個位元組。 晶片記憶體長度為4字節,16個計數器的1024個條目後,將重新開始記錄。 在 EEPROM 庫中,EEPROM.put 方法不會寫入;如果單元的值與正在寫入的資訊匹配,則單元不會退化。 因此,保證記憶體運行時間將超過64年。 可能但不能保證的工作時間可能會更長。

電路原理圖本地自主資料採集系統
Arduino IDE 中的程式//12 位元組 (328%)

#包括// 核心圖形庫
#包括// 硬體特定庫
#包括
#包括
#包括
#包括
#包括
RF24 無線電(9, 10); // 用於使用 RF24 庫的無線電對象,
// 和腳位編號 nRF24L01+ (CE, CSN)
#包括
DS3231 實時時鐘(SDA、SCL);
時間t;

//#定義TFT_CS 10
#定義TFT_CS 8
#define TFT_RST -1 //您也可以將其連接到Arduino重置
// 在這種情況下,將此 #define pin 設定為 -1!
//#define TFT_DC 9 // DC=RS=A0 - 用於選擇指令或資料暫存器的指定選項。
#定義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);
#包括

位元組移位= 52;
位元組引腳狀態;
unsigned long Pump[4];// 具有 4 秒計數器值的陣列
浮動米= 3600.0;
無符號整數位址=0;
int rc;// 計數器變數
無符號長 sumprim = 0;
無符號長 sumsec = 0;
位元組 i = 0;
位元組 k = 34;
無符號整數 z = 0;
位元組 b = B00000001;
字節 pumrcounter[4]; // 用於儲存物件狀態的數組,1 - 關閉,0 - 開啟。
int 開始 = 0; //

void setup(){

rtc.begin();
radio.begin(); // 啟動 nRF24L01+ 工作
無線電.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); // 日期,29 年 2018 月 XNUMX 日

tft.initR(INITR_BLACKTAB); //初始化ST7735S晶片,黑色標籤
// 如果您使用的是 1.44" TFT,請使用此初始化程序(取消註解)
//tft.initR(INITR_144GREENTAB); //初始化ST7735S晶片,紅色rcB選項卡
tft.setTextWrap(假); // 允許文字超出右邊緣
tft.setRotation( 2 ); // 對於黑色 PCB 和紅色 tft.setRotation(0) 是否。
tft.fillScreen(ST7735_BLACK); //清螢幕

DDRD = DDRD | B00000000;
連接埠 = 連接埠 | B11110000; // 軟體緊縮正在工作,高等級 -
// 受控物件“不工作”,4個高階連接埠D全部寫入“1”,不計數。

for ( rc = 0; rc < 4; rc++)
{
tft.setCursor(3, rc*10+shift); // 顯示控制物件的位置號
tft.print(rc + 1);
}

tft.setCursor(12, 0); //輸出3行文字
tft.println("開發人員與建置"); // 讚美自己所愛的人
tft.setCursor(24, 10); // 或邪惡的版權
tft.print("開發者MM");
tft.setCursor(28, 20);
tft.print("建置 DD");

//資料恢復/////////////////////////////////////////////// /////////////////////

for ( z = 0; z < 1023; z += 16 ) { // 迭代產業的所有儲存格
//並寫入4個幫浦變數的數組,每個計數器4個位元組,因為
// 無符號長變數。 有 4 個計數器,所有 4 個計數器的一筆記錄佔用 16 個位元組。
EEPROM.get(z, 泵[0]); // 因此,沒有 for 循環,體積更小
EEPROM.get(z+4, 泵[1]);
EEPROM.get(z+8, 泵[2]);
EEPROM.get(z+12, 泵[3]);

// 為 4 個計數器的總和分配新的下一個值
sumprim = (泵[0] + 泵[1] + 泵[2] + 泵[3]);

// 將 sumprim 變數中 4 個計數器總和的新值與該變數中的先前值進行比較
// sumsec,如果先前的總和小於或等於新的總和,則指派新的大於或等於的值
// 總和秒值。

if ( sumsec <= sumprim ) {
sumsec = sumprim; //

//並將目前值z賦給位址變量,z是16個值的4位元組區塊的開頭位址
// 同時記錄的計數器(因為當輪詢連接埠時,它的所有 8 位元都會同時寫入,
// 包含連接埠 D 所需的高 4 位元)。
地址=z;
}
}

// 再次存取eeprom記憶體的16位元組區塊的開頭位址,該區塊包含4個記錄的計數器值
// 最後,即由於凍結而關閉或重新啟動先前的值。 記錄最新的
// 將計數器值放入一個由 4 個變數組成的陣列中 Pump。

EEPROM.get(地址, 泵[0]);
EEPROM.get(地址+4,泵[1]);
EEPROM.get(地址+8,泵[2]);
EEPROM.get(地址+12,泵[3]);

地址+=16; //增加寫入下一個區塊的位址,但不覆蓋最後一筆記錄的數據

//資料復原結束////////////////////////////////////////////// ///////////////////////////////////

AttachInterrupt(0, 數, 上升); // 腳位D2,使能中斷,每秒來一次
// 來自 SQW 輸出的 RTC DS3231 脈衝

wdt_啟用(WDTO_8S); // 啟動看門狗定時器,在凍結的情況下重新啟動控制器,時間,
// 為此​​,您需要發出計時器重置命令 wdt_reset( 並避免在正常操作期間重新啟動 - 8 秒。
// 對於測試,不建議將值設為小於 8 秒。在這種情況下,最好重置計時器
// 抽搐,每秒都會發生。

}

無效循環(){
// 空循環,這裡將控制馬達的缺相運行
}

無效計數(){

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(); // 每個週期(即第二個)重置看門狗

for (rc = 0; rc < 4; rc ++) // 檢查輸入狀態符合性的循環開始
// 將連接埠位元設定為連接埠 D 位元的先前讀取狀態
{
pinState = (PIND >> 4) & ( b << rc );

if (pumrcounter [rc] != pinState) { // 如果不匹配,則
pumrcounter[rc] = pinState; // 為連接埠位狀態變數指派新值 1/0
}
// 顏色控制物件的狀態指示
// 藍色是現有螢幕(或庫?)的一個小故障,RGB 和 BGR 混合在一起。
if (pinState == ( b << rc )) {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_BLUE); // 對於低等級計數,將綠色變更為藍色
} {
tft.fillRect(15, ((rc * 10 + 移位)), 7, 7, ST7735_GREEN); // 對於低等級計數,將藍色變更為綠色
泵[rc] += 1; // 操作時間計數器加 1 秒
}
}

k++;
如果(k==36){
k為0;

tft.fillRect(30, 移位, 97, 40, ST7735_BLACK); // 清空運行時間顯示區域
tft.fillRect(60, 120, 73, 7, ST7735_BLACK); // 和日期

tft.setCursor(60, 120); // 設定遊標位置
tft.print(rtc.getDateStr()); //在液晶螢幕上顯示日期

for (rc = 0; rc < 4; rc ++) //輸出整、十分之幾的運行時間
{
tft.setCursor ( 30, rc * 10 + shift ); // 百分之一小時螢幕向下移動 10 個像素
tft.println(泵[rc] / m);
}

// 將「原始」運行時間值(以秒為單位)寫入 EEPROM ////////////////////////////////

對於 (rc = 0; rc < 4; rc++)
{
EEPROM.put(地址,泵[rc]);
地址 += sizeof(float); // 增加寫入位址變數
}
}

// 透過無線電頻道傳送數據,指示應傳送多少位元組。
如果((k == 6)||(k == 18)||(k == 30)){

無符號長數據;

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

for (i = 0; i < 4; i++) {
數據=泵[i];
radio.write(&data, sizeof(data));
}
}
}

最後有一些註解。 計數發生在輸入的低邏輯電平。

對於帶有光敏電阻 GL2 的選項,上拉電阻 R5-R36 為 5516 kOhm。 對於光電晶體管光耦合器和繼電器,設定為 4,7-5,1 kOhm。 Arduino Nano v3.0 引導程式已替換為 Arduino Uno,使用 TL866A 程式設計器來確保看門狗計時器的正確操作。 保險絲經過校正,可在高於 4,3 V 的電壓下工作。未使用外部重設電路 R6 C3。 在範例程式中,發射機頻率不對應於免許可範圍;2,4 MHz 範圍僅限於頻率 2400.0-2483.5 MHz。

E01-ML01DP05 發射器的範圍為 2400-2525 MHz。 一個通道的頻寬為1 MHz,當設定速率為「RF24_2MBPS」時,指定的radio.setChannel(120)通道將被佔用,即下一通道被佔用。 頻段為 2 MHz。

來源: www.habr.com

添加評論