На предприятието бяха закупени постове за мониторинг НЕКСТ-М, произведени от българската компания «НексТ Технолоджис». За визуализация на работата на помпените агрегати,
пожарно-охранителната сигнализация, наличието на напрежение на стартовите устройства, температурата в помещението и аварийните нива на водата. Сърцето на НЕКСТ-М е ATMEGA 1280, което дава надежда за възможността да се създаде собствен комплект за конкретни нужди.
Задачата беше в минимално кратки срокове и при минимални разходи да се създаде напълно автономна система за локална диспетчеризация според специфичните нужди. Основата е микроконтролер. Разработката и производството се извършват от самия персонал.
Системата трябва да работи без зависимост от мобилни мрежи, сървъри, интернет и разрешителна система за използване на радиочестотни ресурси, без да се използват компютри за системите за контрол и управление или максимум периодично използване на лаптопи, без достъп до обектите за дълъг период от време (6-9 месеца). Конфигурацията на мрежата е радиална. Данните се събират в една точка и след това се изпращат за обработка чрез обикновени комуникационни канали или под формата на физическо копие.
Системата трябва да осигурява:
- контрол на работата на помпени установки
- технологична автоматика
- защита от последици от аварийни режими
- сигнализация за аварийни режими
- изчисляване на времето на работа
- изчисляване на обема на потребената електрическа енергия
- контрол на температурата на оборудването
- охранно-пожарна сигнализация
- периодично дистанционно извличане на информация
- неизвестни изисквания в бъдеще
Условия за работа:
- обхват на територията 1 кв.км.
- пряка видимост между обектите
- температура от +50 до -50 С
- влажност до 100%
- биологично активни отлагания (гъбички, сулфатно-възстановяващи бактерии)
- вибрация, не повече от 1-2 класи на машините по ГОСТ ИСО 10816-1-97
- електромагнитна обстановка - комутация на електродвигатели с контактори КТ 6053, оборудване за плавно стартиране RVS-DN, оборудване за ПИД-регулиране SIEMENS MICROMASTER, излъчване в ISM и GSM диапазони, спазвайки изискванията за тези устройства, ръчна дъгова заварка на обекта
- превишено напрежение в мрежата, краткотрайни прекъсвания на електрозахранването, мълниеносни пренапрежения, фазов наклон при скъсване на проводник ВЛ в разпределителни мрежи 6-10 кВ.
Въпреки такива строги изисквания, реализацията е сравнително несложна при поетапно решаване на задачата.
С оглед на всичко, като "мозък" на замисления проект е избрана платката "Arduino Nano 3.0". Платката от "Robotdyn" има контролер ATMEGA 328 и необходими стабилизатор на напрежението 3,3V на
ток 800 мА и конвертор на CH340G UART-USB.
На първо място бяха създадени броячи на работа като най-актуални. Преди използваните промишлени броячи, изградени на PIC-ове с безтрансформаторна схема на захранване, се повредиха от скокове на напрежението през годината на работа. Цели останаха само свързаните чрез самоделни захранващи блокове на напрежение 5V. За ускоряване на монтажа и универсалност на свързването, сигналът за състоянието на агрегатите се взема от терминалите на комутационните устройства, т.е. регистриране на присъствието на 1-ва фаза на напрежението при трифазно захранване 380V. За съгласуването с контролера се използва междинно релета с намотка 220V или оптопара, съставена от светодиод и фоторезистор GL5516 или оптопара RS817. Всички варианти бяха тествани в работа. Светодиодът се захранва от правонапрежение с ограничение на тока с два конденсатора СВВ22, проектирани за напрежение 630V, свързани последователно за безопасност при случайна проверка на веригите с мегаомметър.
Отчитане на показанията за време на работа чрез LCD екран ST7735S, предаване на данни в реално време по радиочестота с модул E01-ML01DP05 на 2,4 MHz. Това устройство съдържа чип nRF24L01+ и усилвател за приемане-предаване RFX2401C,
изходна мощност до 100 mW. Антените са спирални и са проектирани за необходимия диапазон в онлайн калкулатора. . Изборът на тип антени е определен от изключването на приема на еднократно отразени вълни от околните метални конструкции. Частите на антената са изработени на 3D принтер. Текущото състояние на броячите се запазва в EEPROM на самия контролер и в случай на непредвидено отключване на захранването, се възстановява. Временните интервали за броене се осигуряват от RTC микросхемата DS3231 под формата на модул с резервна батерия. В захранването са приложени 3 модула, а именно импулсен източник 220/5В HLK-PM01 600mA, преобразувател от 1-5В до 5В. и — контролер на батерията, който има за защита от късо съединение, дълбоко разреждане и презареждане. Всички компоненти бяха закупени от сайта Aliexpress.
Макетна платка
4-канален брояч. На входовете са поставени LC филтри за защита от смущения по линията на свързване от усукана двойка. Данните за състоянието на контролируемите обекти постоянно се прочитат 1 път в секунда, отразяват се с цвят на LCD. Обновлението на показанията и записа в енергийно независима памет се извършва на всеки 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 и ЧЕРВЕН тft.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 kΩ за варианта с фотосензорите GL5516. В случай на фототранзисторна оптична връзка и реле, използвайте 4,7-5,1 kΩ. Зареждачът Arduino Nano v3.0 е заменен с Arduino Uno чрез програматора TL866A за правилна работа на стражевия таймер. Фюзите са коригирани за работа при напрежение над 4,3 V. Външната веригата за нулиране R6 C3 не е била използвана. В примера програмата честотата на предавателя не съответства на нелицензируемия диапазон, диапазонът 2,4 GHz е ограничен с честотите 2400.0—2483.5 MHz.
Диапазонът на предавателя E01-ML01DP05 е 2400-2525 MHz. Ширината на лентата на един канал е 1 MHz, при зададена скорост «RF24_2MBPS» ще бъде зает указания radio.setChannel(120) канал и следващият, т.е. лентата ще бъде 2 MHz.
Източник: habr.com
