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

На підприємстві було закуплено посади моніторингу НЕКСТ-М вітчизняного виробництва «Некс Технолоджис». Для забезпечення візуалізації роботи насосних агрегатів,
пожежно-охоронної сигналізації, наявності напруги на пускачах, температури у приміщенні, аварійного рівня води. Серцем НЕКСТ-М служить 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В, включених послідовно для збереження при випадковій перевірці ланцюгів мегаомметром.
Зчитування показань часу напрацювання за допомогою РК екрану ST7735S, передача радіоканалу даних в режимі реального часу за допомогою модуля E01-ML01DP05 на частоті 2,4 МГц. Даний пристрій містить чіп nRF24L01+ і підсилювач прийому передачі RFX2401C,
Вихідна потужність до 100 мВт. Антени спіральні, розраховані на потрібний діапазон в онлайн-калькуляторі сайту. Вибір типу антен обумовлений виключенням прийому одноразово відбитих хвиль від навколишніх металоконструкцій. Деталі антен надруковані на 3Д принтері. Поточний стан лічильників зберігається в 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 байти, це число формату long, 4 лічильника, разом 4 байт займає один запис. Довжина пам'яті мікросхеми 16 байт, після 1024 записів 64-х лічильників запис почнеться спочатку. У бібліотеці EEPROM метод EEPROM.put не робить запис, якщо значення комірки та інформації, що записується, збігається, деградації осередків не буде. У результаті гарантованого напрацювання пам'яті буде понад 4 років. Час можливої, але негарантованої роботи може бути набагато більшим.

Принципова схемаЛокальна автономна система збору даних
Програма в Arduino IDE//12 байт (328%)

#include // Core graphics library
#include // Hardware-specific library
#включати
#include
#включати
#include
#include
RF24 radio(9, 10); // Об'єкт radio для роботи з бібліотекою RF24,
// та номери висновків nRF24L01+ (CE, CSN)
#включати
DS3231 rtc(SDA, SCL);
Time t;

//#define TFT_CS 10
#define TFT_CS 8
#define TFT_RST -1 // Ви можете також підключити це до Arduino reset
// У якому випадку, натиснути цей #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 // встановіть, щоб увімкнути pins you like!
#define TFT_MOSI 11 // натисніть на будь-яку pins you like!
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
#включати

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;
байт 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); // initialize a ST7735S chip, black 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); // Allow text to run off right edge
tft.setRotation( 2 ); // for BLACK PCB and RED tft.setRotation(0) or not.
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 MM»);
tft.setCursor (28, 20);
tft.print («BUILD-ER DD»);

//відновлення даних////////////////////////////////////////////// ////////////

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-х лічильників
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); // Pin 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
} Ще {
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 У. Зовнішній ланцюг скидання R6 C3 не використовувалася. У прикладі програми частота передавача не відповідає діапазону, що не ліцензується, діапазон 2,4 МГц обмежений частотами 2400.0-2483.5 МГц.

Діапазон передавача E01-ML01DP05 становить 2400-2525 МГц. Ширина лінії одного каналу- 1 МГц, при налаштуванні швидкості як «RF24_2MBPS» буде зайнятий вказаний radio.setChannel(120) канал і наступний, тобто. смуга буде 2 МГц.

Джерело: habr.com

Додати коментар або відгук