Lokales autonomes System zur Datensammlung

In dem Unternehmen wurden Monitoring-Stationen vom heimischen Hersteller „Next Technologies“ beschafft. Für die Visualisierung der Arbeit der Pumpenaggregate,
Feuer- und Einbruchmeldeanlagen, das Vorhandensein von Spannung an den Startelementen, die Temperatur im Raum, den Alarmwasserstand. Das Herzstück des NEXST-M ist die ATMEGA 1280, was die Möglichkeit zur Erstellung eines eigenen Systems für spezifische Bedürfnisse erfreulich macht.

Die Aufgabe bestand darin, in minimaler Zeit und mit minimalen Kosten ein vollständig autonomes System zur lokalen Disposition für spezifische Bedürfnisse zu schaffen. Die Grundlage ist ein Mikrocontroller. Die Entwicklung und Herstellung erfolgt durch das Personal selbst.

Das System muss unabhängig von Mobilfunknetzen, Server, dem Internet und dem Genehmigungssystem zur Nutzung von Funkfrequenzressourcen arbeiten, wobei keine Computer für die Steuerungs- und Kontrollsysteme verwendet werden oder maximal periodisch Laptops eingesetzt werden dürfen, ohne dass über längere Zeiträume (6-9 Monate) Objekte betreten werden. Die Netzkonfiguration hat eine radiale Struktur. Daten werden an einem Punkt gesammelt und anschließend zur Bearbeitung über herkömmliche Kommunikationskanäle oder in Form einer haptischen Kopie gesendet.

Das System muss Folgendes gewährleisten:

  • Kontrolle des Betriebs der Pumpenanlagen
  • technologische Automatisierung
  • Schutz vor den Folgen von Notbetrieb
  • Alarmierung über Notbetriebsmodi
  • Erfassung der Betriebszeit
  • Zählung des verbrauchten Energievolumens
  • Kontrolle der Temperatur der Ausrüstung
  • Einbruch- und Brandschutzmeldeanlagen
  • zeitweilige Fernabfrage von Informationen
  • unbekannte Anforderungen in der Zukunft

Betriebsbedingungen:

  • Bedeckungsbereich von 1 qm.
  • direkte Sicht zwischen den Objekten
  • Temperatur von +50 bis -50 °C
  • Feuchtigkeit bis zu 100%
  • biologisch aktive Ablagerungen (Schimmel, sulfatreduzierende Bakterien)
  • Vibration, höchstens Maschinen der Klassen 1-2 nach GOST ISO 10816-1-97
  • elektromagnetische Bedingungen - Schaltung von Elektromotoren mit Controllern KT 6053, sanften Anlaufgeräten RVS-DN, PID-Regelungen SIEMENS MICROMASTER, Strahlung im ISM- und GSM-Bereich gemäß den Anforderungen an diese Geräte, manuelles elektrisches Lichtbogen-Schweißen vor Ort.
  • Überhöhte Netzspannung, kurzzeitige Unterbrechungen der Stromversorgung, Gewitterüberspannungen, Phasenverschiebungen bei einem Drahtbruch von Freileitungen in Verteilungssystemen von 6-10 kV.

Trotz solcher strengen Anforderungen ist die Umsetzung durchaus unkompliziert, wenn die Aufgabe schrittweise gelöst wird.

In Anbetracht aller Faktoren wurde das «Gehirn» des Vorhabens auf der «Arduino Nano 3.0»-Platine realisiert. Die Platine von «Robotdyn» hat einen ATMEGA 328 Mikrocontroller und einen notwendigen Spannungsregler von 3,3 V für
800 mA Strom und einen CH340G UART-USB-Konverter.

Zunächst wurden Leistungsmesser entwickelt, da diese am relevantesten sind. Die zuvor verwendeten industriellen Zähler, die auf PICs mit netztransformatorfreier Stromversorgung basierten, gingen aufgrund von Spannungsspitzen während eines Betriebsjahres kaputt. Nur die an selbstgebauten 5-V-Netzteilen angeschlossenen zählten weiterhin. Zur Beschleunigung der Montage und Universalität der Verbindung wird das Signal über den Zustand der Aggregate von den Anschlussklemmen der Schaltgeräte abgenommen, d.h. die Registrierung der Präsenz der ersten Phase der Spannung bei dreiphasiger 380-V-Versorgung. Zur Anpassung an den Mikrocontroller wird ein Zwischenrelais mit einer Spule von 220 V oder eine Optokoppler, die aus einer LED und einem GL5516-Fotowiderstand oder einem PC817-Optokoppler bestehen, verwendet. Alle Varianten wurden im Betrieb getestet. Die LED wird mit gleichgerichteter Spannung betrieben, wobei der Strom durch zwei in Serie geschaltete SVV22-Kondensatoren, die für 630 V ausgelegt sind, begrenzt wird, um bei zufälligem Testen der Schaltungen mit einem Isolationsmessgerät die Sicherheit zu gewährleisten.
Das Auslesen der Betriebsstundenzähler erfolgt über ein LCD-Display ST7735S, die Datenübertragung erfolgt über ein Funksignal in Echtzeit mit dem Modul E01-ML01DP05 bei einer Frequenz von 2,4 MHz. Dieses Gerät enthält den nRF24L01+ Chip und den RFX2401C Empfangs- und Sendeverstärker,
Ausgangsleistung bis zu 100 mW. Die Antennen sind Spiralantennen, die für den erforderlichen Frequenzbereich in einem Online-Rechner ausgelegt sind. der WebsiteDie Auswahl des Antennetyps hängt vom Ausschluss der Empfangs von einmal reflektierten Wellen durch umliegende Metallstrukturen ab. Die Teile der Antennen werden mit einem 3D-Drucker hergestellt. Der aktuelle Zustand der Zähler wird im EEPROM des Controllers gespeichert und kann im Falle eines unerwarteten Stromausfalls wiederhergestellt werden. Die Zeitintervalle für die Zählung werden durch den RTC-Chip DS3231 bereitgestellt, der als Modul mit einer Batterieversorgung arbeitet. Im Netzteil sind drei Module eingebaut: die eigentliche Impulsquelle 220/5V HLK-PM01 600mA, ein Wandler von 1-5V auf 5V. HW-553 und 03962A — ein Akkukontroller, der ein Schema zum Schutz vor Kurzschluss, Tiefentladung und Überladung hat. Alle Komponenten wurden auf der Aliexpress-Website erworben.

BrotbrettLokales autonomes System zur Datensammlung
4-Kanal-Zähler. An den Eingängen befinden sich LC-Filter zum Schutz vor Störungen über die Kommunikationsleitung aus verdrilltem Kabel. Die Daten über den Zustand der überwachten Objekte werden ständig einmal pro Sekunde ausgelesen und farblich auf dem LCD angezeigt. Die Aktualisierung der Anzeigen und die Speicherung in den nichtflüchtigen Speicher erfolgen alle 36 Sekunden. 36 Sekunden entsprechen 1/100 Stunde, genau in diesem Format werden die Daten benötigt. Alle 12 Sekunden erfolgt die Übertragung der Informationen über die Anzahl der Arbeitssekunden für jedes Kontrollaggregat. Der EEPROM-Speicher hat eine begrenzte Anzahl von Schreib-Löschzyklen, laut Hersteller 100.000 Mal. Der schlechteste Fall ist, wenn ständig mindestens eine Zelle aktualisiert wird. Der Umfang eines Zählers beträgt 4 Bytes, das ist eine Zahl im long-Format, 4 Zähler, somit benötigt ein Eintrag 16 Bytes. Die Länge des Chipspeichers beträgt 1024 Bytes, nach 64 Schreibvorgängen der 4 Zähler beginnt das Schreiben wieder von vorne. In der EEPROM-Bibliothek führt die Methode EEPROM.put keine Schreiboperation aus, wenn der Wert der Zelle mit den zu schreibenden Informationen übereinstimmt, eine Degradation der Zellen tritt nicht auf. Folglich wird die garantierte Betriebszeit des Speichers mehr als 7 Jahre betragen. Die mögliche, aber nicht garantierte Betriebszeit kann deutlich höher sein.

SchaltplanLokales autonomes System zur Datensammlung
Programm 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); // radio-Objekt für die Arbeit mit der RF24-Bibliothek,
// и номера выводов nRF24L01+ (CE, CSN)
#include <DS3231.h>
DS3231 rtc(SDA, SCL);
Zeit 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 mit 4 Zählerwerten in Sekunden
float m = 3600.0;
unsigned int address = 0;
int rc; // Variable für die Zähler
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 zum Speichern der Zustände der Objekte, 1 - aus, 0 - ein.
int start = 0; //

void setup() {

rtc.begin();
radio.begin(); // Initialisieren des nRF24L01+
radio.setChannel(120); // Datenübertragungskanal (von 0 bis 127).
radio.setDataRate (RF24_250KBPS); // Datenübertragungsrate (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS).
radio.setPALevel (RF24_PA_MAX); // Sendeleistung (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm,
// RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openWritingPipe (0xAABBCCDD11LL); // Öffne die Leitung mit der ID zur Datenübertragung

// Для установки времени- раскомментировать нужные строки
//rtc.setDOW(1); // День недели
//rtc.setTime(21, 20, 0); // Время, в формате 24 часа.
//rtc.setDate(29, 10, 2018); // Дата, 29 октября 2018г.

tft.initR(INITR_BLACKTAB); // ST7735S-Chip initialisieren, schwarzer Tab
// 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); // Erlaube Text, über die rechte Kante hinauszulaufen
tft.setRotation( 2 ); // für BLACK PCB und RED tft.setRotation(0) oder nicht.
tft.fillScreen(ST7735_BLACK); // Bildschirm löschen

DDRD = DDRD | B00000000;
PORTD = PORTD | B11110000; // Software-Pull-Up aktiv, hoher Pegel-
// контролируемые объекты «не работают», во все 4 старших порта D записана «1», не идет счет.

for ( rc = 0; rc < 4; rc++)
{
tft.setCursor ( 3, rc * 10 + shift ); // Ausgabe der Positionsnummern der Kontrollobjekte
tft.print ( rc + 1 );
}

tft.setCursor (12, 0); // Ausgabe von 3 Zeilen Text
tft.println («DEVELOPERS & BUILD» ); // zur Selbstlobung
tft.setCursor (24, 10); // oder böswilliger Urheberrechtshinweis
tft.print («DEVELOPER M.M.»);
tft.setCursor (28, 20);
tft.print («BUILD-ER D.D.»);

//восстановление данных/////////////////////////////////////////////////////////

for ( z = 0; z < 1023; z += 16 ) { // Durchläuft alle EEPROM-Zellen
//и записывает в массив из 4-х переменных pump, по 4 байта каждый счетчик, т.к.
// переменная беззнаковая лонг. Счетчиков 4, одна запись всех 4-х занимает 16 байт.
EEPROM.get ( z, pump [0]); // so, ohne for-Schleife, weniger Volumen
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; // Adresse für die nächste Schreibblockerhöhung, ohne die Daten des letzten Eintrags zu überschreiben

// конец восстановления данных////////////////////////////////////////////////////////////////

attachInterrupt(0, count, RISING); // Pin D2, Interrupt aktivieren, jede Sekunde kommen Daten
// импульсы от RTC DS3231 с выхода SQW

wdt_enable (WDTO_8S); // Wächtertimer starten, der den Controller im Falle eines Hängens neu startet, Zeit,
// за которое надо подать команду сброса таймера wdt_reset( и избежать перезагрузки при нормальной работе- 8 сек.
// для тестов не рекомендуется устанавливать значение менее 8 сек.В данном случае сброс таймера происходит в пре-
// рывании, а оно каждую секунду.

}

void loop() {
// пустой цикл, здесь будет контроль за неполнофазным режимом работы эл.двигателя
}

void count() {

tft.setTextColor(ST7735_WHITE); // Schriftfarbe einstellen
t = rtc.getTime(); // Zeit ablesen
tft.setCursor ( 5, 120 ); // Cursorposition einstellen
tft.fillRect ( 5, 120, 50, 7, ST7735_BLACK); // Bereich für die Zeitdarstellung leeren
tft.print(rtc.getTimeStr()); // Output clock readings

wdt_reset(); // Wächtertimer jedes Zyklus zurücksetzen, d.h. jede Sekunde

for (rc = 0; rc < 4; rc ++) // Beginn der Schleife zur Überprüfung des Zustands der Eingänge
// битов порта предыдущему считанному состоянию битов порта D
{
pinState = (PIND >> 4) & ( b << rc );

if (pumrcounter [rc] != pinState) { // und wenn sie nicht übereinstimmen, dann
pumrcounter [rc] = pinState; // Zuweisung des Statuswertes des Portbits an die Variable neuen Wertes 1/0
}
// индикация состояния объектов контроля цветом
// BLUE- это небольшой глюк имеющегося экрана ( или библиотеки? ), перепутаны RGB и BGR.
if (pinState == ( b << rc )) {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_BLUE); // zum Zählen bei niedrigem Pegel, BLUE in GREEN ändern
} else {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_GREEN); // zum Zählen bei niedrigem Pegel, BLUE in GREEN ändern
pump [rc] += 1; // zähle eine Sekunde zur Betriebszeit hinzu
}
}

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

tft.fillRect ( 30, shift, 97, 40, ST7735_BLACK ); // Bereinigung des Zeitdarstellungsbereichs
tft.fillRect ( 60, 120, 73, 7, ST7735_BLACK); // und des Datums

tft.setCursor ( 60, 120 ); // Cursorposition einstellen
tft.print(rtc.getDateStr()); // Datum auf LCD anzeigen

for (rc = 0; rc < 4; rc++) // Ausgabe der Messwerte in Ganzzahlen, Zehnteln und
{
tft.setCursor(30, rc * 10 + shift); // Hundertstel Stunden mit einer Vertikalverschiebung von 10 Pixeln auf dem Display
tft.println(pump[rc] / m);
}

// запись «сырых» значений наработки (в секундах)в EEPROM //////////////////////////////

for (rc = 0; rc < 4; rc++)
{
EEPROM.put(address, pump[rc]);
address += sizeof(float); // Inkrement der Speicheradresse
}
}

// отправляем данные по радиоканалу из 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));
}
}
}

Einige Hinweise am Ende. Die Zählung erfolgt bei niedrigem logischen Pegel an den Eingängen.

Die Pull-Up-Widerstände R2-R5 betragen 36 kOhm für die Variante mit Fotowiderständen GL5516. Bei Verwendung von Fototransistor-Optokopplern und Relais sollten 4,7-5,1 kOhm verwendet werden. Der Bootloader Arduino Nano v3.0 wurde durch Arduino Uno mit einem TL866A-Programmierer ersetzt, um eine ordnungsgemäße Funktion des Watchdog-Timers zu gewährleisten. Die Fuses wurden für den Betrieb bei einer Spannung über 4,3 V angepasst. Der externe Reset-Kreis R6 C3 wurde nicht verwendet. Im Beispielprogramm entspricht die Frequenz des Senders nicht dem lizenzfreien Bereich, der 2,4 MHz-Bereich ist auf die Frequenzen 2400,0–2483,5 MHz beschränkt.

Der Frequenzbereich des Senders E01-ML01DP05 beträgt 2400–2525 MHz. Die Bandbreite eines Kanals beträgt 1 MHz, bei einer Einstellung der Geschwindigkeit als „RF24_2MBPS“ wird der angegebene radio.setChannel(120)-Kanal und der nächste belegt, d. h. die Bandbreite beträgt 2 MHz.

Quelle: habr.com

60GB SSD 8Gb DDR4