Virksomheden har anskaffet overvågningsposter NEXST-M af indenlandsk produktion fra „Next Technologies“. For at sikre visualisering af pumpens arbejde,
brand- og tyverialarm, spænding på starterne, temperatur i rummet, nødvandstand. Hjertet i NEXST-M er ATMEGA 1280, og denne fakta gav håb i forhold til muligheden for at skabe et skræddersyet system til specifikke behov.
Opgaven blev stillet om at skabe et fuldstændigt autonomt lokalt kontrolsystem til specifikke behov på kortest mulige tid og med minimale omkostninger. Grundlaget er mikrocontrolleren. Udviklingen og produktionen udføres af det samme personale.
Systemet skal fungere uden afhængighed af mobilnetværk, servere, internettet og tilladelsessystemet til brug af radiofrekvensressourcer, uden at bruge computere til kontrol- og styresystemer, eller maksimalt sporadisk brug af bærbare computere, uden adgang til objekterne i en længere periode (6-9 mdr.). Netværkskonfigurationen har en radial struktur. Data indsamles ét sted og sendes derefter til behandling via almindelige kommunikationskanaler eller som en fysisk kopi.
Systemet skal sikre:
- overvågning af pumpestationen
- teknologisk automatik
- beskyttelse mod konsekvenserne af nødsituationer
- alarm for nødtilstande
- tælling af driftstid
- tælling af forbrugt elektricitet
- overvågning af udstyrets temperatur
- brand- og tyverialarm
- periodisk fjernlæsningsinformation
- ukendte krav i fremtiden
Driftsbetingelser:
- dækningsområde 1 kv.km.
- fri synslinje mellem objekterne
- temperatur fra +50 til -50 C
- fugtighed op til 100%
- biologisk aktive belægninger (skimmel, sulfat-reducerende bakterier)
- vibration, højst maskiner af klasse 1-2 ifølge GOST ISO 10816-1-97
- elektromagnetisk miljø - kommutation af elektriske motorer med kontakterne KT 6053, blødstartapparater RVS-DN, PID-reguleringsudstyr fra SIEMENS MICROMASTER, stråling i ISM og GSM-båndet i henhold til kravene til disse enheder, manuel lysbuesvejsning på stedet
- overvoltage in the network, brief interruptions in power supply, lightning surges, phase imbalance when a wire breaks in 6-10 kV distribution networks.
Despite such strict requirements, the implementation is quite simple when the task is solved in stages.
Taking everything into account, the 'brain' of the project became the 'Arduino Nano 3.0' board. The board from 'Robotdyn' features an ATMEGA 328 microcontroller and a necessary 3.3V voltage stabilizer.
The current is 800 mA and a CH340G UART-USB converter.
First and foremost, counters for operational time were created as the most relevant. Previously used industrial counters built on PIC microcontrollers with non-transformer power supply circuits failed due to voltage spikes over a year of operation. Only those connected by homemade 5V power supplies remained intact. To speed up installation and ensure versatility in connection, the signal about the status of the units is taken from the terminals of the switching devices, i.e., registering the presence of the 1st phase of voltage in three-phase 380V power supply. An intermediate relay with a 220V winding or an optocoupler made from a diode and a GL5516 photoresistor or the PC817 optocoupler is used for compatibility with the controller. All variants were tested in operation. The LED is powered by rectified voltage with current limiting using two capacitances СВВ22 rated for 630V connected in series for safety when unintentionally testing circuits with a megohmmeter.
Reading the operational time readings using an ST7735S LCD screen, transmitting data via radio channel in real time with the E01-ML01DP05 module at a frequency of 2.4 GHz. This device contains the nRF24L01+ chip and a RFX2401C reception-transmission amplifier,
with an output power of up to 100 mW. The antennas are spiral-shaped, calculated for the desired range in an online calculator. Valget af antennetype er baseret på udelukkelsen af modulation fra enkeltreflekterede bølger fra omkringliggende metalstrukturer. Antennekomponenterne er printet på en 3D-printer. Den aktuelle tilstand af tællerne gemmes i EEPROM'en på kontrolleren og kan genskabes i tilfælde af uventet strømafbrydelse. Tidsintervallerne for optælling drives af RTC-chippen DS3231, som fungerer som et modul med en reservebatteri. Der anvendes 3 moduler i strømforsyningen, den egentlige impulsstrømforsyning er 220/5V HLK-PM01 600mA, en konverter fra 1-5V til 5V. og — en batterikontroller, som har til beskyttelse mod kortslutning, overafladning og overopladning. Alle komponenter blev købt på Aliexpress.
Prøveplade
4-kanals tæller. Der er LC-filtre på indgangene for at beskytte mod interferens i kommunikationslinjen fra tvistet par. Data om tilstanden af de kontrollerede objekter læses konstant én gang i sekundet og vises med farver på LCD-skærmen. Opdatering af målinger og skrivning til ikke-flygtig hukommelse sker hvert 36. sekund. 36 sekunder svarer til 1/100 time, præcis i dette format kræves dataene. Hver 12. sekund overføres information om antallet af sekunder, hver kontrolaggregat har været i drift. EEPROM-hukommelsen har et begrænset antal skrive-slette cykler, ifølge producenten 100000 gange. Den værste situation er, når der konstant foretages opdateringer af mindst én celle. Størrelsen på 1 tæller er 4 byte, hvilket er et tal af long-format, 4 tællere, i alt 16 byte til en skriveoperation. Længden af chip-hukommelsen er 1024 byte, efter 64 skriver i 4 tællere, vil skrivningen starte forfra. I EEPROM-biblioteket udfører metoden EEPROM.put ikke skrivning, hvis celleværdien og den skrivne information er ens, der vil ikke være nogen forringelse af cellerne. Resultatet er, at den garanterede levetid for hukommelsen vil være mere end 7 år. Den mulige, men ikke-garanterede driftstid kan være meget længere.
Principskema
Programmet i Arduino IDE//12 328 байт (38%)
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
#include <EEPROM.h>
#include <Wire.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // radioobjektet til brug med RF24-biblioteket,
// и номера выводов nRF24L01+ (CE, CSN)
#include <DS3231.h>
DS3231 rtc(SDA, SCL);
Time t;
//#define TFT_CS 10
#define TFT_CS 8
#define TFT_RST -1 // you can also connect this to the Arduino reset
// in which case, set this #define pin to -1!
//#define TFT_DC 9 // DC=RS=A0- варианты обозначений вывода выбора регистра команд или данных.
#define TFT_DC 3
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// Option 2: use any pins but a little slower!
#define TFT_SCLK 13 // set these to be whatever pins you like!
#define TFT_MOSI 11 // set these to be whatever pins you like!
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
#include <avr/wdt.h>
byte shift = 52;
byte pinState;
unsigned long pump[4]; // array med 4 værdier fra tællerne sekunder
float m = 3600.0;
unsigned int address = 0;
int rc; // variabel til tællerne
unsigned long sumprim = 0;
unsigned long sumsec = 0;
byte i = 0;
byte k = 34;
unsigned int z = 0;
byte b = B00000001;
byte pumrcounter[4]; // array til opbevaring af tilstandene af objekterne, 1- slukket, 0- tændt.
int start = 0; //
void setup() {
rtc.begin();
radio.begin(); // Initialiserer arbejdsgangen for nRF24L01+
radio.setChannel(120); // datakanal (fra 0 til 127).
radio.setDataRate (RF24_250KBPS); // dataoverføringshastighed (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS).
radio.setPALevel (RF24_PA_MAX); // transmissionskraft (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm,
// RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openWritingPipe (0xAABBCCDD11LL); // Åbner rør med identifikator til dataoverførsel
// Для установки времени- раскомментировать нужные строки
//rtc.setDOW(1); // День недели
//rtc.setTime(21, 20, 0); // Время, в формате 24 часа.
//rtc.setDate(29, 10, 2018); // Дата, 29 октября 2018г.
tft.initR(INITR_BLACKTAB); // initialiser en ST7735S-chip, sort label
// Use this initializer (uncomment) if you’re using a 1.44" TFT
//tft.initR(INITR_144GREENTAB); // initialize a ST7735S chip, RED rcB tab
tft.setTextWrap(false); // tillad tekst at løbe ud over højre kant
tft.setRotation( 2 ); // for SORT PCB og RØD tft.setRotation(0) eller ej.
tft.fillScreen(ST7735_BLACK); // rydder skærmen
DDRD = DDRD | B00000000;
PORTD = PORTD | B11110000; // software pull-up fungerer, høj niveau-
// контролируемые объекты «не работают», во все 4 старших порта D записана «1», не идет счет.
for ( rc = 0; rc < 4; rc++)
{
tft.setCursor ( 3, rc * 10 + shift ); // viser nummer på kontrolobjekter
tft.print ( rc + 1 );
}
tft.setCursor (12, 0); // viser 3 linjer tekst
tft.println («DEVELOPERS & BUILD» ); // til at hylde os selv
tft.setCursor (24, 10); // eller en slesk copyright
tft.print («DEVELOPER M.M.»);
tft.setCursor (28, 20);
tft.print («BUILD-ER D.D.»);
//восстановление данных/////////////////////////////////////////////////////////
for ( z = 0; z < 1023; z += 16 ) { // Gennemgår alle EEPROM-celler
//и записывает в массив из 4-х переменных pump, по 4 байта каждый счетчик, т.к.
// переменная беззнаковая лонг. Счетчиков 4, одна запись всех 4-х занимает 16 байт.
EEPROM.get ( z, pump [0]); // på den måde, uden for-løkke, mindre størrelse
EEPROM.get ( z + 4, pump [1]);
EEPROM.get ( z + 8, pump [2]);
EEPROM.get ( z + 12, pump [3]);
// присвоение нового очередного значения суммы 4-x счётчиков
sumprim = (pump [0] + pump [1] + pump [2] + pump [3]);
// сравнивается новое значение суммы 4-х счетчиков в переменной sumprim с предыдущим значением в переменной
// sumsec и если предыдущая сумма меньше или равна новой сумме, присваивается новое большее или равное
// sumsec значение.
if ( sumsec <= sumprim ) {
sumsec = sumprim; //
//и присваивается переменной address текущее значение z, z- это адрес начала блока в 16 байт из 4-х значений
// счетчиков, записанных в одно и то-же время ( т.к. при опросе порта записываются одновременно все его 8 бит,
// в том числе наши нужные старшие 4 бита порта D).
address = z;
}
}
// еще раз обращение к памяти еепром по адресу начала блока в 16 байт из 4-х значений счетчиков записанных
// последними, т.е. значения перед выключением или перезагрузкой по причине зависания. Запись последних
// значений счетчиков в массив из 4-х переменных pump.
EEPROM.get ( address, pump [0]);
EEPROM.get ( address + 4, pump [1]);
EEPROM.get ( address + 8, pump [2]);
EEPROM.get ( address + 12, pump [3]);
address += 16; // øger adressen for at skrive næste blok uden at overskrive den seneste optagelse
// конец восстановления данных////////////////////////////////////////////////////////////////
attachInterrupt(0, count, RISING); // pin D2, aktiverer interruption, hver sekund kommer der
// импульсы от RTC DS3231 с выхода SQW
wdt_enable (WDTO_8S); // aktiverer watchdog timer, genstarter kontrolleren i tilfælde af hængning, tid,
// за которое надо подать команду сброса таймера wdt_reset( и избежать перезагрузки при нормальной работе- 8 сек.
// для тестов не рекомендуется устанавливать значение менее 8 сек.В данном случае сброс таймера происходит в пре-
// рывании, а оно каждую секунду.
}
void loop() {
// пустой цикл, здесь будет контроль за неполнофазным режимом работы эл.двигателя
}
void count() {
tft.setTextColor(ST7735_WHITE); // sætter skriftfarven
t = rtc.getTime(); // læser tid
tft.setCursor ( 5, 120 ); // sætter cursor position
tft.fillRect ( 5, 120, 50, 7, ST7735_BLACK); // rydder output-området for tid
tft.print(rtc.getTimeStr()); // viser klokkeslætsdata
wdt_reset(); // nulstiller watchdog timeren hver cyklus, d.v.s. hvert sekund
for (rc = 0; rc < 4; rc ++) // start af loop til at kontrollere indgangens status
// битов порта предыдущему считанному состоянию битов порта D
{
pinState = (PIND >> 4) & ( b << rc );
if (pumrcounter [rc] != pinState) { // og hvis det ikke stemmer overens, så
pumrcounter [rc] = pinState; // tildeler den variable portbitstatus et nyt værdi 1/0
}
// индикация состояния объектов контроля цветом
// BLUE- это небольшой глюк имеющегося экрана ( или библиотеки? ), перепутаны RGB и BGR.
if (pinState == ( b << rc )) {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_BLUE); // for at tælle ved lavt niveau skift grøn til blå
} else {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_GREEN); // for at tælle ved lavt niveau skift blå til grøn
pump [rc] += 1; // tilføjer 1 sekund til driftstidstælleren
}
}
k ++;
if ( k == 36 ) {
k = 0;
tft.fillRect ( 30, shift, 97, 40, ST7735_BLACK ); // rydder output-området for driftstid
tft.fillRect ( 60, 120, 73, 7, ST7735_BLACK); // og datoen
tft.setCursor ( 60, 120 ); // sætter cursorens position
tft.print(rtc.getDateStr()); // viser datoen på LCD-skærmen
for (rc = 0; rc < 4; rc++) // viser målinger i heltal, tiendedel og
{
tft.setCursor ( 30, rc * 10 + shift ); // hundrededele af timer med et skift på skærmen nedad med 10 pixels
tft.println(pump [rc] / m);
}
// запись «сырых» значений наработки (в секундах)в EEPROM //////////////////////////////
for (rc = 0; rc < 4; rc++)
{
EEPROM.put(address, pump [rc]);
address += sizeof(float); // inkrementerer adressevariablen for skrivning
}
}
// отправляем данные по радиоканалу из data указывая сколько байт надо отправить.
if ((k == 6 ) || (k == 18 ) || (k == 30 )) {
unsigned long data;
radio.write(&start, sizeof(start));
for ( i = 0; i < 4; i++) {
data = pump [i];
radio.write( &data, sizeof(data));
}
}
}
Lidt bemærkninger til slut. Tælleren aktiveres ved lavt logisk niveau på indgange.
Pull-up modstande R2-R5 36 kΩ for variant med fotomodstande GL5516. I tilfælde af fototransistor-optokobler og relæ, sættes 4,7-5,1 kΩ. Arduino Nano v3.0 bootloader er blevet udskiftet med Arduino Uno ved hjælp af programmer TL866A for korrekt drift af watchdog timer. Fuse indstillingerne er ændret for drift ved spænding over 4,3 V. Den eksterne reset-kredsløb R6 C3 blev ikke brugt. I programmet er senderfrekvensen ikke i overensstemmelse med det ikke-licenserede bånd, båndet 2,4 MHz er begrænset til frekvenserne 2400,0—2483,5 MHz.
Senderens bånd E01-ML01DP05 ligger mellem 2400-2525 MHz. Bredde af én kanals bånd – 1 MHz, når hastigheden er indstillet til 'RF24_2MBPS', vil den angivne radio.setChannel(120) kanal og den næste blive optaget, d.v.s. båndet vil være 2 MHz.
Kilde: habr.com
