Système local autonome de collecte de données

La société a acheté des postes de surveillance NEKST-M, produits localement par Next Technologies. Pour assurer la visualisation du fonctionnement des unités de pompage,
alarmes incendie et sécurité, présence de tension aux démarreurs, température ambiante, niveau d'eau de secours. Le cœur du NEKST-M est l'ATMEGA 1280 et ce fait est encourageant en termes de possibilité de créer votre propre kit pour des besoins spécifiques.

L'objectif était de créer un système de répartition local entièrement autonome pour des besoins spécifiques dans les plus brefs délais et à un coût minimal. La base est un microcontrôleur. Développement, fabrication, créés par le personnel lui-même.

Le système doit fonctionner sans dépendre des réseaux cellulaires, des serveurs, d'Internet et du système de licence pour l'utilisation des ressources radiofréquences, ne pas utiliser d'ordinateurs pour le fonctionnement du système de surveillance et de contrôle ou, tout au plus, utiliser périodiquement des ordinateurs portables, sans accès à objets pendant une longue période (6-9 mois). La configuration réseau a une structure radiale. Les données sont collectées à un moment donné, puis envoyées pour traitement via les canaux de communication habituels ou sous forme papier.

Le système doit fournir :

  • surveiller le fonctionnement des unités de pompage
  • automatisation technologique
  • protection contre les conséquences des conditions d'urgence
  • signalisation d'urgence
  • calcul du temps de fonctionnement
  • calculer la quantité d'électricité consommée
  • contrôle de la température des équipements
  • sécurité et alarme incendie
  • enregistrement périodique à distance des informations
  • besoins futurs inconnus

Conditions de travail:

  • zone de couverture 1 km².
  • visibilité directe entre les objets
  • température de +50 à -50 C
  • humidité jusqu'à 100%
  • dépôts biologiquement actifs (moisissures, bactéries sulfato-réductrices)
  • vibration, pas plus, des machines des classes 1-2 selon GOST ISO 10816-1-97
  • environnement électromagnétique - commutation de moteurs électriques avec contacteurs KT 6053, équipement de démarrage progressif RVS-DN, équipement de contrôle SIEMENS MICROMASTER PID, rayonnement dans la gamme ISM et GSM selon les exigences de ces appareils, soudage manuel à l'arc sur site
  • tension de réseau excessive, coupures d'alimentation de courte durée, surtensions dues à la foudre, déséquilibre de phase lors de la rupture d'un fil de ligne aérienne dans les réseaux de distribution 6-10 kV.

Malgré des exigences aussi strictes, la mise en œuvre est assez simple lorsqu’on résout le problème étape par étape.

Tout bien considéré, la carte « Arduino Nano 3.0 » est devenue le « cerveau » du plan. La carte robotdyn dispose d'un contrôleur ATMEGA 328, le stabilisateur de tension 3,3 V nécessaire pour
courant 800 mA et convertisseur vers CH340G UART-USB.

Tout d'abord, les compteurs d'heures de fonctionnement ont été créés comme étant les plus récents. Les compteurs industriels précédemment utilisés, assemblés sur des PIC avec un circuit d'alimentation sans transformateur, sont tombés en panne en raison de surtensions au cours de l'année de fonctionnement. Seuls ceux connectés à l’aide d’alimentations 5V maison sont restés intacts. Pour accélérer l'installation et la polyvalence de la connexion, un signal sur l'état des unités est extrait des bornes des appareils de commutation, c'est-à-dire enregistrement de la présence de la tension 1ère phase avec une alimentation triphasée de 380V. Pour la coordination avec le contrôleur, un relais intermédiaire avec un enroulement 220V ou un optocoupleur composé d'une LED et d'une photorésistance GL5516 ou un optocoupleur PC817 est utilisé. Toutes les options ont été testées. La LED est alimentée par une tension redressée avec limitation de courant à l'aide de deux condensateurs SVV22 conçus pour une tension de 630 V connectés en série pour plus de sécurité lors de tests accidentels des circuits avec un mégohmmètre.
Lecture des relevés de temps de fonctionnement à l'aide de l'écran LCD ST7735S, transmission de données en temps réel par radio à l'aide du module E01-ML01DP05 à une fréquence de 2,4 MHz. Cet appareil contient la puce nRF24L01+ et l'amplificateur d'émission/réception RFX2401C,
puissance de sortie jusqu'à 100 mW. Antennes hélicoïdales conçues pour la portée souhaitée dans le calculateur en ligne сайта. Le choix du type d'antenne est déterminé par l'exclusion de la réception d'ondes uniquement réfléchies par les structures métalliques environnantes. Les pièces de l'antenne sont imprimées sur une imprimante 3D. L'état actuel des compteurs est stocké dans l'EEPROM du contrôleur lui-même et est restauré en cas de panne de courant inattendue. Les intervalles de temps de comptage sont fournis par la puce RTC DS3231 sous la forme d'un module avec batterie de secours. L'alimentation utilise 3 modules, la source d'impulsions réelle 220/5V HLK-PM01 600mA, un convertisseur de 1-5V à 5V HW-553 и 03962A - contrôleur de batterie avec motif protection contre les courts-circuits, les décharges excessives et les surcharges. Tous les composants ont été achetés sur le site Aliexpress.

Planche à painSystème local autonome de collecte de données
Compteur 4 canaux. Il y a des filtres LC aux entrées pour protéger contre les interférences sur une ligne de communication à paire torsadée. Les données sur l'état des objets de contrôle sont lues en permanence une fois par seconde et affichées en couleur sur l'écran LCD. Les lectures sont mises à jour et enregistrées dans une mémoire non volatile toutes les 1 secondes. 36 secondes correspondent à 36/1 d'heure, c'est le format dans lequel les données sont requises. Toutes les 100 secondes. des informations sont transmises sur le nombre de secondes de fonctionnement pour chaque unité de commande. La mémoire EEPROM a un nombre limité de cycles d'écriture-effacement, selon le fabricant, 12 100000 fois. La pire option est lorsqu'au moins une cellule est constamment mise à jour. Le volume du 1er compteur est de 4 octets, c'est un numéro au format long, 4 compteurs, un total de 16 octets est occupé par un enregistrement. La longueur de la mémoire de la puce est de 1024 octets ; après 64 entrées de 4 compteurs, l'enregistrement recommencera. Dans la bibliothèque EEPROM, la méthode EEPROM.put n'écrit pas ; si la valeur de la cellule et l'information en cours d'écriture correspondent, il n'y aura pas de dégradation des cellules. De ce fait, la durée de fonctionnement garantie de la mémoire sera supérieure à 7 ans. Le temps de travail possible mais non garanti peut être beaucoup plus long.

SchémaSystème local autonome de collecte de données
Programme dans l'IDE Arduino//12 328 octets (38 %)

#inclure // Bibliothèque graphique principale
#include // Bibliothèque spécifique au matériel
#comprendre
#include
#comprendre
#inclure
#inclure
Radio RF24 (9, 10) ; // objet radio pour travailler avec la bibliothèque RF24,
// et numéros de broches nRF24L01+ (CE, CSN)
#comprendre
DS3231 rtc(SDA, SCL);
Temps t ;

//#définir TFT_CS 10
#définir TFT_CS 8
#define TFT_RST -1 // vous pouvez également le connecter à la réinitialisation Arduino
// auquel cas, définissez cette broche #define sur -1 !
//#define TFT_DC 9 // DC=RS=A0 - options de désignation pour sélectionner une commande ou un registre de données.
#définir TFT_DC 3

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

// Option 2 : utilisez n'importe quelle épingle mais un peu plus lentement !
#define TFT_SCLK 13 // définissez-les comme les broches de votre choix !
#define TFT_MOSI 11 // définissez-les sur les broches de votre choix !
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST) ;
#inclure

décalage d'octet = 52 ;
octet pinState ;
pompe longue non signée [4] ; // tableau avec des valeurs de compteur de 4 secondes
flotteur m = 3600.0 ;
adresse entière non signée = 0 ;
int rc;// variable pour les compteurs
résumé long non signé = 0 ;
somme longue non signée = 0 ;
octet je = 0 ;
octet k = 34 ;
entier non signé z = 0 ;
octet b = B00000001 ;
compteur d'octets [4] ; // tableau pour stocker les états des objets, 1 - off, 0 - on.
int début = 0 ; //

void setup() {

rtc.begin();
radio.begin(); // Lancement du travail nRF24L01+
radio.setChannel(120); // canal de données (de 0 à 127).
radio.setDataRate(RF24_250KBPS); // taux de transfert de données (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS).
radio.setPALevel(RF24_PA_MAX); // puissance de l'émetteur (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm,
// RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openWritingPipe(0xAABBCCDD11LL); // Ouvrir un tube avec un identifiant pour le transfert de données

// Pour régler l'heure, décommentez les lignes nécessaires
//rtc.setDOW(1); // Jour de la semaine
//rtc.setTime(21, 20, 0); // Heure, au format 24 heures.
//rtc.setDate(29, 10, 2018); // Date, 29 octobre 2018

tft.initR(INITR_BLACKTAB); // initialise une puce ST7735S, languette noire
// Utilisez cet initialiseur (décommentez) si vous utilisez un TFT 1.44"
//tft.initR(INITR_144GREENTAB); // initialise une puce ST7735S, onglet RED rcB
tft.setTextWrap(false); // Autorise le texte à s'étendre sur le bord droit
tft.setRotation( 2 ); // pour PCB NOIR et ROUGE tft.setRotation(0) ou non.
tft.fillScreen(ST7735_BLACK); // écran propre

DDRD = DDRD | B00000000 ;
PORTD = PORTD | B11110000 ; // le serrage logiciel fonctionne, niveau élevé -
// les objets contrôlés « ne fonctionnent pas », « 4 » est écrit sur les 1 ports senior D, aucun comptage n'a lieu.

pour ( rc = 0; rc < 4; rc++)
{
tft.setCursor ( 3, rc * 10 + maj ); // affichage des numéros de position des objets de contrôle
tft.print(rc + 1);
}

tft.setCursor(12, 0); // affiche 3 lignes de texte
tft.println("DEVELOPPEURS ET CONSTRUCTION"); // pour se féliciter de ses proches
tft.setCursor(24, 10); // ou le mal du droit d'auteur
tft.print("DEVELOPPEUR M.M.");
tft.setCursor(28, 20);
tft.print("BUILD-ER D.D.");

//récupération de données////////////////////////////////////////////// ///////////

for ( z = 0; z < 1023; z += 16 ) { // Itère dans toutes les cellules de l'industrie
// et écrit dans un tableau de 4 variables de pompe, 4 octets pour chaque compteur, car
// variable longue non signée. Il y a 4 compteurs, un enregistrement des 4 prend 16 octets.
EEPROM.get(z, pompe[0]); // donc, sans la boucle for, moins de volume
EEPROM.get(z+4, pompe[1]);
EEPROM.get(z+8, pompe[2]);
EEPROM.get(z+12, pompe[3]);

// attribution d'une nouvelle valeur suivante pour la somme de 4 compteurs
sumprim = (pompe [0] + pompe [1] + pompe [2] + pompe [3]) ;

// compare la nouvelle valeur de la somme de 4 compteurs dans la variable sumprim avec la valeur précédente dans la variable
// sumsec et si la somme précédente est inférieure ou égale à la nouvelle somme, la nouvelle supérieure ou égale est attribuée
// valeur sumsec.

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

//et la valeur actuelle z est affectée à la variable d'adresse, z est l'adresse du début d'un bloc de 16 octets de 4 valeurs
// compteurs enregistrés en même temps (puisque lors de l'interrogation d'un port, les 8 bits de celui-ci sont écrits simultanément,
// y compris nos 4 bits élevés nécessaires du port D).
adresse = z ;
}
}

// accès à nouveau à la mémoire eeprom à l'adresse du début d'un bloc de 16 octets de 4 valeurs de compteur enregistrées
// dernier, c'est-à-dire valeurs avant d'arrêter ou de redémarrer en raison d'un gel. Enregistrer le dernier
// compteur les valeurs dans un tableau de 4 variables pompe.

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

adresse += 16 ; //augmenter l'adresse pour écrire le bloc suivant sans écraser les données du dernier enregistrement

//fin de récupération des données////////////////////////////////////////// //////////////////

attachInterrupt(0, nombre, RISING); // broche D2, active les interruptions, arrive chaque seconde
// impulsions du RTC DS3231 de la sortie SQW

wdt_enable(WDTO_8S); // démarre le minuteur de surveillance, redémarre le contrôleur en cas de gel, heure,
// pour lequel vous devez émettre la commande de réinitialisation du timer wdt_reset( et éviter de redémarrer pendant le fonctionnement normal - 8 sec.
// pour les tests, il n'est pas recommandé de définir la valeur à moins de 8 secondes. Dans ce cas, le timer est réinitialisé de préférence
// saccades, et cela arrive toutes les secondes.

}

boucle vide () {
// cycle vide, ici il y aura un contrôle sur le fonctionnement en phase ouverte du moteur électrique
}

nombre vide() {

tft.setTextColor(ST7735_WHITE); // définit la couleur de la police
t = rtc.getTime(); // Temps de lecture
tft.setCursor(5, 120); // définition de la position du curseur
tft.fillRect(5, 120, 50, 7, ST7735_BLACK); // efface la zone de sortie temporelle
tft.print(rtc.getTimeStr()); // lectures d'horloge de sortie

wdt_reset(); // réinitialise le chien de garde à chaque cycle, c'est-à-dire une seconde

for (rc = 0; rc < 4; rc ++) // début du cycle de vérification de la conformité de l'état d'entrée
// Portez les bits vers l'état de lecture précédent des bits du port D
{
pinState = (PIND >> 4) & ( b << rc );

if (pumrcounter [rc] != pinState) { // et si ne correspond pas, alors
pumrcounter[rc] = pinState; // assignation à la variable d'état du bit de port une nouvelle valeur 1/0
}
// indication de l'état des objets de contrôle des couleurs
// BLEU est un petit bug de l'écran existant (ou de la bibliothèque ?), RVB et BGR sont mélangés.
si (pinState == ( b << rc )) {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_BLUE); // pour un comptage de bas niveau, changez le VERT en BLEU
} Else {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_GREEN); // pour un comptage de bas niveau, changez le BLEU en VERT
pompe [rc] += 1 ; // ajoute 1 seconde au compteur de temps de fonctionnement
}
}

k++;
si (k == 36) {
k est 0;

tft.fillRect(30, décalage, 97, 40, ST7735_BLACK); // effacement de la zone d'affichage du temps de fonctionnement
tft.fillRect(60, 120, 73, 7, ST7735_BLACK); // et dates

tft.setCursor(60, 120); // définition de la position du curseur
tft.print(rtc.getDateStr()); // affiche la date sur l'écran LCD

pour (rc = 0; rc < 4; rc ++) //sortie des heures de fonctionnement en entier, dixièmes et
{
tft.setCursor ( 30, rc * 10 + shift ); // centièmes d'heure avec un décalage d'écran vers le bas de 10 pixels
tft.println(pompe [rc] / m);
}

// écriture des valeurs d'heures de fonctionnement « brutes » (en secondes) dans l'EEPROM /////////////////////////////

pour (rc = 0; rc < 4; rc++)
{
EEPROM.put(adresse, pompe [rc]);
adresse += sizeof(float); // incrémente la variable d'adresse d'écriture
}
}

// envoie des données sur le canal radio à partir de données indiquant le nombre d'octets à envoyer.
si ((k == 6 ) || (k == 18 ) || (k == 30 )) {

données longues non signées ;

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

pour (je = 0; je < 4; je++) {
données = pompe [i] ;
radio.write( &data, sizeof( data));
}
}
}

Quelques notes à la fin. Le comptage s'effectue à un niveau logique bas au niveau des entrées.

Les résistances pull-up R2-R5 sont de 36 kOhm pour l'option avec photorésistances GL5516. Dans le cas d'un optocoupleur et d'un relais à phototransistor, réglé sur 4,7-5,1 kOhm. Le chargeur de démarrage Arduino Nano v3.0 a été remplacé par l'Arduino Uno à l'aide du programmateur TL866A pour le bon fonctionnement de la minuterie de surveillance. Les fusibles sont corrigés pour fonctionner à des tensions supérieures à 4,3 V. Le circuit de réinitialisation externe R6 C3 n'a pas été utilisé. Dans l'exemple de programme, la fréquence de l'émetteur ne correspond pas à la plage sans licence ; la plage de 2,4 MHz est limitée aux fréquences 2400.0 2483.5-XNUMX XNUMX MHz.

La portée de l'émetteur E01-ML01DP05 est de 2400 2525 à 1 24 MHz. La bande passante d'un canal est de 2 MHz, lorsque la vitesse est définie sur « RF120_2MBPS », le canal radio.setChannel(XNUMX) spécifié et le suivant seront occupés, c'est-à-dire la bande sera de XNUMX MHz.

Source: habr.com

Ajouter un commentaire