Lokalt autonomt datainsamlingssystem

Företaget köpte NEKST-M övervakningsstolpar, tillverkade på hemmaplan av Next Technologies. För att säkerställa visualisering av driften av pumpenheter,
brand- och trygghetslarm, spänningsnärvaro vid starter, rumstemperatur, nödvattennivå. Hjärtat i NEKST-M är ATMEGA 1280 och detta faktum är uppmuntrande när det gäller möjligheten att skapa ditt eget kit för specifika behov.

Uppgiften var inställd på att skapa ett helt autonomt lokalt utskickssystem för specifika behov på kortast möjliga tid och till minimal kostnad. Grunden är en mikrokontroller. Utveckling, tillverkning, skapad av personalen själva.

Systemet måste fungera utan beroende av mobilnät, servrar, internet och licenssystemet för användning av radiofrekvensresurser, inte använda datorer i driften av övervaknings- och kontrollsystemet eller som mest periodiskt använda bärbara datorer, utan tillgång till föremål under lång tid (6-9 månader). Nätverkskonfigurationen har en radiell struktur. Data samlas in vid ett tillfälle och skickas sedan för bearbetning via vanliga kommunikationskanaler eller som papperskopia.

Systemet måste tillhandahålla:

  • övervakning av driften av pumpenheter
  • teknisk automation
  • skydd mot konsekvenserna av nödsituationer
  • nödsignalering
  • drifttidsberäkning
  • beräkna mängden el som förbrukas
  • utrustningens temperaturkontroll
  • säkerhet och brandlarm
  • periodisk fjärrregistrering av information
  • okända framtida krav

Arbetsvillkor:

  • täckningsområde 1 kvadratkilometer.
  • direkt synlighet mellan objekt
  • temperatur från +50 till -50 C
  • luftfuktighet upp till 100%
  • biologiskt aktiva avlagringar (mögel, sulfatreducerande bakterier)
  • vibrationer, inte längre, av maskiner i klass 1-2 enligt GOST ISO 10816-1-97
  • elektromagnetisk miljö - omkoppling av elmotorer med KT 6053 kontaktorer, RVS-DN mjukstartsutrustning, SIEMENS MICROMASTER PID styrutrustning, strålning i ISM- och GSM-området enligt kraven för dessa enheter, manuell bågsvetsning på plats
  • för hög nätspänning, kortvariga avbrott i strömförsörjningen, blixtöverspänningar, fasobalans när en luftledning går sönder i 6-10 kV distributionsnät.

Trots så stränga krav är implementeringen ganska enkel när man löser problemet steg för steg.

Med allt i beräkningen blev "Arduino Nano 3.0"-kortet planens "hjärna". Robotdyn-kortet har en ATMEGA 328-kontroller, den nödvändiga 3,3V-spänningsstabilisatorn för
ström 800 mA och omvandlare till CH340G UART-USB.

Först och främst skapades drifttidsräknare som de mest uppdaterade. Tidigare använda industrimätare monterade på PIC:er med en transformatorlös strömförsörjningskrets misslyckades på grund av spänningsstötar inom ett års drift. Endast de som var anslutna med hemmagjorda 5V-strömförsörjningar förblev intakta. För att påskynda installationen och mångsidigheten i anslutningen tas en signal om enheternas tillstånd från kopplingsanordningarnas terminaler, dvs. registrering av närvaron av 1:a fasspänningen med en trefas strömförsörjning på 380V. För att samordna med regulatorn används ett mellanrelä med en 220V-lindning eller en optokopplare som består av en LED och en GL5516 fotoresistor eller en PC817 optokopplare. Alla alternativ testades. Lysdioden drivs av en likriktad spänning med strömbegränsning med hjälp av två SVV22-kondensatorer designade för en spänning på 630V kopplade i serie för säkerhet vid oavsiktlig testning av kretsarna med en megohmmeter.
Avläsning av drifttidsavläsningar med ST7735S LCD-skärm, realtidsdataöverföring via radio med E01-ML01DP05-modulen vid en frekvens på 2,4 MHz. Denna enhet innehåller nRF24L01+-chippet och RFX2401C sändnings-/mottagningsförstärkaren,
uteffekt upp till 100 mW. Spiralantenner designade för önskad räckvidd i online-kalkylatorn сайта. Valet av antenntyp bestäms av uteslutningen av mottagningen av enkelreflekterade vågor från omgivande metallstrukturer. Antenndelar skrivs ut på en 3D-skrivare. Räknarnas aktuella tillstånd lagras i själva styrenhetens EEPROM och återställs i händelse av ett oväntat strömavbrott. Tidsintervall för räkning tillhandahålls av RTC-chippet DS3231 i form av en modul med ett reservbatteri. Strömförsörjningen använder 3 moduler, den faktiska pulskällan 220/5V HLK-PM01 600mA, en omvandlare från 1-5V till 5V HW-553 и 03962A - batterikontroll med schema skydd mot kortslutning, överladdning och överladdning. Alla komponenter köptes på Aliexpress webbplats.

BrödbrädaLokalt autonomt datainsamlingssystem
4-kanals räknare. Det finns LC-filter vid ingångarna för att skydda mot störningar över en tvinnad kommunikationslinje. Data om kontrollobjektens tillstånd läses konstant en gång per sekund och visas i färg på LCD-skärmen. Avläsningarna uppdateras och registreras i det icke-flyktiga minnet var 1:e sekund. 36 sekunder är 36/1 av en timme, detta är formatet som data krävs. Var 100:e sek. information sänds om antalet sekunders drift för varje styrenhet. EEPROM-minnet har ett begränsat antal skriv-raderingscykler, enligt tillverkaren, 12 100000 gånger. Det värsta alternativet är när minst en cell ständigt uppdateras. Volymen för den första räknaren är 1 byte, detta är ett långt format nummer, 4 räknare, totalt 4 byte upptas av en post. Längden på chipets minne är 16 byte; efter 1024 inmatningar av 64 räknare kommer inspelningen att börja om. I EEPROM-biblioteket skriver inte metoden EEPROM.put, om värdet på cellen och informationen som skrivs överensstämmer, kommer det inte att ske någon försämring av cellerna. Som ett resultat kommer den garanterade minnesdrifttiden att vara mer än 4 år. Tiden för möjligt men inte garanterat arbete kan vara mycket längre.

KretsschemaLokalt autonomt datainsamlingssystem
Program i Arduino IDE//12 328 byte (38 %)

#omfatta // Kärngrafikbibliotek
#omfatta // Hårdvaruspecifikt bibliotek
#omfatta
#omfatta
#omfatta
#omfatta
#omfatta
RF24 radio(9, 10); // radioobjekt för att arbeta med RF24-biblioteket,
// och pin-nummer nRF24L01+ (CE, CSN)
#omfatta
DS3231 rtc(SDA, SCL);
Tid t;

//#define TFT_CS 10
#define TFT_CS 8
#define TFT_RST -1 // du kan också koppla denna till Arduino-återställningen
// i så fall, ställ in denna #define pin till -1!
//#define TFT_DC 9 // DC=RS=A0 - beteckningsalternativ för val av kommando eller dataregister.
#define TFT_DC 3

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

// Alternativ 2: använd valfri stift men lite långsammare!
#define TFT_SCLK 13 // ställ in dessa till att vara vilka stift du vill!
#define TFT_MOSI 11 // ställ in dessa till att vara vilka stift du vill!
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
#omfatta

byte shift = 52;
byte pinState;
osignerad lång pump[4];// array med 4 sekunders räknarvärden
float m = 3600.0;
osignerad int-adress = 0;
int rc;// variabel för räknare
osignerad lång sumprim = 0;
osignerad lång sumsek = 0;
byte i = 0;
byte k = 34;
osignerad int z = 0;
byte b = B00000001;
byte pumrcounter[4]; // array för att lagra objekttillstånd, 1 - av, 0 - på.
int start = 0; //

ogiltig installation () {

rtc.begin();
radio.begin(); // Initiera arbete nRF24L01+
radio.setChannel(120); // datakanal (från 0 till 127).
radio.setDataRate(RF24_250KBPS); // dataöverföringshastighet (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS).
radio.setPALevel(RF24_PA_MAX); // sändareffekt (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm,
// RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openWritingPipe(0xAABBCCDD11LL); // Öppna ett rör med en identifierare för dataöverföring

// För att ställa in tiden, avkommentera de nödvändiga raderna
//rtc.setDOW(1); // Veckodag
//rtc.setTime(21, 20, 0); // Tid, i 24-timmarsformat.
//rtc.setDate(29, 10, 2018); // Datum 29 oktober 2018

tft.initR(INITR_BLACKTAB); // initiera ett ST7735S-chip, svart flik
// Använd denna initialiserare (avkommentera) om du använder en 1.44" TFT
//tft.initR(INITR_144GREENTAB); // initiera ett ST7735S-chip, RÖD rcB-flik
tft.setTextWrap(false); // Tillåt text att rinna av högerkanten
tft.setRotation( 2 ); // för SVART PCB och RÖD tft.setRotation(0) eller inte.
tft.fillScreen(ST7735_BLACK); // rensa skärmen

DDRD = DDRD | B00000000;
PORTD = PORTD | B11110000; // mjukvaruåtstramningen fungerar, hög nivå -
// kontrollerade objekt "fungerar inte", "4" skrivs till alla 1 seniorportar D, ingen räkning sker.

för (rc = 0; rc < 4; rc++)
{
tft.setCursor ( 3, rc * 10 + shift ); // visar positionsnummer för kontrollobjekt
tft.print(rc + 1);
}

tft.setCursor(12, 0); // mata ut 3 rader text
tft.println("UTVECKLARE & BYGGA"); // att berömma dig själv nära och kära
tft.setCursor(24, 10); // eller ond upphovsrätt
tft.print("UTVECKLAR MM");
tft.setCursor(28, 20);
tft.print("BUILD-ER DD");

//dataåterställning/////////////////////////////////////////// ///////////

for ( z = 0; z < 1023; z += 16 ) { // Itererar genom alla celler i industrin
//och skriver till en array med 4 pumpvariabler, 4 byte för varje räknare, eftersom
// lång variabel utan tecken. Det finns 4 räknare, en post av alla 4 tar 16 byte.
EEPROM.get(z, pump[0]); // så, utan for-slingan, mindre volym
EEPROM.get(z+4, pump[1]);
EEPROM.get(z+8, pump[2]);
EEPROM.get(z+12, pump[3]);

// tilldelar ett nytt nästa värde för summan av 4 räknare
sumprim = (pump [0] + pump [1] + pump [2] + pump [3]);

// jämför det nya värdet av summan av 4 räknare i sumprimvariabeln med det tidigare värdet i variabeln
// sumsec och om den tidigare summan är mindre än eller lika med den nya summan, tilldelas den nya större eller lika
// sumsec värde.

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

//och det aktuella värdet z tilldelas adressvariabeln, z är adressen till början av ett 16-byte block med 4 värden
// räknare inspelade samtidigt (eftersom när man pollar en port skrivs alla 8 bitar av den samtidigt,
// inklusive våra nödvändiga höga 4 bitar av port D).
adress = z;
}
}

// återigen åtkomst till eeprom-minnet på adressen till början av ett block med 16 byte av 4 inspelade räknarvärden
// sist, dvs. värden innan avstängning eller omstart på grund av frysning. Spelar in det senaste
// räkna värden i en array med 4 variabler pump.

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

adress += 16; //ökning av adressen för att skriva nästa block utan att skriva över data från den sista posten

//slut på dataåterställning/////////////////////////////////////////////////////////// //////////////////

attachInterrupt(0, count, RISING); // pin D2, aktivera avbrott, kommer varje sekund
// pulser från RTC DS3231 från SQW-utgång

wdt_enable(WDTO_8S); // starta watchdog-timern, starta om kontrollern vid frysning, tid,
// för vilket du behöver utfärda timerreset-kommandot wdt_reset( och undvika omstart under normal drift - 8 sek.
// för tester rekommenderas inte att ställa in värdet till mindre än 8 sekunder. I detta fall återställs timern helst
// rycker, och det händer varje sekund.

}

ogiltig slinga () {
// tom cykel, här kommer det att finnas kontroll över elmotorns öppenfasdrift
}

void count() {

tft.setTextColor(ST7735_WHITE); // ställ in teckensnittsfärgen
t = rtc.getTime(); // lästid
tft.setCursor(5, 120); // ställer in markörens position
tft.fillRect(5, 120, 50, 7, ST7735_BLACK); // rensar tidsutdataområdet
tft.print(rtc.getTimeStr()); // mata ut klockavläsningar

wdt_reset(); // återställ vakthunden varje cykel, d.v.s. sekund

för (rc = 0; rc < 4; rc ++) // början av cykeln för att kontrollera överensstämmelsen med ingångstillståndet
// portbitar till det tidigare läsläget för port D-bitar
{
pinState = (PIND >> 4) & (b << rc);

if (pumrcounter [rc] != pinState) { // och om inte matchar, då
pumrcounter[rc] = pinState; // tilldelar portbitens statusvariabel ett nytt värde 1/0
}
// indikation på tillståndet för färgkontrollobjekt
// BLÅT är ett litet fel på den befintliga skärmen (eller biblioteket?), RGB och BGR blandas ihop.
if (pinState == ( b << rc )) {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_BLUE); // för lågnivåräkning ändra GRÖN till BLÅ
} Else {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_GREEN); // för lågnivåräkning ändra BLÅT till GRÖNT
pump [rc] += 1; // lägg till 1 sekund till drifttidsräknaren
}
}

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

tft.fillRect(30, shift, 97, 40, ST7735_BLACK); // rensar visningsområdet för drifttid
tft.fillRect(60, 120, 73, 7, ST7735_BLACK); // och datum

tft.setCursor(60, 120); // ställer in markörens position
tft.print(rtc.getDateStr()); // visa datumet på LCD-skärmen

för (rc = 0; rc < 4; rc ++) //output drifttimmar totalt, tiondelar och
{
tft.setCursor ( 30, rc * 10 + shift ); // hundradelar av en timme med en skärmförskjutning ned med 10 pixlar
tft.println(pump [rc] / m);
}

// skriver "rå" driftstimmarsvärden (i sekunder) till EEPROM ////////////////////////////////////////////////

för (rc = 0; rc < 4; rc++)
{
EEPROM.put(adress, pump [rc]);
adress += sizeof(float); // öka skrivadressvariabeln
}
}

// skicka data över radiokanalen från data som indikerar hur många byte som ska skickas.
om ((k == 6 ) || (k == 18 ) || (k == 30 )) {

långa osignerade data;

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

för (i = 0; i < 4; i++) {
data = pump[i];
radio.write( &data, sizeof( data));
}
}
}

Några anteckningar på slutet. Räkning sker på en låg logisk nivå vid ingångarna.

Uppdragningsmotstånd R2-R5 är 36 kOhm för alternativet med fotomotstånd GL5516. I fallet med en fototransistor optokopplare och relä, inställt på 4,7-5,1 kOhm. Arduino Nano v3.0 bootloader ersattes med Arduino Uno med hjälp av TL866A-programmeraren för korrekt funktion av watchdog-timern. Säkringarna är korrigerade för att fungera vid spänningar över 4,3 V. Den externa återställningskretsen R6 C3 användes inte. I exempelprogrammet motsvarar inte sändarfrekvensen det olicensierade området, 2,4 MHz-området är begränsat till frekvenserna 2400.0-2483.5 MHz.

Räckvidden för E01-ML01DP05-sändaren är 2400-2525 MHz. Bandbredden för en kanal är 1 MHz, när man ställer in hastigheten som “RF24_2MBPS” kommer den specificerade radio.setChannel(120) kanalen och nästa att vara upptagen, d.v.s. bandet kommer att vara 2 MHz.

Källa: will.com

Lägg en kommentar