Presso l'azienda sono stati acquistati i posti di monitoraggio NEXТ-M di produzione nazionale "Next Technologies". Per garantire la visualizzazione del funzionamento delle unità di pompaggio,
del sistema di allerta antincendio e di sicurezza, della presenza di tensione sui relè, della temperatura negli ambienti, del livello d'emergenza dell'acqua. Il cuore del NEXТ-M è l'ATMEGA 1280 e questo fatto ha stimolato la possibilità di creare un proprio kit per esigenze specifiche.
È stato assegnato il compito di creare, in tempi minimi e con costi ridotti, un sistema completamente autonomo di supervisione locale per necessità specifiche. La base è un microcontrollore. Lo sviluppo, la produzione, vengono effettuati dalle stesse forze del personale.
Il sistema deve funzionare senza dipendenza dalle reti cellulari, server, da internet e da un sistema autorizzativo per l'uso delle risorse radiofrequenziali, senza utilizzare computer nei sistemi di controllo e gestione o al massimo un uso sporadico di laptop, senza accesso agli oggetti per un lungo periodo (6-9 mesi). La configurazione della rete ha una struttura radiale. I dati vengono raccolti in un unico punto e poi inviati per l'elaborazione tramite normali canali di comunicazione o in forma di copia cartacea.
Il sistema deve garantire:
- il controllo del funzionamento delle installazioni idrauliche
- l'automazione tecnologica
- la protezione dagli effetti delle modalità di emergenza
- l'allerta riguardo a situazioni di emergenza
- il calcolo del tempo di operatività
- il conteggio del volume di energia elettrica consumata
- il controllo della temperatura delle attrezzature
- il sistema di allerta antincendio e di sicurezza
- l'acquisizione periodica delle informazioni a distanza
- richieste sconosciute in futuro
Condizioni di lavoro:
- area di copertura di 1 km².
- visibilità diretta tra gli oggetti
- temperatura da +50 a -50 °C
- umidità fino al 100%
- depositi biologicamente attivi (muffa, batteri riduttori di solfato)
- vibrazioni, non oltre, macchine di classe 1-2 secondo GOST ISO 10816-1-97
- situazione elettromagnetica- commutazione dei motori elettrici tramite relè KТ 6053, apparecchiature di avviamento morbido RVS-DN, apparecchiature di regolazione PID SIEMENS MICROMASTER, emissioni nei range ISM e GSM secondo le esigenze di tali apparecchi, saldatura ad arco manuale in loco
- elevata tensione di rete, interruzioni temporanee dell'alimentazione elettrica, sovratensioni da fulmini, squilibrio di fase in caso di rottura del cavo di rete nelle reti di distribuzione 6-10 kV.
Nonostante tali rigorose esigenze, la realizzazione è abbastanza semplice se si affronta il compito per fasi.
Tenendo conto di tutto, la 'mente' del progettato è diventata la scheda 'Arduino Nano 3.0'. La scheda di 'Robotdyn' ha un microcontrollore ATMEGA 328, un regolatore di tensione necessario di 3,3V su
corrente di 800 mA e un convertitore su CH340G UART-USB.
In primo luogo, sono stati creati contatori di utilizzo come i più rilevanti. I contatori industriali precedentemente utilizzati, basati su PIC con schema di alimentazione senza trasformatore, sono andati in avaria a causa di picchi di tensione durante un anno di funzionamento. Sono rimasti intatti solo quelli collegati tramite alimentatori artigianali a 5V. Per accelerare il montaggio e rendere l'installazione universale, il segnale sullo stato degli apparecchi è prelevato dai morsetti degli apparati di commutazione, ovvero la registrazione della presenza della 1ª fase di tensione in un'alimentazione trifase a 380V. Per l'intesa con il microcontrollore si utilizza un relè intermedio con bobina a 220V o un optoaccoppiatore composto da un LED e un fotoresistore GL5516 o un optoaccoppiatore PC817. Tutte le varianti sono state testate in funzionalità. Il LED è alimentato da tensione rettificata con limitazione della corrente tramite due condensatori CBB22 progettati per una tensione di 630V, collegati in serie per la sicurezza durante eventuali controlli delle linee con un megometro.
Lettura dei tempi di funzionamento tramite schermo LCD ST7735S, trasmissione dei dati in tempo reale tramite modulo E01-ML01DP05 a una frequenza di 2,4 MHz. Questo dispositivo contiene un chip nRF24L01+ e un amplificatore di ricezione-trasmissione RFX2401C,
con potenza di uscita fino a 100 mW. Le antenne sono spiraliformi, progettate per la gamma necessaria nel calcolatore online. . La scelta del tipo di antenne è determinata dall'esclusione della ricezione delle onde riflesse una sola volta dalle strutture metalliche circostanti. I dettagli delle antenne sono stampati in 3D. Lo stato attuale dei contatori viene memorizzato nell'EEPROM del controller stesso e, in caso di improvvisa interruzione dell'alimentazione, viene ripristinato. Gli intervalli di tempo per il conteggio sono forniti dal chipset RTC DS3231 in forma di modulo con batteria di alimentazione di riserva. Nell'alimentatore sono utilizzati 3 moduli: il proprio alimentatore a impulsi 220/5V HLK-PM01 600mA, un convertitore da 1-5V a 5V e — controller della batteria che ha di protezione da cortocircuiti, scarica e sovraccarica. Tutti i componenti sono stati acquistati su Aliexpress.
Breadboard
Contatore a 4 canali. Sono stati installati filtri LC sugli ingressi per proteggere dalle interferenze lungo la linea di comunicazione a coppie ritorte. I dati sullo stato degli oggetti monitorati vengono letti continuamente ogni secondo e visualizzati a colori su un display LCD. L'aggiornamento delle letture e la registrazione nella memoria non volatile avviene ogni 36 secondi. 36 secondi corrispondono a 1/100 di ora, questo è il formato richiesto per i dati. Ogni 12 secondi vengono trasferite informazioni sul numero di secondi di funzionamento per ciascun dispositivo di monitoraggio. La memoria EEPROM ha un numero limitato di cicli di scrittura-cancellazione, secondo il produttore, 100000 volte. Il peggiore dei casi è quando viene continuamente aggiornato almeno un celle. La dimensione di un contatore è di 4 byte, che è un numero di formato long, 4 contatori in totale occupano 16 byte per una registrazione. La lunghezza della memoria del chip è di 1024 byte e, dopo 64 scritture dei 4 contatori, la registrazione ricomincerà dall'inizio. Nella libreria EEPROM, il metodo EEPROM.put non esegue la scrittura se il valore della cella e le informazioni da scrivere coincidono, non ci sarà degrado delle celle. Alla fine, il tempo garantito di funzionamento della memoria sarà superiore a 7 anni. Il tempo di funzionamento possibile, ma non garantito, può essere molto più lungo.
Schema principale
Programma in 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); // oggetto radio per lavorare con la libreria RF24,
// и номера выводов 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 con 4 valori dei contatori di secondi
float m = 3600.0;
unsigned int address = 0;
int rc; // variabile per i contatori
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 per memorizzare gli stati degli oggetti, 1- spento, 0- acceso.
int start = 0; //
void setup() {
rtc.begin();
radio.begin(); // Iniziamo il funzionamento di nRF24L01+
radio.setChannel(120); // canale di trasmissione dei dati (da 0 a 127).
radio.setDataRate (RF24_250KBPS); // velocità di trasmissione dei dati (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS).
radio.setPALevel (RF24_PA_MAX); // potenza del trasmettitore (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm,
// RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openWritingPipe (0xAABBCCDD11LL); // Apriamo il tubo con l'identificativo per la trasmissione dei dati
// Для установки времени- раскомментировать нужные строки
//rtc.setDOW(1); // День недели
//rtc.setTime(21, 20, 0); // Время, в формате 24 часа.
//rtc.setDate(29, 10, 2018); // Дата, 29 октября 2018г.
tft.initR(INITR_BLACKTAB); // inizializza un chip ST7735S, linguetta nera
// 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); // Consenti al testo di uscire dal bordo destro
tft.setRotation( 2 ); // per PCB NERO e ROSSO tft.setRotation(0) o meno.
tft.fillScreen(ST7735_BLACK); // pulizia dello schermo
DDRD = DDRD | B00000000;
PORTD = PORTD | B11110000;// il pull-up software funziona, livello alto-
// контролируемые объекты «не работают», во все 4 старших порта D записана «1», не идет счет.
for ( rc = 0; rc < 4; rc++)
{
tft.setCursor ( 3, rc * 10 + shift ); // visualizzazione dei numeri delle posizioni degli oggetti di controllo
tft.print ( rc + 1 );
}
tft.setCursor (12, 0); // visualizzazione di 3 righe di testo
tft.println ("DEVELOPERS & BUILD"); // per esaltare noi stessi
tft.setCursor (24, 10); // o un oscuro copyright
tft.print ("DEVELOPER M.M.");
tft.setCursor (28, 20);
tft.print ("BUILD-ER D.D.");
//восстановление данных/////////////////////////////////////////////////////////
for ( z = 0; z < 1023; z += 16 ) { // Scorre tutte le celle della EEPROM
//и записывает в массив из 4-х переменных pump, по 4 байта каждый счетчик, т.к.
// переменная беззнаковая лонг. Счетчиков 4, одна запись всех 4-х занимает 16 байт.
EEPROM.get ( z, pump [0]); // così, senza un ciclo for, meno volume
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; // aumento dell'indirizzo per la registrazione del prossimo blocco senza sovrascrivere i dati dell'ultima registrazione
// конец восстановления данных////////////////////////////////////////////////////////////////
attachInterrupt(0, count, RISING); // pin D2, abilitazione dell'interruzione, ogni secondo arrivano
// импульсы от RTC DS3231 с выхода SQW
wdt_enable (WDTO_8S); // avvio del timer watchdog, riavvia il controller in caso di blocco, tempo,
// за которое надо подать команду сброса таймера wdt_reset( и избежать перезагрузки при нормальной работе- 8 сек.
// для тестов не рекомендуется устанавливать значение менее 8 сек.В данном случае сброс таймера происходит в пре-
// рывании, а оно каждую секунду.
}
void loop() {
// пустой цикл, здесь будет контроль за неполнофазным режимом работы эл.двигателя
}
void count() {
tft.setTextColor(ST7735_WHITE); // impostazione del colore del font
t = rtc.getTime(); // lettura dell'ora
tft.setCursor ( 5, 120 ); // impostazione della posizione del cursore
tft.fillRect ( 5, 120, 50, 7, ST7735_BLACK); // pulizia dell'area di output del tempo
tft.print(rtc.getTimeStr()); // visualizzazione dei dati dell'orologio
wdt_reset(); // reset del timer watchdog ogni ciclo, ovvero ogni secondo
for (rc = 0; rc < 4; rc++) // inizio del ciclo di controllo della corrispondenza dello stato degli ingressi
// битов порта предыдущему считанному состоянию битов порта D
{
pinState = (PIND >> 4) & ( b << rc );
if (pumrcounter [rc] != pinState) { // e se non corrisponde, allora
pumrcounter [rc] = pinState; // assegnazione alla variabile dello stato del bit del porto del nuovo valore 1/0
}
// индикация состояния объектов контроля цветом
// BLUE- это небольшой глюк имеющегося экрана ( или библиотеки? ), перепутаны RGB и BGR.
if (pinState == ( b << rc )) {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_BLUE); // per il conteggio a livello basso cambiare GREEN in BLUE
} else {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_GREEN); // per il conteggio a livello basso cambiare BLUE in GREEN
pump [rc] += 1; // aggiungiamo al contatore del tempo di lavoro 1 secondo
}
}
k ++;
if ( k == 36 ) {
k = 0;
tft.fillRect ( 30, shift, 97, 40, ST7735_BLACK ); // pulizia dell'area di output del tempo di funzionamento
tft.fillRect ( 60, 120, 73, 7, ST7735_BLACK); // e date
tft.setCursor ( 60, 120 ); // impostazione della posizione del cursore
tft.print(rtc.getDateStr()); // visualizzazione della data sullo schermo LCD
for (rc = 0; rc < 4; rc ++) // visualizzazione dei valori di funzionamento in interi, decimali e
{
tft.setCursor ( 30, rc * 10 + shift ); // centesimi di ora con uno spostamento dello schermo di 10 pixel verso il basso
tft.println(pump [rc] / m);
}
// запись «сырых» значений наработки (в секундах)в EEPROM //////////////////////////////
for (rc = 0; rc < 4; rc ++)
{
EEPROM.put(address, pump [rc]);
address += sizeof(float); // incremento della variabile dell'indirizzo di scrittura
}
}
// отправляем данные по радиоканалу из 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));
}
}
}
Piccole osservazioni alla fine. Il conteggio avviene a un basso livello logico sugli ingressi.
Le resistenze di pull-up R2-R5 sono 36 kOhm per la variante con fotoresistenze GL5516. Nel caso di un optoaccoppiatore a fototransistor e relè, utilizzare 4,7-5,1 kOhm. Il bootloader Arduino Nano v3.0 è stato sostituito con Arduino Uno tramite programmatore TL866A per un corretto funzionamento del timer watchdog. I fuse sono stati corretti per il funzionamento a tensioni superiori a 4,3 V. Il circuito di reset esterno R6 C3 non è stato utilizzato. Nell'esempio di programma, la frequenza del trasmettitore non corrisponde alla banda non licenziata, la banda di 2,4 GHz è limitata dalle frequenze 2400.0—2483.5 MHz.
L'intervallo del trasmettitore E01-ML01DP05 è compreso tra 2400-2525 MHz. La larghezza di banda di un canale è di 1 MHz, impostando la velocità su "RF24_2MBPS" verrà occupato il canale radio.setChannel(120) specificato e quello successivo, quindi la banda sarà di 2 MHz.
Fonte: habr.com
