Локална автономна система за събиране на данни

Компанията закупи постове за мониторинг NEKST-M, произведени в страната от Next Technologies. За да се осигури визуализация на работата на помпените агрегати,
противопожарни и охранителни аларми, наличие на напрежение при стартери, стайна температура, аварийно ниво на водата. Сърцето на NEKST-M е ATMEGA 1280 и този факт е обнадеждаващ от гледна точка на възможността за създаване на собствен комплект за конкретни нужди.

Поставена е задачата да се създаде напълно автономна локална диспечерска система за конкретни нужди в най-кратки срокове и с минимални разходи. Основата е микроконтролер. Разработка, производство, създадено от самия персонал.

Системата трябва да работи без зависимост от клетъчни мрежи, сървъри, интернет и лицензионната система за използване на радиочестотни ресурси, да не използва компютри при работата на системата за наблюдение и контрол или най-много периодично да използва лаптопи, без достъп до обекти за дълго време (6-9 месеца). Конфигурацията на мрежата има радиална структура. Данните се събират в една точка и след това се изпращат за обработка чрез редовни комуникационни канали или като хартиено копие.

Системата трябва да осигурява:

  • наблюдение на работата на помпените агрегати
  • технологична автоматизация
  • защита от последствията от извънредни ситуации
  • аварийна сигнализация
  • изчисляване на работното време
  • изчисляване на количеството консумирана електроенергия
  • контрол на температурата на оборудването
  • СОТ и пожароизвестяване
  • периодичен дистанционен запис на информация
  • неизвестни бъдещи изисквания

Условията на труд:

  • площ на покритие 1 кв. км.
  • директна видимост между обектите
  • температура от +50 до -50 С
  • влажност до 100%
  • биологично активни отлагания (мухъл, сулфат-редуциращи бактерии)
  • вибрации, не повече, на машини от класове 1-2 съгласно GOST ISO 10816-1-97
  • електромагнитна среда - комутация на електродвигатели с контактори KT 6053, оборудване за плавен старт RVS-DN, оборудване за управление SIEMENS MICROMASTER PID, облъчване в ISM и GSM диапазона според изискванията за тези устройства, ръчно електродъгово заваряване на място
  • прекомерно мрежово напрежение, краткотрайни прекъсвания на електрозахранването, пренапрежения от мълнии, дисбаланс на фазите при прекъсване на проводник на въздушна линия в разпределителни мрежи 6-10 kV.

Въпреки толкова строги изисквания, изпълнението е доста просто при решаване на проблема стъпка по стъпка.

Като се има предвид всичко, платката „Arduino Nano 3.0“ стана „мозъкът“ на плана. Платката robotdyn има контролер ATMEGA 328, необходимия стабилизатор на напрежение 3,3 V за
ток 800 mA и конвертор към CH340G UART-USB.

На първо място бяха създадени броячи на работни часове като най-актуални. Използваните по-рано индустриални измервателни уреди, сглобени на PIC с безтрансформаторна захранваща верига, се повредиха поради скокове на напрежението в рамките на една година работа. Само тези, свързани с домашни 5V захранвания, останаха непокътнати. За да се ускори инсталирането и гъвкавостта на свързването, сигналът за състоянието на модулите се взема от клемите на превключващите устройства, т.е. регистриране на наличието на 1-во фазово напрежение с трифазно захранване 380V. За координация с контролера се използва междинно реле с намотка 220V или оптрон, съставен от светодиод и фоторезистор GL5516 или оптрон PC817. Всички опции бяха тествани. Светодиодът се захранва от изправено напрежение с ограничение на тока, като се използват два кондензатора SVV22, проектирани за напрежение от 630 V, свързани последователно за безопасност по време на случайно тестване на веригите с мегаомметър.
Отчитане на показанията за работно време с помощта на LCD екран ST7735S, предаване на данни в реално време чрез радио с помощта на модул E01-ML01DP05 на честота 2,4 MHz. Това устройство съдържа чип nRF24L01+ и усилвател за предаване/приемане RFX2401C,
изходна мощност до 100 mW. Спирални антени, проектирани за желания обхват в онлайн калкулатора сайта. Изборът на тип антена се определя от изключването на приемането на единично отразени вълни от околните метални конструкции. Частите на антената се отпечатват на 3D принтер. Текущото състояние на броячите се съхранява в EEPROM на самия контролер и се възстановява в случай на неочаквано прекъсване на захранването. Времевите интервали за броене се осигуряват от RTC чипа DS3231 под формата на модул с резервна батерия. Захранването използва 3 модула, реален импулсен източник 220/5V HLK-PM01 600mA, преобразувател от 1-5V към 5V HW-553 и 03962A - контролер на батерията с схема защита срещу късо съединение, преразреждане и презареждане. Всички компоненти са закупени от уебсайта на Aliexpress.

Дъска за хлябЛокална автономна система за събиране на данни
4-канален брояч. Има LC филтри на входовете за защита срещу смущения по комуникационна линия с усукана двойка. Данните за състоянието на контролните обекти се четат постоянно веднъж в секунда и се показват цветно на LCD. Показанията се актуализират и записват в енергонезависима памет на всеки 1 секунди. 36 секунди е 36/1 от час, това е форматът, в който се изискват данните. На всеки 100 сек. предава се информация за броя секунди на работа за всеки контролен блок. EEPROM паметта има ограничен брой цикли запис-изтриване, според производителя, 12 100000 пъти. Най-лошият вариант е, когато поне една клетка непрекъснато се актуализира. Обемът на първия брояч е 1 байта, това е номер с дълъг формат, 4 брояча, общо 4 байта се заемат от един запис. Дължината на паметта на чипа е 16 байта, след 1024 записа на 64 брояча, записът ще започне отначало. В EEPROM библиотеката методът EEPROM.put не записва; ако стойността на клетката и записваната информация съвпадат, няма да има влошаване на клетките. В резултат на това гарантираното време за работа на паметта ще бъде повече от 4 години. Времето за възможна, но не гарантирана работа може да бъде много по-дълго.

Електрическа схемаЛокална автономна система за събиране на данни
Програма в Arduino IDE//12 328 байта (38%)

#включи // Основна графична библиотека
#включи // Специфична за хардуера библиотека
#include
#включи
#include
#включи
#включи
RF24 радио (9, 10); // радио обект за работа с библиотеката RF24,
// и пин номера nRF24L01+ (CE, CSN)
#включи
DS3231 rtc (SDA, SCL);
Време t;

//#define TFT_CS 10
#define TFT_CS 8
#define TFT_RST -1 // можете също да свържете това към нулирането на Arduino
// в който случай задайте този #define pin на -1!
//#define TFT_DC 9 // DC=RS=A0 - опции за обозначаване за избор на команда или регистър на данни.
#define TFT_DC 3

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

// Вариант 2: използвайте всякакви щифтове, но малко по-бавно!
#define TFT_SCLK 13 // задайте това да бъдат каквито щифтове желаете!
#define TFT_MOSI 11 // задайте това да бъдат каквито щифтове желаете!
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
#включи

смяна на байта = 52;
байт pinState;
unsigned long pump[4];// масив със стойности на брояча за 4 секунди
float m = 3600.0;
неподписан int адрес = 0;
int rc;// променлива за броячи
unsigned long sumprim = 0;
unsigned long sumsec = 0;
байт i = 0;
байт k = 34;
unsigned int z = 0;
байт b = B00000001;
брояч на байтове [4]; // масив за съхраняване на състоянията на обекта, 1 - изключено, 0 - включено.
int начало = 0; //

void setup () {

rtc.begin();
radio.begin(); // Започване на работа nRF24L01+
radio.setChannel(120); // канал за данни (от 0 до 127).
radio.setDataRate(RF24_250KBPS); // скорост на трансфер на данни (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS).
radio.setPALevel(RF24_PA_MAX); // мощност на предавателя (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm,
// RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openWritingPipe(0xAABBCCDD11LL); // Отваряне на канал с идентификатор за пренос на данни

// За да зададете времето, разкоментирайте необходимите редове
//rtc.setDOW(1); // Ден от седмицата
//rtc.setTime(21, 20, 0); // Време, в 24-часов формат.
//rtc.setDate(29, 10, 2018); // Дата, 29 октомври 2018 г

tft.initR(INITR_BLACKTAB); // инициализиране на чип ST7735S, черен раздел
// Използвайте този инициализатор (разкоментирайте), ако използвате 1.44" TFT
//tft.initR(INITR_144GREENTAB); // инициализиране на чип ST7735S, раздел ЧЕРВЕН rcB
tft.setTextWrap(false); // Позволете на текста да изтича от десния ръб
tft.setRotation(2); // за ЧЕРНА печатна платка и ЧЕРВЕНА tft.setRotation(0) или не.
tft.fillScreen(ST7735_BLACK); // изчистване на екрана

DDRD = DDRD | B00000000;
PORTD = PORTD | B11110000; // затягането на софтуера работи, високо ниво -
// контролираните обекти „не работят“, „4“ се записва на всичките 1 старши порта D, не се извършва броене.

за (rc = 0; rc < 4; rc++)
{
tft.setCursor (3, rc * 10 + shift); // показване на номера на позиции на контролни обекти
tft.print(rc + 1);
}

tft.setCursor(12, 0); // изведе 3 реда текст
tft.println("РАЗРАБОТЧИЦИ И ИЗГРАЖДАНЕ"); // да похвалите себе си близки
tft.setCursor(24, 10); // или зло авторско право
tft.print("РАЗРАБОТЧИК MM");
tft.setCursor(28, 20);
tft.print("BUILD-ER DD");

//възстановяване на данни////////////////////////////////////////////// ////////////

for ( z = 0; z < 1023; z += 16 ) { // Преминава през всички клетки на индустрията
//и записва в масив от 4 помпащи променливи, 4 байта за всеки брояч, защото
// неподписана дълга променлива. Има 4 брояча, един запис от всичките 4 отнема 16 байта.
EEPROM.get(z, помпа[0]); // така, без for цикъла, по-малко обем
EEPROM.get(z+4, помпа[1]);
EEPROM.get(z+8, помпа[2]);
EEPROM.get(z+12, помпа[3]);

// присвояване на нова следваща стойност за сумата от 4 брояча
sumprim = (помпа [0] + помпа [1] + помпа [2] + помпа [3]);

// сравнява новата стойност на сумата от 4 брояча в променливата sumprim с предишната стойност в променливата
// sumsec и ако предишната сума е по-малка или равна на новата сума, новата по-голяма или равна се присвоява
// sumsec стойност.

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

//и текущата стойност z се присвоява на адресната променлива, z е адресът на началото на 16-байтов блок от 4 стойности
// броячи, записани по едно и също време (тъй като при запитване на порт, всичките 8 бита от него се записват едновременно,
// включително нашите необходими високи 4 бита на порт D).
адрес = z;
}
}

// още веднъж достъп до eeprom паметта на адреса на началото на блок от 16 байта от 4 записани стойности на брояча
// последно, т.е. стойности преди изключване или рестартиране поради замръзване. Записва най-новото
// стойности на брояча в масив от 4 променливи помпа.

EEPROM.get(адрес, помпа[0]);
EEPROM.get(адрес + 4, помпа[1]);
EEPROM.get(адрес + 8, помпа[2]);
EEPROM.get(адрес + 12, помпа[3]);

адрес += 16; //увеличаване на адреса за запис на следващия блок без презаписване на данните от последния запис

//край на възстановяването на данни/////////////////////////////////////////// / ///////////////////

attachInterrupt(0, брой, RISING); // пин D2, разрешаване на прекъсвания, идват всяка секунда
// импулси от RTC DS3231 от SQW изход

wdt_enable(WDTO_8S); // стартиране на таймера за наблюдение, рестартиране на контролера в случай на замръзване, време,
// за което трябва да подадете командата за нулиране на таймера wdt_reset( и да избегнете рестартиране по време на нормална работа - 8 сек.
// за тестове не се препоръчва да задавате стойност на по-малко от 8 секунди.В този случай за предпочитане е таймерът да се нулира
// дръпване и това се случва всяка секунда.

}

цикъл void () {
// празен цикъл, тук ще има контрол върху отворената фаза на електродвигателя
}

void count() {

tft.setTextColor(ST7735_WHITE); // задаване на цвета на шрифта
t = rtc.getTime(); // време за четене
tft.setCursor(5, 120); // настройка на позицията на курсора
tft.fillRect(5, 120, 50, 7, ST7735_BLACK); // изчистване на зоната за извеждане на времето
tft.print(rtc.getTimeStr()); // изходни показания на часовника

wdt_reset(); // нулира контролера всеки цикъл, т.е. секунда

for (rc = 0; rc < 4; rc ++) // начало на цикъла за проверка на съответствието на входното състояние
// порт битове към предишното състояние на четене на порт D битове
{
pinState = (PIND >> 4) & (b << rc);

if (pumrcounter [rc] != pinState) { // и ако не съвпада, тогава
pumrcounter[rc] = pinState; // присвояване на променливата за състоянието на порт бит нова стойност 1/0
}
// индикация на състоянието на обектите за управление на цвета
// СИНЬО е малък проблем на съществуващия екран (или библиотека?), RGB и BGR са смесени.
if (pinState == ( b << rc )) {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_BLUE); // за ниско ниво на броене сменете ЗЕЛЕНОТО на СИНЬО
} Още {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_GREEN); // за отчитане на ниско ниво сменете СИНЬО на ЗЕЛЕНО
помпа [rc] += 1; // добавяне на 1 секунда към брояча на работното време
}
}

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

tft.fillRect(30, shift, 97, 40, ST7735_BLACK); // изчистване на зоната за показване на работното време
tft.fillRect(60, 120, 73, 7, ST7735_BLACK); // и дати

tft.setCursor(60, 120); // настройка на позицията на курсора
tft.print(rtc.getDateStr()); // показване на датата на LCD екрана

за (rc = 0; rc < 4; rc ++) //изходни работни часове цели, десети и
{
tft.setCursor (30, rc * 10 + shift); // стотни от час с изместване на екрана надолу с 10 пиксела
tft.println(помпа [rc] / m);
}

// записване на „сурови“ стойности на работните часове (в секунди) в EEPROM ///////////////////////////////

за (rc = 0; rc < 4; rc++)
{
EEPROM.put(адрес, помпа [rc]);
адрес += sizeof(float); // увеличава променливата на адреса за запис
}
}

// изпраща данни по радиоканала от данни, показващи колко байта трябва да бъдат изпратени.
if ((k == 6 ) || (k == 18 ) || (k == 30 )) {

неподписани дълги данни;

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

за (i = 0; i < 4; i++) {
данни = помпа [i];
radio.write( &данни, sizeof(данни));
}
}
}

Няколко бележки в края. Броенето се извършва на ниско логическо ниво на входовете.

Издърпващите съпротивления R2-R5 са 36 kOhm за варианта с фоторезистори GL5516. В случай на фототранзисторен оптрон и реле, настройте на 4,7-5,1 kOhm. Буутлоудърът Arduino Nano v3.0 беше заменен с Arduino Uno с помощта на програмиста TL866A за правилната работа на таймера за наблюдение. Предпазителите са коригирани да работят при напрежение над 4,3 V. Външната верига за нулиране R6 C3 не е използвана. В примерната програма честотата на предавателя не съответства на нелицензирания диапазон; обхватът от 2,4 MHz е ограничен до честоти 2400.0-2483.5 MHz.

Обхватът на предавателя E01-ML01DP05 е 2400-2525 MHz. Честотната лента на един канал е 1 MHz, при настройка на скоростта като “RF24_2MBPS” посоченият radio.setChannel(120) канал и следващият ще бъдат заети, т.е. лентата ще бъде 2 MHz.

Източник: www.habr.com

Добавяне на нов коментар