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

На предприятието бяха закупени постове за мониторинг НЕКСТ-М от родно производство «НексТ Технолоджис». За осигуряване на визуализация на работата на помпените агрегати,
пожарно-охранителната сигнализация, наличието на напрежение на пускателите, температурата в помещението, аварийното ниво на водата. Сърцето на НЕКСТ-М е ATMEGA 1280 и този факт вдъхновява в перспектива за създаването на собствен комплект за конкретни нужди.

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

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

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

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

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

  • територия на покритие 1 кв. км.
  • пряка видимост между обектите
  • температури от +50 до -50 С
  • влажност до 100%
  • биологично активни отложения (гъбички, сулфатредуциращи бактерии)
  • вибрация, не повече от класове 1-2 по ГОСТ ИСО 10816-1-97
  • електромагнитна обстановка - комутация на електродвигатели с контактори КТ 6053, апаратура за плавно пускане RVS-DN, апаратура за ПИД-регулиране SIEMENS MICROMASTER, излъчвания в ISM и GSM диапазон според изискванията към тези устройства, ръчна дъгово заварка на обекта
  • високо напрежение в мрежата, краткотрайни прекъсвания на електрозахранването, мълниеви пренапрежения, изкривяване на фазите при прекъсване на проводник от ВЛ в разпределителни мрежи 6-10 кВ.

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

С оглед на всичко, "мозъкът" на планираното стана платката "Ардуино нано 3.0". Платката от "Robotdyn" разполага с контролер ATMEGA 328, необходимия стабилизатор на напрежението 3,3В на
ток 800 мА и конвертер на CH340G UART-USB.

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

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

Принципна схемаЛокална автономна система за събиране на данни
Програмата в 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 за работа с библиотеката RF24,
// и номера выводов nRF24L01+ (CE, CSN)
#include <DS3231.h>
DS3231 rtc(SDA, SCL);
Time 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]; // масив с 4 стойности на броячите на секундите
float m = 3600.0;
unsigned int address = 0;
int rc; // променлива за броячите
unsigned long sumprim = 0;
unsigned long sumsec = 0;
byte i = 0;
byte k = 34;
unsigned int z = 0;
byte b = B00000001;
byte pumrcounter [4]; // масив за съхранение на състоянията на обектите, 1- изключено, 0- включено.
int start = 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, черен таб.
// 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); // Разрешаване на текста да се извива извън дясната граница.
tft.setRotation( 2 ); // за черен PCB и червен tft.setRotation(0) или не.
tft.fillScreen(ST7735_BLACK); // почистване на екрана

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

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

tft.setCursor (12, 0); // извеждане на 3 реда текст
tft.println («DEVELOPERS & BUILD» ); // за възхвала на нас самите
tft.setCursor (24, 10); // или злобен авторски права
tft.print («DEVELOPER M.M.»);
tft.setCursor (28, 20);
tft.print («BUILD-ER D.D.»);

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

for ( z = 0; z < 1023; z += 16 ) { // Прехождане на всички клетки на еепрома
//и записывает в массив из 4-х переменных pump, по 4 байта каждый счетчик, т.к.
// переменная беззнаковая лонг. Счетчиков 4, одна запись всех 4-х занимает 16 байт.
EEPROM.get ( z, pump [0]); // така, без for цикъл, по-малък обем
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; // увеличаване на адреса за запис на следващия блок без затиране на данните от последния запис

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

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

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

}

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

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
}
// индикация состояния объектов контроля цветом
// BLUE- это небольшой глюк имеющегося экрана ( или библиотеки? ), перепутаны RGB и BGR.
if (pinState == ( b << rc )) {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_BLUE); // за броене по ниско ниво сменете GREEN с BLUE
} else {
tft.fillRect(15, ((rc * 10 + shift)), 7, 7, ST7735_GREEN); // за броене по ниско ниво сменете BLUE с GREEN
pump [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 екрана

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

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

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

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

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

Съпротивленията с подтягане R2-R5 36 кОм за версията с фоторезистори GL5516. При използване на фототранзисторна опто-схема и релета, поставете 4,7-5,1 кОм. Бутлоадерът на 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.

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

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster