Lokalny autonomiczny system gromadzenia danych

Spółka zakupiła stanowiska monitorujące NEKST-M produkcji krajowej firmy Next Technologies. Aby zapewnić wizualizację pracy agregatów pompowych,
alarmy przeciwpożarowe i bezpieczeństwa, obecność napięcia na rozrusznikach, temperatura pokojowa, awaryjny poziom wody. Sercem NEKST-M jest ATMEGA 1280 i fakt ten cieszy pod względem możliwości stworzenia własnego zestawu pod konkretne potrzeby.

Zadanie polegało na stworzeniu w pełni autonomicznego lokalnego systemu dyspozytorskiego na konkretne potrzeby w możliwie najkrótszym czasie i przy minimalnych kosztach. Podstawą jest mikrokontroler. Rozwój, produkcja, tworzone przez samych pracowników.

System musi działać niezależnie od sieci komórkowych, serwerów, Internetu i systemu licencjonowania korzystania z zasobów częstotliwości radiowych, nie wykorzystywać komputerów w obsłudze systemu monitorowania i sterowania lub co najwyżej okresowo korzystać z laptopów, bez dostępu do obiektów przez długi czas (6-9 miesięcy). Konfiguracja sieci ma strukturę promieniową. Dane zbierane są w jednym miejscu, a następnie przesyłane do przetwarzania zwykłymi kanałami komunikacji lub w formie papierowej.

System musi zapewniać:

  • monitorowanie pracy agregatów pompowych
  • automatyzacja technologiczna
  • ochrona przed skutkami warunków awaryjnych
  • sygnalizacja awaryjna
  • obliczanie czasu pracy
  • obliczanie ilości zużytej energii elektrycznej
  • kontrola temperatury sprzętu
  • alarm i alarm przeciwpożarowy
  • okresowe zdalne rejestrowanie informacji
  • nieznane przyszłe wymagania

Warunki pracy:

  • obszar zasięgu 1 kmXNUMX.
  • bezpośrednia widoczność pomiędzy obiektami
  • temperatura od +50 do -50 C
  • wilgotność do 100%
  • osady biologicznie aktywne (pleśń, bakterie redukujące siarczany)
  • drgań, nie więcej, maszyn klas 1-2 według GOST ISO 10816-1-97
  • środowisko elektromagnetyczne - załączanie silników elektrycznych za pomocą styczników KT 6053, urządzenia miękkiego startu RVS-DN, urządzenia sterujące SIEMENS MICROMASTER PID, promieniowanie w zakresie ISM i GSM zgodnie z wymaganiami dla tych urządzeń, ręczne spawanie łukowe na miejscu
  • nadmierne napięcie sieciowe, krótkotrwałe przerwy w dostawie prądu, przepięcia piorunowe, niezrównoważenie faz w przypadku przerwy w przewodzie linii napowietrznej w sieciach dystrybucyjnych 6-10 kV.

Pomimo tak rygorystycznych wymagań, wdrożenie jest dość proste, rozwiązując problem krok po kroku.

Biorąc wszystko pod uwagę, „mózgiem” planu stała się płytka „Arduino Nano 3.0”. Na płycie robotdyn znajduje się kontroler ATMEGA 328, niezbędny do zasilania stabilizator napięcia 3,3V
prąd 800 mA i konwerter na CH340G UART-USB.

Przede wszystkim stworzono liczniki godzin pracy, jako najnowocześniejsze. Dotychczas używane liczniki przemysłowe montowane na układach PIC z beztransformatorowym obwodem zasilania uległy awarii na skutek skoków napięcia w ciągu roku eksploatacji. Jedynie te podłączone za pomocą domowych zasilaczy 5V pozostały nienaruszone. Aby przyspieszyć montaż i wszechstronność podłączenia, sygnał o stanie zespołów pobierany jest z zacisków urządzeń przełączających, tj. rejestracja obecności napięcia I fazy przy zasilaniu trójfazowym 1V. Do koordynacji ze sterownikiem stosuje się przekaźnik pośredni z uzwojeniem 380 V lub transoptor składający się z diody LED i fotorezystora GL220 lub transoptor PC5516. Wszystkie opcje zostały przetestowane. Dioda LED zasilana jest napięciem wyprostowanym z ograniczeniem prądu za pomocą dwóch kondensatorów SVV817 zaprojektowanych na napięcie 22V, połączonych szeregowo dla bezpieczeństwa podczas przypadkowego sprawdzania obwodów megaomomierzem.
Odczyt wskazań czasu pracy za pomocą ekranu LCD ST7735S, transmisja danych w czasie rzeczywistym drogą radiową za pomocą modułu E01-ML01DP05 na częstotliwości 2,4 MHz. To urządzenie zawiera układ nRF24L01+ i wzmacniacz nadawczo-odbiorczy RFX2401C,
moc wyjściowa do 100 mW. Anteny śrubowe zaprojektowane dla żądanego zasięgu w kalkulatorze online сайта. O wyborze typu anteny decyduje wykluczenie odbioru pojedynczych fal odbitych od otaczających konstrukcji metalowych. Części anteny są drukowane na drukarce 3D. Aktualny stan liczników zapisywany jest w pamięci EEPROM samego sterownika i jest przywracany w przypadku nieoczekiwanej przerwy w dostawie prądu. Przedziały czasowe do zliczania zapewnia układ RTC DS3231 w postaci modułu z baterią podtrzymującą. W zasilaczu zastosowano 3 moduły, źródło impulsowe rzeczywiste 220/5V HLK-PM01 600mA, konwerter z 1-5V na 5V HW-553 и 03962A - kontroler baterii z schemat ochrona przed zwarciem, nadmiernym rozładowaniem i przeładowaniem. Wszystkie komponenty zostały zakupione na stronie Aliexpress.

Deska do chlebaLokalny autonomiczny system gromadzenia danych
Licznik 4-kanałowy. Na wejściach znajdują się filtry LC chroniące przed zakłóceniami w linii komunikacyjnej skrętką. Dane o stanie obiektów kontrolnych są stale odczytywane raz na sekundę i wyświetlane w kolorze na wyświetlaczu LCD. Odczyty są aktualizowane i zapisywane w pamięci nieulotnej co 1 sekund. 36 sekund to 36/1 godziny. Jest to format, w jakim wymagane są dane. Co 100 sek. przekazywana jest informacja o liczbie sekund pracy każdej jednostki sterującej. Pamięć EEPROM ma ograniczoną liczbę cykli zapisu i kasowania, według producenta, 12 100000 razy. Najgorszą opcją jest sytuacja, gdy co najmniej jedna komórka jest stale aktualizowana. Objętość pierwszego licznika wynosi 1 bajty, jest to liczba w długim formacie, 4 liczniki, łącznie 4 bajtów zajmuje jeden rekord. Długość pamięci chipa wynosi 16 bajty, po 1024 wpisach 64 liczników rejestracja rozpocznie się od nowa. W bibliotece EEPROM metoda EEPROM.put nie zapisuje; jeśli wartość komórki i zapisywane informacje są zgodne, nie nastąpi degradacja komórek. Dzięki temu gwarantowany czas pracy pamięci wyniesie ponad 4 lat. Czas możliwej, ale nie gwarantowanej pracy może być znacznie dłuższy.

Schemat obwoduLokalny autonomiczny system gromadzenia danych
Program w Arduino IDE//12 328 bajtów (38%)

#włączać // Podstawowa biblioteka graficzna
#włączać // Biblioteka specyficzna dla sprzętu
#zawierać
#włączać
#zawierać
#włączać
#włączać
Radio RF24(9, 10); // obiekt radiowy do pracy z biblioteką RF24,
// i numery pinów nRF24L01+ (CE, CSN)
#włączać
DS3231 rtc(SDA, SCL);
Czas t;

//#zdefiniuj TFT_CS 10
#zdefiniuj TFT_CS 8
#define TFT_RST -1 // możesz także podłączyć to do resetu Arduino
// w takim przypadku ustaw ten pin #define na -1!
//#define TFT_DC 9 // DC=RS=A0 - opcje oznaczenia służące do wyboru polecenia lub rejestru danych.
#zdefiniuj TFT_DC 3

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

// Opcja 2: użyj dowolnych pinów, ale trochę wolniej!
#define TFT_SCLK 13 // ustaw je na dowolne piny!
#define TFT_MOSI 11 // ustaw je na dowolne piny!
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
#włączać

przesunięcie bajtu = 52;
bajt pinState;
unsigned long pompa[4];// tablica z wartościami liczników z 4 sekund
pływak m = 3600.0;
adres int bez znaku = 0;
int rc;// zmienna dla liczników
długi sumprim bez znaku = 0;
długa suma bez znaku = 0;
bajt i = 0;
bajt k = 34;
bez znaku int z = 0;
bajt b = B00000001;
bajt licznika[4]; // tablica do przechowywania stanów obiektów, 1 - wyłączona, 0 - włączona.
int początek = 0; //

void setup () {

rtc.begin();
radio.begin(); // Rozpocznij pracę nRF24L01+
radio.setKanał(120); // kanał danych (od 0 do 127).
radio.setDataRate(RF24_250KBPS); // szybkość transmisji danych (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS).
radio.setPALevel(RF24_PA_MAX); // moc nadajnika (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm,
// RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openWritingPipe(0xAABBCCDD11LL); // Otwórz potok z identyfikatorem do przesyłania danych

// Aby ustawić godzinę, odkomentuj niezbędne linie
//rtc.setDOW(1); // Dzień tygodnia
//rtc.setTime(21, 20, 0); // Czas w formacie 24-godzinnym.
//rtc.setDate(29, 10, 2018); // Data, 29 października 2018 r

tft.initR(INITR_BLACKTAB); // inicjalizacja układu ST7735S, czarna zakładka
// Użyj tego inicjatora (odkomentuj), jeśli używasz 1.44-calowego TFT
//tft.initR(INITR_144GREENTAB); // zainicjuj układ ST7735S, zakładka RED rcB
tft.setTextWrap(false); // Zezwalaj na wychodzenie tekstu poza prawą krawędź
tft.setRotation( 2 ); // dla CZARNEJ PCB i CZERWONEJ tft.setRotation(0) lub nie.
tft.fillScreen(ST7735_BLACK); // czysty ekran

DDRD = DDR | B00000000;
PORTD = PORTD | B11110000; // dokręcanie oprogramowania działa, wysoki poziom -
// kontrolowane obiekty „nie działają”, „4” jest zapisywane na wszystkich 1 starszych portach D, zliczanie nie jest wykonywane.

dla ( rc = 0; rc < 4; rc++)
{
tft.setCursor ( 3, rc * 10 + przesunięcie ); // wyświetlanie numerów pozycji obiektów kontrolnych
tft.print(rc + 1);
}

tft.setCursor(12, 0); // wypisz 3 linie tekstu
tft.println("DEWELOPERS I BUDUJ"); // chwalić się bliskimi
tft.setCursor(24, 10); // lub złe prawa autorskie
tft.print("MM DEWELOPERA");
tft.setCursor(28, 20);
tft.print("BUILD DD");

//odzyskiwanie danych////////////////////////////////////////////// ///////////

for ( z = 0; z < 1023; z += 16 ) { // Iteruje po wszystkich komórkach branży
//i zapisuje do tablicy 4 zmiennych pompy, po 4 bajty na każdy licznik, ponieważ
// długa zmienna bez znaku. Istnieją 4 liczniki, jeden rekord ze wszystkich 4 zajmuje 16 bajtów.
EEPROM.get(z, pompa[0]); // więc bez pętli for mniejsza głośność
EEPROM.get(z+4, pompa[1]);
EEPROM.get(z+8, pompa[2]);
EEPROM.get(z+12, pompa[3]);

// przypisanie nowej kolejnej wartości sumie 4 liczników
sumprim = (pompa [0] + pompa [1] + pompa [2] + pompa [3]);

// porównuje nową wartość sumy 4 liczników w zmiennej sumprim z poprzednią wartością zmiennej
// sumsec i jeśli poprzednia suma jest mniejsza lub równa nowej sumie, przydzielana jest nowa większa lub równa
// wartość sumy sekund.

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

//a bieżąca wartość z jest przypisana do zmiennej adresu, z jest adresem początku 16-bajtowego bloku 4 wartości
// liczniki rejestrowane w tym samym czasie (ponieważ podczas odpytywania portu wszystkie 8 bitów są zapisywane jednocześnie,
// włączając nasze niezbędne wysokie 4 bity portu D).
adres = z;
}
}

// ponowne uzyskanie dostępu do pamięci eeprom pod adresem początku bloku 16 bajtów 4 zarejestrowanych wartości liczników
// ostatni, tj. wartości przed wyłączeniem lub ponownym uruchomieniem z powodu zamrożenia. Nagrywam najnowsze
// licznik wartości do tablicy 4 zmiennych pompy.

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

adres += 16; //zwiększenie adresu zapisu kolejnego bloku bez nadpisywania danych ostatniego rekordu

//koniec odzyskiwania danych/////////////////////////////////////////// //////////////////

dołączPrzerwanie(0, liczba, WSCHODZĄCY); // pin D2, włącz przerwania, przychodzą co sekundę
// impulsy z RTC DS3231 z wyjścia SQW

wdt_enable(WDTO_8S); // uruchom timer watchdoga, zrestartuj kontroler w przypadku zamrożenia, czas,
// dla którego należy wydać polecenie resetowania timera wdt_reset( i uniknąć ponownego uruchamiania podczas normalnej pracy - 8 sek.
// dla testów nie zaleca się ustawiania wartości mniejszej niż 8 sekund.W takim przypadku najlepiej jest zresetować timer
// szarpnięcie i dzieje się to co sekundę.

}

void loop () {
// cykl pusty, tutaj będzie kontrola pracy silnika elektrycznego w fazie otwartej
}

liczba pustych wartości() {

tft.setTextColor(ST7735_WHITE); // ustaw kolor czcionki
t = rtc.getTime(); // czas czytania
tft.setCursor(5, 120); // ustawienie pozycji kursora
tft.fillRect(5, 120, 50, 7, ST7735_BLACK); // czyszczenie obszaru wyjściowego czasu
tft.print(rtc.getTimeStr()); // odczyty zegara wyjściowego

wdt_reset(); // resetuj watchdoga w każdym cyklu, tj. w sekundzie

for (rc = 0; rc < 4; rc ++) // początek cyklu sprawdzającego zgodność stanu wejściowego
// bity portu do poprzedniego stanu odczytu bitów portu D
{
pinState = (PIND >> 4) & ( b << rc );

if (pumrcounter [rc] != pinState) { // i jeśli nie pasuje, to
pumrcounter[rc] = stan pinu; // przypisanie zmiennej statusu bitu portu nowej wartości 1/0
}
// wskazanie stanu obiektów kontroli koloru
// NIEBIESKI to mała usterka istniejącego ekranu (lub biblioteki?), RGB i BGR są pomieszane.
if (stan pinu == ( b << rc )) {
tft.fillRect(15, ((rc * 10 + przesunięcie)), 7, 7, ST7735_BLUE); // dla zliczania niskiego poziomu zmień ZIELONY na NIEBIESKI
} Else {
tft.fillRect(15, ((rc * 10 + przesunięcie)), 7, 7, ST7735_GREEN); // dla zliczania niskiego poziomu zmień NIEBIESKI na ZIELONY
pompa [rc] += 1; // dodaj 1 sekundę do licznika czasu pracy
}
}

k++;
jeśli (k == 36) {
k = 0;

tft.fillRect(30, przesunięcie, 97, 40, ST7735_BLACK); // czyszczenie obszaru wyświetlania czasu pracy
tft.fillRect(60, 120, 73, 7, ST7735_BLACK); // i daty

tft.setCursor(60, 120); // ustawienie pozycji kursora
tft.print(rtc.getDateStr()); // wyświetl datę na ekranie LCD

for (rc = 0; rc < 4; rc ++) //wyjście godzin pracy w całości, dziesiątych i
{
tft.setCursor ( 30, rc * 10 + shift ); // setne godziny przy przesunięciu ekranu w dół o 10 pikseli
tft.println(pompa [rc] / m);
}

// zapis „surowych” wartości godzin pracy (w sekundach) do EEPROM /////////////////////////////

dla (rc = 0; rc < 4; rc++)
{
EEPROM.put(adres, pompa [rc]);
adres += rozmiar(float); // zwiększ zmienną adresu zapisu
}
}

// wyślij dane kanałem radiowym z danych wskazujących, ile bajtów należy przesłać.
if ((k == 6 ) || (k == 18 ) || (k == 30 )) {

długie dane bez znaku;

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

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

Na koniec kilka uwag. Zliczanie odbywa się na niskim poziomie logicznym na wejściach.

Rezystancje podciągające R2-R5 wynoszą 36 kOhm dla opcji z fotorezystorami GL5516. W przypadku transoptora i przekaźnika fototranzystora ustawić na 4,7-5,1 kOhm. Bootloader Arduino Nano v3.0 został zastąpiony Arduino Uno przy użyciu programatora TL866A do poprawnego działania timera watchdoga. Bezpieczniki są przystosowane do pracy przy napięciach powyżej 4,3 V. Zewnętrzny obwód resetujący R6 C3 nie był używany. W przykładowym programie częstotliwość nadajnika nie odpowiada zakresowi nielicencjonowanemu, zakres 2,4 MHz ogranicza się do częstotliwości 2400.0-2483.5 MHz.

Zasięg nadajnika E01-ML01DP05 wynosi 2400-2525 MHz. Szerokość pasma jednego kanału wynosi 1 MHz, przy ustawieniu prędkości na „RF24_2MBPS” określony kanał radio.setChannel(120) i następny będzie zajęty, tj. pasmo będzie wynosić 2 MHz.

Źródło: www.habr.com

Dodaj komentarz