Système d'acquisition de données autonome local

Suite de cet article
L'entreprise a acheté des postes de surveillance NEXT-M de la production nationale NEXT Technologies. Pour assurer la visualisation du fonctionnement des unités de pompage,
alarme incendie, tension au démarrage, température ambiante, niveau d'eau de secours. Le cœur de NEXT-M est l'ATMEGA 1280 et ce fait était encourageant en termes de possibilité de créer son propre kit pour des besoins spécifiques.

La tâche était de créer un système de répartition local entièrement autonome dans les plus brefs délais et au moindre coût. La base est le microcontrôleur. Développement, fabrication, le tout par le personnel lui-même.

Le système doit fonctionner sans dépendance vis-à-vis des réseaux cellulaires, des serveurs, d'Internet et du système de licence pour l'utilisation des ressources de radiofréquence, ne pas utiliser d'ordinateurs ou utiliser périodiquement au maximum les ordinateurs portables dans le système de surveillance et de contrôle, sans accès aux objets pendant une longue période (6-9 mois). La configuration du 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 conventionnels ou sous forme de copie papier.

Le système devrait fournir:

  • surveiller le fonctionnement des unités de pompage
  • automatisation technologique
  • protection d'urgence
  • alarme d'urgence
  • heures de fonctionnement
  • calcul de la quantité d'électricité consommée
  • contrôle de la température de l'équipement
  • alarme incendie
  • lecture périodique d'informations à distance
  • besoins futurs inconnus

Conditions de travail:

  • zone de couverture 1 km2.
  • 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, machines de 1 à 2 classes selon GOST ISO 10816-1-97
  • environnement électromagnétique - commutation des moteurs électriques par contacteurs KT 6053, démarreurs progressifs RVS-DN, équipement de contrôle PID SIEMENS MICROMASTER, rayonnement dans la gamme ISM et GSM selon les exigences de ces appareils, soudage à l'arc manuel sur site
  • surtension du réseau, coupures de courant de courte durée, surtensions de foudre, déséquilibre de phase en cas de ligne aérienne en circuit ouvert dans les réseaux de distribution de 6-10 kV.

Malgré ces exigences strictes, la mise en œuvre est assez simple avec une solution progressive au problème.

Avec tout cela à l'esprit, la carte Arduino Nano 3.0 est devenue le «cerveau» du conçu. Le châle Robotdyn a un contrôleur ATMEGA 328, le régulateur de tension 3,3 V nécessaire
Courant de 800 mA et convertisseur vers CH340G UART-USB.

Tout d'abord, les compteurs de temps de fonctionnement ont été créés comme les plus pertinents. Les compteurs industriels précédemment utilisés collectés sur des PIC avec un circuit d'alimentation sans transformateur sont tombés en panne à cause de surtensions pendant l'année de fonctionnement. Seul intact à l'aide d'alimentations maison pour 5V est resté intact. Pour accélérer l'installation et l'universalité de la connexion, un signal sur l'état des unités est prélevé sur les bornes des appareils de commutation, c'est-à-dire enregistrement de la présence de la 1ère phase de la tension avec une alimentation triphasée 380V. Pour coordonner 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 d'un optocouple 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 CBB22 conçus pour une tension de 630V et connectés en série pour la sécurité lors de la vérification aléatoire des circuits avec un mégohmmètre.
Lecture de la durée de fonctionnement à l'aide de l'écran LCD ST7735S, transmission de données en temps réel par voie aérienne à l'aide du module E01-ML01DP05 à une fréquence de 2,4 MHz. Cet appareil contient une puce nRF24L01 + et un amplificateur de réception-réception RFX2401C,
puissance de sortie jusqu'à 100 mW. Antennes spirales conçues pour la plage souhaitée dans la calculatrice en ligne du site . Le choix du type d'antenne est dû à l'exclusion de la réception des ondes une fois réfléchies des structures métalliques environnantes. Les pièces d'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 une batterie de secours. Trois modules sont utilisés dans l'unité d'alimentation, la source d'impulsions HLK-PM01 600mA 220 / 5V elle-même, les convertisseurs HW-553 et 03962A de 1-5V à 5V sont un contrôleur de batterie avec un circuit de protection contre les courts-circuits, les décharges excessives et les surcharges. Tous les composants ont été achetés sur le site Web Aliexpress.

Planche à pain
image alt

Compteur 4 canaux. Aux entrées se trouvent des filtres LC 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 1 fois par seconde, affichées en couleur sur l'écran LCD. Les lectures sont mises à jour et enregistrées dans une mémoire non volatile toutes les 36 secondes. 36 sec soit 1/100 heures, c'est dans ce format que les données sont nécessaires. Toutes les 12 secondes des informations sont transmises sur le nombre de secondes de fonctionnement de chaque unité de contrôle. La mémoire EEPROM a un nombre limité de cycles d'effacement en écriture, selon le fabricant, 100 000 fois. La pire option est lorsqu'au moins une cellule est constamment mise à jour. La taille du premier compteur est de 4 octets, c'est un nombre au format long, 4 compteurs, un total de 16 octets occupe 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 recommence. Dans la bibliothèque EEPROM, la méthode EEPROM.put n'enregistre pas, si la valeur de la cellule et les informations en cours d'écriture correspondent, il n'y aura pas de dégradation des cellules. En conséquence, la durée de fonctionnement garantie de la mémoire sera supérieure à 7 ans. Le temps d'un travail possible mais injustifié peut être beaucoup plus long.

Schéma du circuit
image alt

Programme en Arduino IDE
// 12 328 octets (38%)

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

// # définir TFT_CS 10
#define TFT_CS 8
#define TFT_RST -1 // vous pouvez également le connecter à la réinitialisation Arduino
// dans ce cas, définissez cette broche #define sur -1!
// # define TFT_DC 9 // DC = RS = A0- options pour désigner la sortie du choix du registre de commandes ou de données.
#define TFT_DC 3

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

// Option 2: utilisez des broches mais un peu plus lentement!
#define TFT_SCLK 13 // définissez-les comme les broches que vous aimez!
#define TFT_MOSI 11 // définissez-les comme les broches que vous aimez!
// Adafruit_ST7735 tft = Adafruit_ST7735 (TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
#include <avr / wdt.h>

décalage d'octet = 52;
byte pinState;
pompe longue non signée [4]; // tableau avec 4 secondes
flotteur m = 3600,0;
adresse int non signée = 0;
int rc; // variable pour les compteurs
sumprim long non signé = 0;
Sumsec long non signé = 0;
octet i = 0;
octet k = 34;
unsigned int z = 0;
octet b = B00000001;
compteur d'octets [4]; // tableau pour stocker les états des objets, 1- off, 0- on
int start = 0; //

void setup () {

rtc.begin ();
radio.begin (); // Lancer l'opération nRF24L01 +
radio.setChannel (120); // canal de transmission 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); // Ouvre le tube avec l'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, onglet noir
// Utilisez cet initialiseur (décommenter) si vous utilisez un TFT 1,44 "
//tft.initR(INITR_144GREENTAB); // initialise une puce ST7735S, onglet rcB ROUGE
tft.setTextWrap (false); // Autorise le texte à s'écouler du bord droit
tft.setRotation (2); // pour PCB noir et RED tft.setRotation (0) ou non.
tft.fillScreen (ST7735_BLACK); // efface l'écran

DDRD = DDRD | B00000000;
PORTD = PORTD | B11110000; // travaux de serrage de logiciels, haut niveau-
// les objets surveillés «ne fonctionnent pas», «1» est écrit dans les 4 ports supérieurs de D, le compte ne marche pas.

pour (rc = 0; rc <4; rc ++)
{
tft.setCursor (3, rc * 10 + shift); // affiche le nombre de positions des objets de contrôle
tft.print (rc + 1);
}

tft.setCursor (12, 0); // affiche 3 lignes de texte
tft.println ("DÉVELOPPEURS ET CONSTRUIRE"); // pour louer vos proches
tft.setCursor (24, 10); // ou mauvais droit d'auteur
tft.print ("DEVELOPER MM");
tft.setCursor (28, 20);
tft.print ("BUILD-ER DD");

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

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

// affectation d'une nouvelle valeur suivante de la somme des compteurs 4-x
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 le montant précédent est inférieur ou égal à la nouvelle somme, un nouveau supérieur ou égal est attribué
// valeur sumsec.

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

// et la valeur courante z est affectée à la variable d'adresse, z est l'adresse du début du bloc de 16 octets à partir de 4 valeurs
// compteurs enregistrés en même temps (car lors de l'interrogation d'un port, tous ses 8 bits sont enregistrés simultanément
// y compris nos 4 bits de port D souhaités).
adresse = z;
}
}

// Encore une fois, l'accès à la mémoire epromprom à l'adresse de début du bloc est de 16 octets à partir de 4 valeurs des compteurs enregistrés
// dernier, c'est-à-dire avant d'arrêter ou de redémarrer en raison d'un blocage. Dernier enregistrement
// valeurs des compteurs pour 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; // augmente l'adresse pour écrire le bloc suivant sans écraser les données du dernier enregistrement

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

attachInterrupt (0, count, RISING); // broche D2, activer le fonctionnement d'interruption, chaque seconde où ils arrivent
// impulsions du RTC DS3231 de la sortie SQW

wdt_enable (WDTO_8S); // démarre la minuterie de surveillance, redémarre le contrôleur en cas de blocage, heure,
// pour lequel vous devez envoyer la commande wdt_reset timer reset (et éviter de redémarrer pendant le fonctionnement normal - 8 secondes.
// pour les tests, il n'est pas recommandé de régler la valeur sur moins de 8 secondes. Dans ce cas, le temporisateur est réinitialisé avant
// creuser, et chaque seconde.

}

boucle vide () {
// cycle vide, ici il y aura un contrôle sur le mode de fonctionnement déphasé du moteur électrique
}

nombre de vides () {

tft.setTextColor (ST7735_WHITE); // définit la couleur de la police
t = rtc.getTime (); // temps de lecture
tft.setCursor (5, 120); // définir la position du curseur
tft.fillRect (5, 120, 50, 7, ST7735_BLACK); // zone de sortie de temps clair
tft.print (rtc.getTimeStr ()); // afficher les heures

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

for (rc = 0; rc <4; rc ++) // début de la boucle pour vérifier l'état de l'entrée
// bits de port à l'état de lecture précédent des bits de port D
{
pinState = (PIND >> 4) & (b << rc);

if (pumrcounter [rc]! = pinState) {// et s'il ne correspond pas, alors
pumrcounter [rc] = pinState; // attribue la variable d'état du bit de port à la nouvelle valeur 1/0
}
// indication de l'état des objets de contrôle des couleurs
// BLUE est un petit problème de l'écran (ou bibliothèque?) Existant, RGB et BGR sont mélangés.
if (pinState == (b << rc)) {
tft.fillRect (15, ((rc * 10 + shift)), 7, 7, ST7735_BLUE); // pour les comptes de bas niveau, remplacez GREEN par BLUE
} else {
tft.fillRect (15, ((rc * 10 + shift)), 7, 7, ST7735_GREEN); // pour un compte de bas niveau, changez BLEU en VERT
pompe [rc] + = 1; // ajoute 1 seconde au compteur d'exécution
}
}

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

tft.fillRect (30, shift, 97, 40, ST7735_BLACK); // efface la zone de sortie du runtime
tft.fillRect (60, 120, 73, 7, ST7735_BLACK); // et dates

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

for (rc = 0; rc <4; rc ++) // affiche les durées de fonctionnement en nombres entiers, dixièmes et
{
tft.setCursor (30, rc * 10 + shift); // centièmes d'heure avec un décalage de 10 pixels vers le bas sur l'écran
tft.println (pompe [rc] / m);
}

// enregistre les valeurs de temps 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'enregistrement
}
}

// envoie des données par liaison 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 (i = 0; i <4; i ++) {
données = pompe [i];
radio.write (& data, sizeof (data));
}
}
}

Quelques commentaires à la fin. Le compte passe à un niveau logique bas aux entrées.
Résistances de suspension R2-R5 36 kOhm pour la version avec photorésistances GL5516. Dans le cas des optocoupleurs et relais à phototransistor, fournir 4,7-5,1 kOhm. Arduino Nano v3.0 bootloader remplacé par Arduino Uno utilisant le programmateur TL866A pour un fonctionnement correct du chien de garde. 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 non autorisée, la plage 2,4 MHz est limitée aux fréquences 2400,0-2483,5 MHz.
La portée de l'émetteur du E01-ML01DP05 est de 2400-2525 MHz. La bande passante d'un canal est de 1 MHz, lorsque vous définissez la vitesse sur "RF24_2MBPS", le canal radio.setChannel (120) spécifié et le suivant, c'est-à-dire, seront occupés la bande sera de 2 MHz.
Continuation

Source: https://habr.com/ru/post/fr447168/


All Articles