Sistema locale autonomo di raccolta dati

L'azienda ha acquistato le postazioni di monitoraggio NEKST-M, prodotte a livello nazionale da Next Technologies. Per garantire la visualizzazione del funzionamento delle unità di pompaggio,
allarmi antincendio e di sicurezza, presenza tensione agli avviatori, temperatura ambiente, livello acqua di emergenza. Il cuore di NEKST-M è ATMEGA 1280 e questo fatto è incoraggiante in termini di possibilità di creare il proprio kit per esigenze specifiche.

L'obiettivo era creare un sistema di spedizione locale completamente autonomo per esigenze specifiche nel più breve tempo possibile e ad un costo minimo. La base è un microcontrollore. Sviluppo, produzione, creati dallo staff stesso.

Il sistema deve funzionare senza dipendenza da reti cellulari, server, Internet e dal sistema di licenze per l'uso delle risorse in radiofrequenza, non utilizzare computer nel funzionamento del sistema di monitoraggio e controllo o, al massimo, utilizzare periodicamente computer portatili, senza accesso a oggetti per lungo tempo (6-9 mesi). La configurazione della rete ha una struttura radiale. I dati vengono raccolti in un determinato momento e quindi inviati per l'elaborazione tramite canali di comunicazione regolari o come copia cartacea.

Il sistema deve fornire:

  • monitorare il funzionamento delle unità di pompaggio
  • automazione tecnologica
  • protezione dalle conseguenze delle condizioni di emergenza
  • segnalazione di emergenza
  • calcolo del tempo di funzionamento
  • calcolo della quantità di elettricità consumata
  • controllo della temperatura delle apparecchiature
  • sicurezza e allarme antincendio
  • registrazione remota periodica delle informazioni
  • requisiti futuri sconosciuti

Condizioni di lavoro:

  • area di copertura 1 kmq.
  • visibilità diretta tra gli oggetti
  • temperatura da +50 a -50 C
  • umidità fino al 100%
  • depositi biologicamente attivi (muffe, batteri solfato-riduttori)
  • vibrazioni, non più, di macchine delle classi 1-2 secondo GOST ISO 10816-1-97
  • ambiente elettromagnetico - commutazione di motori elettrici con contattori KT 6053, apparecchiature di avviamento graduale RVS-DN, apparecchiature di controllo PID SIEMENS MICROMASTER, radiazione nella gamma ISM e GSM secondo i requisiti di questi dispositivi, saldatura ad arco manuale in loco
  • tensione di rete eccessiva, interruzioni brevi dell'alimentazione elettrica, sovratensioni dovute a fulmini, squilibrio di fase in caso di rottura di un filo della linea aerea nelle reti di distribuzione 6-10 kV.

Nonostante i requisiti così severi, l'implementazione è abbastanza semplice quando si risolve il problema passo dopo passo.

Tutto considerato, la scheda “Arduino Nano 3.0” è diventata il “cervello” del progetto. La scheda robotdyn è dotata di un controller ATMEGA 328, lo stabilizzatore di tensione da 3,3 V necessario per
corrente 800 mA e convertitore a CH340G UART-USB.

Innanzitutto sono nati i contatori delle ore di funzionamento, quelli più moderni. I contatori industriali utilizzati in precedenza e montati su PIC con un circuito di alimentazione senza trasformatore si sono guastati a causa di picchi di tensione entro un anno di funzionamento. Sono rimasti intatti solo quelli collegati tramite alimentatori da 5 V fatti in casa. Per velocizzare l'installazione e la versatilità di connessione, dai terminali dei dispositivi di commutazione viene prelevato un segnale sullo stato delle unità, ad es. registrazione della presenza della tensione 1° fase con alimentazione trifase da 380V. Per coordinarsi con il controller viene utilizzato un relè intermedio con avvolgimento da 220 V o un fotoaccoppiatore composto da un LED e una fotoresistenza GL5516 o un fotoaccoppiatore PC817. Tutte le opzioni sono state testate. Il LED è alimentato da una tensione raddrizzata con limitazione di corrente tramite due condensatori SVV22 predisposti per una tensione di 630V collegati in serie per sicurezza durante il test accidentale dei circuiti con megaohmmetro.
Lettura delle letture del tempo di funzionamento utilizzando lo schermo LCD ST7735S, trasmissione dei dati in tempo reale via radio utilizzando il modulo E01-ML01DP05 ad una frequenza di 2,4 MHz. Questo dispositivo contiene il chip nRF24L01+ e l'amplificatore di trasmissione/ricezione RFX2401C,
potenza in uscita fino a 100 mW. Antenne elicoidali progettate per la portata desiderata nel calcolatore online Luogo. La scelta del tipo di antenna è determinata dall'esclusione della ricezione delle singole onde riflesse dalle strutture metalliche circostanti. Le parti dell'antenna sono stampate su una stampante 3D. Lo stato attuale dei contatori è memorizzato nella EEPROM del controller stesso e viene ripristinato in caso di interruzione improvvisa dell'alimentazione. Gli intervalli di tempo per il conteggio sono forniti dal chip RTC DS3231 sotto forma di modulo con batteria di riserva. L'alimentatore utilizza 3 moduli, la sorgente di impulsi effettiva 220/5V HLK-PM01 600mA, un convertitore da 1-5V a 5V HW-553 и 03962A - controller batteria con schema protezione contro cortocircuito, scarica eccessiva e sovraccarico. Tutti i componenti sono stati acquistati sul sito Aliexpress.

Tagliere per il paneSistema locale autonomo di raccolta dati
Contatore a 4 canali. Sugli ingressi sono presenti filtri LC per la protezione dalle interferenze su una linea di comunicazione a doppino intrecciato. I dati sullo stato degli oggetti di controllo vengono letti costantemente una volta al secondo e visualizzati a colori sul display LCD. Le letture vengono aggiornate e registrate nella memoria non volatile ogni 1 secondi. 36 secondi sono 36/1 di ora, questo è il formato in cui vengono richiesti i dati. Ogni 100 secondi viene trasmessa l'informazione relativa al numero di secondi di funzionamento di ciascuna centralina. La memoria EEPROM ha un numero limitato di cicli di cancellazione della scrittura, secondo il produttore, 12 volte. L'opzione peggiore è quando almeno una cella viene costantemente aggiornata. Il volume del primo contatore è di 100000 byte, questo è un numero in formato lungo, 1 contatori, un totale di 4 byte è occupato da un record. La lunghezza della memoria del chip è di 4 byte; dopo 16 inserimenti di 1024 contatori, la registrazione ricomincerà. Nella libreria EEPROM il metodo EEPROM.put non scrive, se il valore della cella e l'informazione che si sta scrivendo coincidono non ci sarà alcun degrado delle celle. Di conseguenza, il tempo di funzionamento garantito della memoria sarà superiore a 64 anni. I tempi di lavoro possibili ma non garantiti possono essere molto più lunghi.

Schema elettricoSistema locale autonomo di raccolta dati
Programma nell'IDE di Arduino//12 byte (328%)

#includere // Libreria grafica principale
#includere // Libreria specifica dell'hardware
#includere
#includere
#includere
#includere
#includere
Radio RF24(9, 10); // oggetto radio per lavorare con la libreria RF24,
// e numeri pin nRF24L01+ (CE, CSN)
#includere
DS3231 rtc(SDA, SCL);
Tempo t;

//#definisce TFT_CS 10
#definisci TFT_CS 8
#define TFT_RST -1 // puoi anche collegarlo al reset di Arduino
// in tal caso, imposta questo pin #define su -1!
//#define TFT_DC 9 // DC=RS=A0 - opzioni di designazione per selezionare un comando o un registro dati.
#definisci TFT_DC 3

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

// Opzione 2: usa qualsiasi pin ma un po' più lentamente!
#define TFT_SCLK 13 // imposta questi pin come preferisci!
#define TFT_MOSI 11 // imposta questi pin come preferisci!
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
#includere

spostamento di byte = 52;
byte pinStato;
unsigned long pump[4];// array con valori del contatore di 4 secondi
galleggiante m = 3600.0;
indirizzo int senza segno = 0;
int rc;// variabile per i contatori
sumprim lungo senza segno = 0;
sumsec lungo senza segno = 0;
byte io = 0;
byte k = 34;
int senza segno z = 0;
byte b = B00000001;
byte contatore[4]; // array per memorizzare gli stati degli oggetti, 1 - off, 0 - on.
int inizio = 0; //

void setup () {

rtc.begin();
radio.begin(); // Avvia il lavoro nRF24L01+
radio.setChannel(120); // canale dati (da 0 a 127).
radio.setDataRate(RF24_250KBPS); // velocità di trasferimento 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); // Apre una pipe con un identificatore per il trasferimento dei dati

// Per impostare l'ora, decommentare le righe necessarie
//rtc.setDOW(1); // Giorno della settimana
//rtc.setTime(21, 20, 0); // Ora, nel formato 24 ore.
//rtc.setData(29, 10, 2018); // Data, 29 ottobre 2018

tft.initR(INITR_BLACKTAB); // inizializza un chip ST7735S, scheda nera
// Usa questo inizializzatore (rimozione del commento) se stai utilizzando un TFT da 1.44".
//tft.initR(INITR_144GREENTAB); // inizializza un chip ST7735S, scheda RCB ROSSA
tft.setTextWrap(falso); // Consenti al testo di fuoriuscire dal bordo destro
tft.setRotazione( 2 ); // per PCB NERO e ROSSO tft.setRotation(0) oppure no.
tft.fillScreen(ST7735_BLACK); // schermo pulito

DDRD = DDRD | B00000000;
PORTD = PORTD | B11110000; // il serraggio del software funziona, livello alto -
// gli oggetti controllati "non funzionano", "4" viene scritto su tutte e 1 le porte senior D, non avviene alcun conteggio.

for ( rc = 0; rc < 4; rc++)
{
tft.setCursor ( 3, rc * 10 + maiusc ); // visualizza i numeri di posizione degli oggetti di controllo
tft.print(rc + 1);
}

tft.setCursor(12, 0); // restituisce 3 righe di testo
tft.println("SVILUPPATORI E COSTRUZIONE"); // per lodare te stesso, i tuoi cari
tft.setCursor(24, 10); // o copyright malvagio
tft.print("SVILUPPATORE MM");
tft.setCursor(28, 20);
tft.print("BUILD-ER DD");

//recupero dati////////////////////////////////////////////// ///////////

for ( z = 0; z < 1023; z += 16 ) { // Scorre tutte le celle del settore
//e scrive su un array di 4 variabili della pompa, 4 byte per ciascun contatore, perché
// variabile lunga senza segno. Sono presenti 4 contatori, un record di tutti e 4 occupa 16 byte.
EEPROM.get(z, pompa[0]); // quindi, senza il ciclo for, meno volume
EEPROM.get(z+4, pompa[1]);
EEPROM.get(z+8, pompa[2]);
EEPROM.get(z+12, pompa[3]);

// assegna un nuovo valore successivo per la somma di 4 contatori
sumprim = (pompa [0] + pompa [1] + pompa [2] + pompa [3]);

// confronta il nuovo valore della somma di 4 contatori nella variabile sumprim con il valore precedente nella variabile
// sumsec e se la somma precedente è inferiore o uguale alla nuova somma, viene assegnata la nuova somma maggiore o uguale
// valore somma-sec.

se (sumsec <= sumprim) {
sommasec = sommarim; //

//e il valore corrente z viene assegnato alla variabile dell'indirizzo, z è l'indirizzo dell'inizio di un blocco di 16 byte di 4 valori
// contatori registrati contemporaneamente (poiché quando si interroga una porta, tutti gli 8 bit vengono scritti simultaneamente,
// inclusi i 4 bit necessari della porta D).
indirizzo = z;
}
}

//accedo nuovamente alla memoria eeprom all'indirizzo di inizio di un blocco di 16 byte di 4 contatori registrati
// ultimo, cioè valori prima dello spegnimento o del riavvio a causa del congelamento. Registrazione dell'ultima
// conta valori in un array di 4 variabili pump.

EEPROM.get(indirizzo, pompa[0]);
EEPROM.get(indirizzo + 4, pompa[1]);
EEPROM.get(indirizzo + 8, pompa[2]);
EEPROM.get(indirizzo + 12, pompa[3]);

indirizzo += 16; //incrementa l'indirizzo per scrivere il blocco successivo senza sovrascrivere i dati dell'ultimo record

//fine del recupero dei dati/////////////////////////////////////////// / //////////////////

attachInterrupt(0, conteggio, RISING); // pin D2, abilita gli interrupt, arrivano ogni secondo
// impulsi dall'RTC DS3231 dall'uscita SQW

wdt_abilita(WDTO_8S); // avvia il timer del watchdog, riavvia il controller in caso di blocco, ora,
// per il quale è necessario eseguire il comando di ripristino del timer wdt_reset( ed evitare il riavvio durante il normale funzionamento - 8 sec.
// per i test è sconsigliato impostare un valore inferiore a 8 secondi, in questo caso è preferibile resettare il timer
// sussulta, e succede ogni secondo.

}

void loop () {
// ciclo a vuoto, qui ci sarà il controllo sul funzionamento in fase aperta del motore elettrico
}

conteggio dei vuoti() {

tft.setTextColor(ST7735_WHITE); // imposta il colore del carattere
t = rtc.getTime(); // Tempo per leggere
tft.setCursor(5, 120); // imposta la posizione del cursore
tft.fillRect(5, 120, 50, 7, ST7735_BLACK); // cancella l'area di output del tempo
tft.print(rtc.getTimeStr()); // letture dell'orologio in uscita

wdt_reset(); // reimposta il watchdog a ogni ciclo, ovvero al secondo

for (rc = 0; rc < 4; rc ++) // inizio del ciclo per la verifica della conformità dello stato di ingresso
// porta i bit allo stato di lettura precedente dei bit della porta D
{
pinState = (PIND >> 4) & ( b << rc );

if (pumrcounter [rc] != pinState) { // e se non corrisponde, allora
contatorepumr[rc] = pinState; // assegna alla variabile di stato del bit della porta un nuovo valore 1/0
}
// indicazione dello stato degli oggetti di controllo del colore
// BLU è un piccolo problema tecnico dello schermo esistente (o della libreria?), RGB e BGR sono confusi.
if (pinState == ( b << rc )) {
tft.fillRect(15, ((rc * 10 + spostamento)), 7, 7, ST7735_BLUE); // per il conteggio di basso livello cambia il VERDE in BLU
} Else {
tft.fillRect(15, ((rc * 10 + spostamento)), 7, 7, ST7735_GREEN); // per il conteggio di basso livello cambia il BLU in VERDE
pompa [rc] += 1; // aggiunge 1 secondo al contatore del tempo di funzionamento
}
}

k++;
se (k == 36) {
k = 0;

tft.fillRect(30, spostamento, 97, 40, ST7735_BLACK); // cancella l'area di visualizzazione del tempo di funzionamento
tft.fillRect(60, 120, 73, 7, ST7735_BLACK); // e date

tft.setCursor(60, 120); // imposta la posizione del cursore
tft.print(rtc.getDateStr()); // visualizza la data sullo schermo LCD

for (rc = 0; rc < 4; rc ++) //emette le ore di funzionamento in interi, decimi e
{
tft.setCursor ( 30, rc * 10 + shift ); // centesimi di ora con uno spostamento dello schermo verso il basso di 10 pixel
tft.println(pompa[rc]/m);
}

// scrittura dei valori “grezzi” delle ore di funzionamento (in secondi) su EEPROM //////////////////////////////

per (rc = 0; rc < 4; rc++)
{
EEPROM.put(indirizzo, pompa [rc]);
indirizzo += dimensione(float); // incrementa la variabile dell'indirizzo di scrittura
}
}

// invia dati sul canale radio dai dati che indicano quanti byte devono essere inviati.
if ((k == 6 ) || (k == 18 ) || (k == 30 )) {

dati lunghi non firmati;

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

per (i = 0; i < 4; i++) {
dati = pompa [i];
radio.write( &data, sizeof( data));
}
}
}

Alcune note alla fine. Il conteggio avviene a livello logico basso sugli ingressi.

Le resistenze pull-up R2-R5 sono 36 kOhm per l'opzione con fotoresistenze GL5516. Nel caso di un fotoaccoppiatore e relè a fototransistor, impostare su 4,7-5,1 kOhm. Il bootloader Arduino Nano v3.0 è stato sostituito con Arduino Uno utilizzando il programmatore TL866A per il corretto funzionamento del timer watchdog. I fusibili sono corretti per funzionare a tensioni superiori a 4,3 V. Il circuito di ripristino esterno R6 C3 non è stato utilizzato. Nel programma di esempio la frequenza del trasmettitore non corrisponde alla gamma senza licenza; la gamma 2,4 MHz è limitata alle frequenze 2400.0-2483.5 MHz.

La portata del trasmettitore E01-ML01DP05 è 2400-2525 MHz. La larghezza di banda di un canale è 1 MHz, quando si imposta la velocità come "RF24_2MBPS" il canale radio.setChannel(120) specificato e quello successivo saranno occupati, ad es. la banda sarà di 2 MHz.

Fonte: habr.com

Aggiungi un commento