Модуль дистанционного телеуправления, телесигнализации, мониторинга температуры и сетевого напряжения

Устройство дистанционного телеуправления, телесигнализации,
мониторинга температуры и сетевого напряжения.
Необходимость разработки такого устройства обусловлена следующими причинами:

  • современные коттеджи характеризуются наличием большого количества дорогостоящих электронных устройств (компьютеры, аудио и видеоаппаратура, бытовая техника, системы управления отоплением, водоснабжением, пожарной и охранной сигнализации др.).
    Надежность работы всех этих устройств сильно зависит от качества питающего напряжения. Для его оценки необходимо проводить непрерывный мониторинг сетевого напряжения в течение, как минимум сутки, чтобы охватывать периоды вечернего максимума и ночного минимума сетевой нагрузки.

  • в связи с постоянным ростом тарифов на электроэнергию и газ, для снижения расходов на их оплату проводятся различные мероприятия для снижения
    таких расходов.
    Одним из способов, позволяющим оценить их эффективность, является суточные мониторинги внутренней температуры при различных внешних температурах.
    Сравнивая скорость падения и роста внутренней температуры до проведения
    защитных мероприятий и после их проведения, можно оценить эффективность проводимых мероприятий.

Разработанный модуль проверялся на работу по радиоканалу на расстоянии до
100м :

  • Телеуправление по четырём каналам с помощью реле, коммутирующим нагрузку
    с напряжением до 250 вольт и током до 2-х ампер (активная нагрузка);
  • Телесигнализацию по одному каналу от датчиков типа “сухой контакт”.
    Срабатывание сигнализации происходит при размыкании контакта с включением зуммера.
  • Измерение температуры в диапазоне от -20℃ до +45℃
    Индицируется:
  • текущая температура
  • максимальная и минимальная измеренная температура с привязкой к дате и времени
  • Индикацию даты и времени. Индицируется число и название месяца, год, день недели, часы, минуты и секунды
  • Измерение переменного напряжения 250В, 50Гц
    Индицируется:
  • текущее напряжение
  • максимальное и минимальное напряжение с привязкой к дате и времени
  • Мониторинг измеренных значений температуры или напряжения с записью во внешнюю EEPROM типа АТ24С256 или внутреннюю EEPROM
    При мониторинге отслеживаются моменты:
  • выхода за заданные пределы и возврата напряжения или температуры в заданные пределы.
  • максимальное и минимальное напряжение за период архивации
    Эти сведения, накопленные за сутки, позволяют оценить:
    -как часто напряжение или температура выходит за заданные пределы
    • как долго длится каждое отклонение.
  • какова величина максимального отклонения за период архивации

Дополнительно прикладываются фотографии:
-внешний вид приёмника;
-внешний вид передатчика;

  • внешний вид датчика напряжения

  • распечатка записанного архива напряжений.

  • схема и скетч программы передатчика

  • схема и скетч программы приёмника
    Эти материалы можно скачать
    с Яндекс диска по адресу 2655. регистратор (2).zip — Яндекс.Диск

    Фоменко Геннадий Фёдорович

e-mail:gfomenko1@mail.ru

1 лайк

не пойдет :slight_smile:
у меня от дома до середины поля с картошкой метров 150, как же я буду следить за самогонным аппаратом :frowning:

полный комплект документации со скетчами, чертежами, фотографиями находится на яндекс диске по адресу 2655. регистратор (2).zip — Яндекс.Диск**
максимальное расстояние для модулей НС 12 составляет 1000м, поэтому можете спокойно гнать самогон и заодно поделится рецептом. С уважением.

товарищ, во первых есть правила форума, во вторых не у всех есть доступ к яндекс диску (у меня например), ну и просто неуважение к жителям форума - заставлять лазить на какой то дополнительный интернет ресурс.

Да ты её жрёшь штоли?

2 лайка

памойму, тему можно сносить в мусорку. Коль у тебя исходники все на яндексе, дак и пиши в Дзене, а не здесь.

По-моему это спам.

1 лайк

Да)))

#include <SoftwareSerial.h>//приёмник установлен в доме №38
SoftwareSerial HC12(10, 11); // HC-12 TX Pin10, HC-12 RX Pin11
#include <Wire.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <iarduino_RTC.h>//SDA подключаем к А4, SCL подключаем к А5
#define xAddr 0x50 // определяет базовый адрес внешней EEPROM
iarduino_RTC time(RTC_DS3231);
LiquidCrystal_I2C lcd(0x27,20,4); // Задаем адрес и размер дисплея
byte Trev = 12;//включение зуммера сигнала тревоги
byte Rej = 3;//Rej=1 - кнопка режима работы с реле, Rej=0 - режим измерения температуры и напряжения
byte R1 = 4;//тумблер выбора реле 1 (R = 1) - включить реле. (R = 0) - отключить реле
byte R2 = 5;//тумблер выбора реле 2
byte R3 = 6;// тумблер выбора реле 3
byte R4 = 7;// тумблер выбора реле 4
byte P = 9;//подтверждение успешного переключения реле в модуле передатчика
char Buf1[16];//массив для записи во внешнюю память даты и времени Tmax за архивируемый период
char Buf2[16];//массив для записи во внешнюю память даты и времени Tmin за архивируемый период
char Buf3[16];//массив для записи во внешнюю память даты и времени Vmax за архивируемый период
char Buf4[16];//массив для записи во внешнюю память даты и времени Vmin за архивируемый период
byte Mig = 8;//мигающий зелёный светодиод, показывающий нормальную работу программы
String str1,str2,str3,str4,str5,str6,stra,strb,strc,strd,stra1,strd1;

byte t;//переменная для выбора исполнительного реле или программного модуля
byte a1 = 1;//разрешение режима мониторинга по условию if((v > v1)||(v < v2))
byte b1 = 0;//запрет режима мониторинга по условию if((v < v3)&& (v>v4))
byte c1 = 1;//разрешение режима мониторинга по условию if((w > w1)|| (w < w2))
byte d1 = 0;//запрет режима мониторинга по условию if((w < w3)&&(w > w4))
byte v1 = 225;//максимально допустимое напряжение
byte v2 = 210;//минимально допустимое напряжение
byte v3 = 223;//напряжение гистерезиса для v1
byte v4 = 211;//напряжение гистерезиса для v2
byte a2;//признак записи архива напряжений
byte a3;//признак записи архива температур
float w1 = 24.00;//максимально допустимая температура
float w2 = 18.00;//минимально допустимая температура
float w3 = 23.30;//температура гистерезиса для w1
float w4 = 18.40;//температура гистерезиса для w2
unsigned int adr1 = 0;
unsigned int eepromAdd = 0;//начальный адрес записи архива в AT24C256
unsigned int adr5 = 0;//конечный адрес архива

void setup()
{
Serial.begin(1200);// Serial port to computer
HC12.begin(1200);// Serial port to HC12
lcd.init(); // Инициализация lcd
lcd.backlight(); // Включаем подсветку
time.begin();
Wire.begin();
//time.settime(0,20,12,02,02,23,4); // 0 сек, 07 мин, 17 час, 25, января, 2023 года,среда(установка начальной даты и времени)
pinMode(Rej,INPUT_PULLUP);//включение на ввод с подтягивающим резистором к +5В
pinMode(R1,INPUT_PULLUP);
pinMode(R2,INPUT_PULLUP);
pinMode(R3,INPUT_PULLUP);
pinMode(R4,INPUT_PULLUP);
pinMode(Trev,OUTPUT);//вывод на зуммер
pinMode(P,OUTPUT);//вывод на синий светодиод подтверждения выполнения команды ТУ
}

void loop()
{
static float Max1 = 0;//максимальная температура за архивируемый период
static float Min1 = 100;//минимальная температура за архивируемый период
static byte Max2 = 0;//максимальное напряжение за архивируемый период
static byte Min2 = 253;//минимальное напряжение за архивируемый период
float L = -1.81;//константа коррекции сбоев HC12
float L1 = -2.01;//константа коррекции сбоев HC12
float T1;
float V1;
int d;
byte a,b,c,f,k,y,r1,r2,r3,r4,v,s,u,p,p1;
byte i = 1;
byte j = 1;
// byte n,n1;
// String strt = (“**************”);
//char BC[16];
//strt.toCharArray(BC,16);
m2: digitalWrite(Mig,HIGH);//признак работы программмы
delay(1000);
digitalWrite(Mig,LOW);
delay(1000);
a = digitalRead(Rej);//признак режима работы - управление реле (а=1) или измерение температуры и напряжения (а=0)
r1 = digitalRead(R1);
r2 = digitalRead(R2);
r3 = digitalRead(R3);
r4 = digitalRead(R4);
t = ((r4<<3)|(r3<<2)|(r2<<1)|r1);//формируем код команды коммутации реле для передачи в НС12(стробируется кнопкой)
//Serial.println(t);
if(a==1)//управление реле (кнопка нажата)
{
HC12.write(t);//отправляем команду в передатчик (включить или выключить заданные реле)

while (HC12.available()) //ждём от передатчика кода подтверждения о включении или отключении реле
{
 s = HC12.read();//читаем код подтверждения

 if(s==75)digitalWrite(Trev,HIGH);//признак срабатывания сигнализации
 else digitalWrite(Trev,LOW); 
 digitalWrite(P,HIGH);//подтверждение о выполнении команды телеупраления

}
goto m2;
}
if(a == 0)//кнопка не нажата
{
c = 40;//опрос датчиков температуры и напряжения
digitalWrite(P,LOW);//сброс сигнала подтверждения коммутации реле
HC12.write(c);//отправляем в передатчик признак режима работы (c=40) (измерение температуры и напряжения)
while (HC12.available())//ждём ответ передатчика
{
f = HC12.read();//первый байт температуры
k = HC12.read();//второй байт температуры
v = HC12.read();//байт напряжения
d = (k<<8 | f);//объеденяем байты
float z = d;//преобразуем из int во float
float w = z/100;//текущая температура (2 знака после запятой)
if(i == 1)
{
T1 = w;
i = 0;
}
if(abs(w-T1)<6)//устранение сбоев при скачкообразном изменении температуры
T1 = w;
else w = T1;
if(Max1 < w)
{
Max1 = w;
str1 = (time.gettime(“d-m H:i “));//фиксируем время Тмах-день, месяц,часы, минуты
stra = ('”’ + str1 +’ ’ + Max1);//формируем строку
//stra = (str1 +’ ’ + Max1 + ‘+’);//формируем строку
stra.toCharArray(Buf1,16);//преобразуем строку в массив для записи в архив Мах1
}
if((w !=L)&&(w != L1))//устранение сбоев в работе НС12
{
if(Min1 > w)
{
Min1= w;
str2 = (time.gettime(“d-m H:i”));//фиксируем время Тmin (день, месяц, часы, минуты)
strd = ('”’ + str2 +’ ’ + Min1);//формируем строку
//strd = (str2 +’ ’ + Min1 + ‘-’);//формируем строку
strd.toCharArray(Buf2,16);//преобразуем строку в массив для записи в архив Min1
}
}
if((Max2 < v)&&(v!=255))
{
Max2 = v;
str3 = (time.gettime(“d-m H:i:s”));//фиксируем время Vmax (день, месяц,часы, минуты, секунды)
stra1 = (time.gettime(“H:i:s”));//часы,минуты, секунды
stra1 = (‘"’ + stra1 + ’ ’ + Max2 + ‘+’ + ‘"’);
stra1.toCharArray(Buf3,16);//преобразуем строку в массив для записи в архив Max2
//Serial.println(Buf3);
}
if((v !=L)&&(v != L1))
{
if(Min2 > v)
{
Min2= v;
str4 = (time.gettime(“d-m H:i:s”));//фиксируем время Vmin
strd1 = (time.gettime(“H:i:s”));
strd1 = (‘"’ + strd1 + ’ ’ + Min2 + ‘-’ + ‘"’);
strd1.toCharArray(Buf4,16);//преобразуем строку в массив для записи в архив Min2
//Serial.println(Buf4);
}
}
str5 = (time.gettime(“d-M-Y-D”));//выводим день, месяц, год, день недели
str6 = (time.gettime(“H:i:s”));//выодим часы,минуты, секунды
//if((r1==0)&&(r2==0)&&(r3==0)&&(r4==0))
if((t==0)||(t==5)||(t==7))//режим отображения текущей температуры, напряжения,Тмах,Тmin, Vmax, Vmin
{
lcd.setCursor(2,0);
lcd.print(" ");//очищаем строку дисплея
lcd.setCursor(2,0);//первая строка,3 символ
lcd.print("T dom = “);
lcd.print(w,2);// температура, два знака после запятой
lcd.print(char(223));//выводим символ градуса Цельсия
lcd.print(“C”);
lcd.setCursor(2,2);//третья строка
lcd.print(” ");
lcd.setCursor(6,2);
lcd.print("U = “);
lcd.print(v);
lcd.print(“B”);
}
//if((r1==1)&&(r2==0)&&(r3==0)&&(r4==0))
if(t==1)//отображаем время Тмах
{
lcd.setCursor(2,0);
lcd.print(” ");//очищаем строку
lcd.setCursor(3,0);
lcd.print(str1);//отображаем дату и время Тмах
lcd.setCursor(6,2);
lcd.print("U = “);
lcd.print(v);//отображаем текущее значение напряжения
lcd.print(“B”);
}
//if((r1==0)&&(r2==1)&&(r3==0)&&(r4==0))
if(t==2)//отображаем время Тмin
{
lcd.setCursor(2,0);
lcd.print(” “);
lcd.setCursor(3,0);//отображаем дату и время Тмin
lcd.print(str2);
}
//if((r1==0)&&(r2==0)&&(r3==1)&&(r4==0))
if(t==4)//отображаем время Vмах
{
lcd.setCursor(2,2);
lcd.print(” “);
lcd.setCursor(3,2);
lcd.print(str3);//отображаем дату и время Vмах
}
//if((r1==0)&&(r2==0)&&(r3==0)&&(r4==1))
if(t==8)//отображаем время Vmin
{
lcd.setCursor(2,2);
lcd.print(” “);
lcd.setCursor(3,2);
lcd.print(str4);//отображаем дату и время Vмin
}
//if((r1==1)&&(r2==1)&&(r3==0)&&(r4==0))
if(t==3)//режим индикации времени и даты
{
lcd.setCursor(2,0);//первая строка
lcd.print(” “);//очищаем строку
lcd.setCursor(6,0);
lcd.print(str6);//выводим время
lcd.setCursor(0,1);//вторая строка
lcd.print(” “);//очищаем строку
lcd.setCursor(2,1);//вторая строка
lcd.print(str5);//выводим дату
lcd.setCursor(2,2);//третья строка
lcd.print(” ");
lcd.setCursor(6,2);
lcd.print("U = “);
lcd.print(v);//отображаем текущее значение напряжения
lcd.print(“B”);
goto m1;//
}
lcd.setCursor(0,1);//вторая строка
lcd.print(” ");//очищаем строку
lcd.setCursor(0,1);
lcd.print(“Tmax”);
lcd.print(Max1,2);
lcd.setCursor(10,1);//вторая строка
lcd.print(“Tmin”);
lcd.print(Min1,2);
m1: lcd.setCursor(0,3);//четвёртая строка
lcd.print(“Vmax=”);
lcd.print(Max2);
lcd.print(“B”);
lcd.setCursor(10,3);
lcd.print(“Vmin=”);
lcd.print(Min2);
lcd.print(“B”);
while (HC12.available()) // ждём получения от передатчика кода подтверждения о передаче измерения
{
u = HC12.read();
if(u==75)digitalWrite(Trev,HIGH);//признак срабатывания сигнализации
else digitalWrite(Trev,LOW);
//if((r1==1)&&(r3==1))
if(t==5)//входим в режим мониторинга напряжения сети
{
if(adr5 < 30000)//максимально возможный адрес фиксаций напряжения сети
{
if((v > v1)||(v < v2))//напряжение сети вышло за допустимые пределы
{
if(a1==1)//разрешение мониторинга по условию if((v > v1)||(v < v2))
{
strb = (time.gettime(“H:i:s “));//фиксируем время (часы, минуты,секунды)
strc = ('”’ + strb + v +‘B’ + '”');//добавляем к строке величину напряжения и добавляем кавычки
char Buf5[16];//создаём массив для записи строки
strc.toCharArray(Buf5,16);//преобразуем строку в массив
//Serial.println(Buf5);
for(i=0; i<16;i++)
{
writeEEPROM(xAddr, eepromAdd+i,Buf5[i]);//записываем строку во внешнюю память
}
eepromAdd = eepromAdd + 16;
// n = n + 1;
//if(n==4)n = 0;

              a1=0;//запрещаем мониторинг по условию if((v > v1)||(v < v2))
              b1 = 1;//разрешаем мониторинг по условию if((v < v3)&& (v>v4))
              adr5 = eepromAdd;
             
              a2 = 1;//разрешаем запись adr5 в ячейки 31100 и 31101
         }
       }
            
       if((v < v3)&& (v>v4))//напряжение сети вернулось в установленные пределы с заданным гитерезисом
          {
           if(b1==1)
                {
                  strb = (time.gettime("H:i:s "));//фиксируем  время (часы, минуты,секунды)
                  strc = ('"' + strb + v + 'B' + '"');//добавляем к строке величину напряжения и добавляем кавычки
                  char Buf6[16];//создаём массив для записи строки
                  strc.toCharArray(Buf6,16);//преобразуем строку в массив
                  //Serial.println(Buf6);  
                  for(i=0; i<16;i++)
                  {
                    writeEEPROM(xAddr, eepromAdd+i,Buf6[i]);//записываем строку во внешнюю память
                     
                  }
                    eepromAdd = eepromAdd + 16;
                    //n = n + 1;
                    //if(n==4)n = 0;
                    a1 = 1;//разрешаем мониторинг по условию if((v > v1)||(v < v2))
                    b1 = 0;//запрещаем мониторинг по условию if((v < v3)&& (v>v4))
                    adr5 = eepromAdd;
                    a2 = 1;//разрешаем запись adr5 в ячейки 31100 и 31101
                }
          }
     } 
   }
   if((a2==1)&&(t != 5))//запись Vmax, Vmin и конечного адреса архива напряжений в AT24C256 при выходе из режима архивации (t != 5)
   {
            for(i=0; i<16;i++)
                  {
                    writeEEPROM(xAddr, eepromAdd+i,Buf3[i]);//записываем  время и величину Vmax во внешнюю память
                  }
                   eepromAdd = eepromAdd + 16;
                   //n = n + 1;
                   //if(n==4)n = 0;
                   adr5 = eepromAdd;
            for(i=0; i<16;i++)
                  {
                    writeEEPROM(xAddr, eepromAdd+i,Buf4[i]);//записываем величину и время Vmin во внешнюю память
                  }
                    eepromAdd = eepromAdd + 16;
                     
                    
                    adr5 = eepromAdd;
                    byte hi = (int)(adr5 >> 8);//записываем конечный адрес архива во внешнюю память 
                    byte low = (int)(adr5 & 0xFF);
                    writeEEPROM(xAddr, 31100,hi);
                    writeEEPROM(xAddr, 31101,low);
                    a2 = 0;
   }
   
    
    //if((t1==1)&&(t2==1)&&(t3==1))
    if(t==7)//входим в режим мониторинга температуры
      {
    
    
        if(adr5 < 30000)//максимально возможный адрес фиксаций температуры
        {
          if((w > w1)||(w < w2))//температура вышла за допустимые пределы
          {
            if(c1==1)//разрешение мониторинга по условию if((w > w1)||(w < w2))
            {
              strb = (time.gettime("d H:i "));//фиксируем дату и время (день,часы, минуты)
              strc = ('"' + strb + w);//добавляем к строке величину температуры и добавляем кавычки
              char Buf7[16];//создаём массив для записи строки
              strc.toCharArray(Buf7,16);//преобразуем строку в массив
              //Serial.println(Buf7);
              for(i=0; i<16;i++)
              {
                writeEEPROM(xAddr, eepromAdd+i,Buf7[i]);//записываем строку в AT24C256
              }
                eepromAdd = eepromAdd + 16;
            }
                c1=0;//запрещаем мониторинг по условию if((w > w1)||(w < w2))
                d1 = 1;//разрешаем мониторинг по условию if((w < w3)&& (w > w4))
                adr5 = eepromAdd;
                a3 = 1;//разрешаем запись adr5 в ячейки 31100 и 31101
          }
        }
          if((w < w3)&&(w > w4))//температура вернулось в установленные пределы с заданным гиcтерезисом
            {
              if(d1==1)
                {
                  strb = (time.gettime("d H:i "));//фиксируем дату и время (день, часы, минуты)
                  strc = ('"' + strb + w );//добавляем к строке величину температуры и добавляем кавычки
                  char Buf8[16];//создаём массив для записи строки
                  strc.toCharArray(Buf8,16);//преобразуем строку в массив
                  //Serial.println(Buf8);
                  for(i=0; i<16;i++)
                    {
                      writeEEPROM(xAddr, eepromAdd+i,Buf8[i]);//записываем строку в AT24C256
                    }
                      eepromAdd = eepromAdd + 16;
                      d1 = 0;//запрещаем мониторинг по условию if((w < w3)&& (w > w4))
                      c1 = 1;//разрешаем мониторинг по условию if((w > w1)||(w < w2))
                      adr5 = eepromAdd;
                      a3 = 1;//разрешаем запись adr5 в ячейки 31100 и 31101
                }
            }
    } 
  }
          if((a3==1)&&(t != 7))//запись конечного адреса архива температур при выходе из режима архивации (t != 7)
            {
              for(i=0; i<16;i++)
                  {
                    writeEEPROM(xAddr, eepromAdd+i,Buf1[i]);//записываем  дату, время и величину Тmax в AT24C256
                  }
                    eepromAdd = eepromAdd + 16;
                    adr5 = eepromAdd;
              for(i=0; i<16;i++)
                  {
                    writeEEPROM(xAddr, eepromAdd+i,Buf2[i]);//записываем дату, время и величину Тmin в AT24C256
                  }
                   eepromAdd = eepromAdd + 16; 
                   adr5 = eepromAdd;
                   byte hi = (byte)(adr5 >> 8);
                   byte low = (byte)(adr5 & 0xFF);
                   writeEEPROM(xAddr, 31100,hi);
                   writeEEPROM(xAddr, 31101,low);
                   a3 = 0;
            } 
    //if((r2==1)&&(r3==1)) 

if(t==6)//переход в режим чтения записанного архива
{
byte hi = readEEPROM(xAddr, 31100);
byte low = readEEPROM(xAddr, 31101);
adr5 = word(hi,low);//конечный адрес архива
Serial.println(adr5);
eepromAdd = 0;
m3: char c[16]; // переменная для хранения массива из 16 символов
for(i = 0;i<16;i++)
{
c[i] = readEEPROM(xAddr, eepromAdd + i);//read a byte
}

  Serial.println(c); 
  eepromAdd = eepromAdd + 16;
  if(eepromAdd < adr5)
    goto m3;
    else Serial.println("Arxiv  END");
    while(1){}//после чтения архива необходимо выйти из режима чтения архива,
              //отключить и снова включить питание модуля для выхода из бесконечного цикла
               
  }    
 }
}  
 goto m2;

}
//записать байт или один символ - меньше 256
void writeEEPROM(int devAddr, unsigned int eeAddr, byte data )
{
Wire.beginTransmission(devAddr);
Wire.write((int)eeAddr >> 8); //записывает старший байт,
Wire.write((int)eeAddr & 0xFF); //записывает младший значащий байт
Wire.write(data);
Wire.endTransmission();
delay(5); // это нужно обязательно
}

//прочитать байт или одиночный символ - меньше 256
byte readEEPROM(int devAddr, unsigned int eeAddr )
{
byte readByte = 0;
Wire.beginTransmission(devAddr);

Wire.write((int)eeAddr >> 8);//записывает старший байт

Wire.write((int)eeAddr & 0xFF);//записывает младший значащий байт
Wire.endTransmission();
Wire.requestFrom(devAddr,1);
if (Wire.available())
readByte = Wire.read();
return readByte;
}

/*Инструкция по работе с модулем
*1. Назначение модуля
*Модуль обеспечивает выполнение следующих операций:
*1.1 Телеуправление по четырём каналам с помощью реле, коммутирующим нагрузку
*с напряжением до 250 вольт и током до 2-х ампер (активная нагрузка)
*
*1.2 Телесигнализацию по одному каналу от датчиков типа “сухой контакт”.
*срабатывание сигнализации происходит при размыкании контакта с включением зуммера
*
*1.3 Индикацию даты и времени. Индицируется число и название месяца, год, день недели, часы, минуты и секунды
*
*1.4 Измерение температуры в диапазоне от -50℃ до 125℃ с точностью 1%.
*Индицируется:
*- текущая температура
*- максимальная и минимальная измеренная температура с привязкой к дате и времени
*
*1.5 Измерение переменного напряжения 250В, 50Гц
*Индицируется:
*- текущее напряжение
*- максимальное и минимальное напряжение с привязкой к дате времени
*1.6 Мониторинг измеренных значений температуры или напряжения с записью во внешнюю EEPROM типа АТ24С256
При мониторинге отслеживаются момоменты
выхода за заданные пределы и возврата напряжения в заданные пределы.
Эти сведения, накопленные за сутки, позволяют оценить:
-как часто напряжение выходит за заданные пределы

  • как долго длится каждое отклонение
    -абсолютный максимум и минимум напряжения за исследуемый период с привязкой к дате и времени
    При мониторинге обеспечивается:
    -запись величины параметра с привязкой к дате и времени, когда его величина становится больше максимального или меньше
    минимального допустимого значения.
    -запись величины параметра с привязкой к дате и времени, когда его величина возвращается в область
    допустимых значений.
    -просмотр записанного архива в мониторе порта
  1. Устройство модуля
    В состав модуля входят два блока:

2.1 Блок приёмника в составе

  • микроконтроллера Ардуино Нано
  • модуля приёмо-передатчика НС12, обеспечивающего связь с объектом на расстоянии до 200м (прямая видимость)
    на скорости 1200Бод
  • модуля реального времени DS3231
  • жидко-кристаллического дисплея LCD 2004 (4 строки на 20 знакомест каждая строка)
  • адаптера питания 220/9В 1А
  • зуммера звукового сигнала
    -модуля внешней памяти EEPROM типа АТ24С256 (32Кб)
  • 4-х тумблеров, для выбора исполнительных реле и задания режимов работы модуля
  • кнопки активации команды телеуправления
  • зелёный светодиод, индицирующий нормалбную работу модуля
  • синий светодиод, индицирующий успешное выполнение команды телеуправления

2.2 Блок передатчика в составе:

  • микроконтроллера Ардуино Нано
  • модуля приёмо-передатчика НС12, обеспечивающего связь с объектом на расстоянии до 200м (прямая видимость)
    на скорости 1200Бод
  • датчика температуры (терморезистор NTC 10кОм при 25 градусах Цельсия)
  • блока реле из 4-х исполнительных реле
  • адаптера питания 220/9В 1А
  • датчика переменного напяжения типа ZMPT101B
  • стабилизатора 9/5В для питания обмоток реле
  • 4-х красных светодиодов, индицирующих включённое состояние реле
  1. Телеуправление
    Устройство обеспечивает дистанционное включение или отключение 4-х объектов.
    Для управления необходимо с помощью 4-х тумблеров на блоке приёмника задать
    необходимую управляющую комбинацию.
    При этом положение тумблера в 1 соответствует включению реле, а положение 0 отключает реле.
    После набора командной комбинации тумблеров нажимаем кнопку и держим её нажатой до
    получения сигнала подтверждения от передатчика - горит синий светодиод.
    Отпускаем кнопку и ставим все тумблеры в положение 0.

  2. Перевод приёмника в режим индикации даты и времени
    Устанавливаем тумблеры 1 и 2 в положение 1
    В первой строке дисплея индицируется время (часы, минуты, секунды)
    Во второй строке дисплея индицируется дата (число, месяц, год, день недели)
    В третьей строке дисплея индицируется текущее значение напряжения.
    В четвёртой строке дисплея индицируется максимальное и минимальное значение напряжения.
    Для выхода из этого режима надо установить тумблеры 1 и 2 в положение 0.

  3. Перевод приёмника в режим индикации даты и времени Тмах
    Устанавливаем тумблер 1 в положение 1
    В первой строке дисплея индицируется дата и время Тмах
    Для выхода из этого режима надо установить тумблер 1 в положение 0.

  4. Перевод приёмника в режим индикации даты и времени Тmin
    Устанавливаем тумблер 2 в положение 1
    В первой строке дисплея индицируется дата и время Тmin
    Для выхода из этого режима надо установить тумблер 2 в положение 0.

  5. Перевод приёмника в режим индикации даты и времени Vmax
    Устанавливаем тумблер 3 в положение 1
    В третьей строке дисплея индицируется дата и время Vmax
    Для выхода из этого режима надо установить тумблер 3 в положение 0.

  6. Перевод приёмника в режим индикации даты и времени Vmin
    Устанавливаем тумблер 4 в положение 1
    В третьей строке дисплея индицируется дата и время Vmin
    Для выхода из этого режима надо установить тумблер 4 в положение 0.

  7. Перевод приёмника в режим мониторинга сетевого напряжения.
    Предварительно необходимо задать следующие параметры мониторинга:

  • максимально допустимое значение сетевого напряжения v1 (по умолчанию 230В)
  • минимально допустимое значение сетевого напряжения v2 (по умолчанию 210В)
  • напряжение гистерезиса v3 для v1 (по умолчанию 229В)
  • напряжение гистерезиса v4 для v2 (по умолчанию 211В)
    Устанавливаем тумблеры 1 и 3 в положение 1
    Включаем питание приемника.
    Для выхода из режима мониторинга напряжения сети необходимо:
    Установить тумблеры 1 и 3 в положение 0
    Переходим в режим просмотра архива из памяти EEPROM Ардуино (см.п.11)

10.Перевод приёмника в режим мониторинга температуры.
Предварительно необходимо задать следующие параметры мониторинга:

  • максимально допустимое значение температуры w1 (по умолчанию 24 гр С)
  • минимально допустимое значение температуры w2 (по умолчанию 18 гр С)
  • температура гистерезиса w3 для w1 (по умолчанию 23.30 гр С)
  • температура гистерезиса w4 для w2 (по умолчанию 18.40 гр С)
    Устанавливаем тумблеры 1, 2 и 3 в положение 1
    Включаем питание приемника.
    Для выхода из режима мониторинга температуры необходимо:
    Устанавливаем в положение 0 сначала тумблер 3, а затем 1 и 2
    Переходим в режим просмотра архива из памяти EEPROM Ардуино (см.п.11)

11.Режим просмотра архива

Внимание!!!
В этом режиме питание приёмника должно осуществляться только от
компьютера по кабелю USB. (Потребление приёмника в этом режиме 100 мА.
Скорость обмена с монитором порта должна быть установлена 1200 Бод.
Отключаем приёмник от адаптера питания
Устанавливаем тумблеры 2 и 3 в положение 1
Подключаем приёмник кабелем USB к компьютеру
Открываем монитор порта и ждём вывода архива на экран
Делаем скрин-шот экрана и распечатываем его
В предпоследней строчке архива выводится дата и время Тмах или Vmax за период регистрации архива
В последней строчке архива выводится дата и время Тmin или Vmin за период регистрации архива
Отключаем приёмник от компьютера
Устанавливаем тумблеры 2 и 3 в положение 0
Подаем питание на приёмник от адаптера

12.Режим телесигнализации
Телесигнализация осуществляется путём подключения контактов датчика сигнализации
ко входу сигнализации на блоке приёмника.
При размыкании контактов датчика передатчик передаёт в приёмник сигнал тревоги
и включается зуммер в приёмнике.
Зуммер можно отключать переключателем, расположенным рядом с зуммером.

13.Замена батареи в модуле DS3231
При замене батареи типа CR2032 (3V) в модуле DS3231 необходимо произвести
начальную установку времени.
Для этого необходимо в секции setup приёмника раскомментировать строку
//time.settime(0,10,17,25,01,23,3); // 0 сек, 10 мин, 17 час, 25, января, 2023 года,среда
записать в неё текущую дату и время, скомпелировать и загрузить программу.
Затем снова закомментировать эту строку и снова скомпелировать и загрузить программу.

*/
#include <SoftwareSerial.h>//передатчик установлен в доме №39(окончательная версия)
SoftwareSerial HC12(10, 11); // HC-12 TX Pin10, HC-12 RX Pin11
#include <GyverNTC.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // Задаем адрес и размер дисплея
GyverNTC therm(1, 10000, 3950); // пин, R термистора при 25 градусах, B термистора. (R резистора по умолч. 10000)
#include “EmonLib.h”
#define VOLT_CAL 277
EnergyMonitor emon1;
byte R1 = 4;//включить(R1 = 1) - отключить реле1 (R1 = 0)
byte R2 = 5;//включить(R1 = 1) - отключить реле2 (R2 = 0)
byte R3 = 6;//включить(R1 = 1) - отключить реле3 (R3 = 0)
byte R4 = 7;//включить(R1 = 1) - отключить реле4 (R4 = 0)
byte Sign = 9;//вход срабатывания сигнализации
byte s = 55;//код подтверждения выполнения запроса телеуправления
byte h = 65;//код подтверждения передачи температуры
byte Trev = 75;//код срабатывания сигнализации
float T1;//температура с датчикa NTC
float V1;//напряжение с датчика ZMPT
byte Mig = 8;//мигающий светодиод

void setup()
{
Serial.begin(1200); // Serial port to computer
HC12.begin(1200); // Serial port to HC12
lcd.init(); // Инициализация lcd
lcd.backlight(); // Включаем подсветку
emon1.voltage(0, VOLT_CAL, 1.7); //Напряжение: входной контакт, калибровка, фазовый сдвиг
pinMode(R1,OUTPUT);
pinMode(R2,OUTPUT);
pinMode(R3,OUTPUT);
pinMode(R4,OUTPUT);
pinMode(Sign,INPUT_PULLUP);//включение на ввод с подтягивающим резистором к +5В
pinMode(Mig,OUTPUT);
}

void loop()
{
byte y,r1,r2,r3,r4;//номера коммутируемых реле
byte c;//признак режима работы
byte Tr = digitalRead(Sign);//вход сигнализации
m2: while (HC12.available()) //ждём запрос от приёмника
{
c = HC12.read();
//Serial.println(c);
if((c!=40)&&(c<16))//выбран режим управления реле
{
r1 = c & B00000001;
r2 = c & B00000010;
r3 = c & B00000100;
r4 = c & B00001000;
if(r1 == 1)digitalWrite(R1,HIGH);
else digitalWrite(R1,LOW);
if(r2 == 2)digitalWrite(R2,HIGH);
else digitalWrite(R2,LOW);
if(r3 == 4)digitalWrite(R3,HIGH);
else digitalWrite(R3,LOW);
if(r4 == 8)digitalWrite(R4,HIGH);
else digitalWrite(R4,LOW);
if(Tr == 1)HC12.write(Trev);//посылаем в приёмник сигнал тревоги 75
else HC12.write(s);//посылаем код подтверждения 55
goto m2;
}
if(c==40)//если выбран режим измерения температуры и напряжения
{
T1 = (therm.getTempAverage());
emon1.calcVI(20,2000); //рассчитать все. Количество полудлин волн (пересечений), тайм-аут
V1 = (emon1.Vrms); //извлечь Vrms в переменную
V1 = V1 -14;//коррекция показаний датчика
lcd.setCursor(0,0);//первая строка,первый символ
lcd.print("T dom ");
lcd.print(T1);
lcd.print(char(223));//выводим символ градуса Цельсия
lcd.print(“C”);
lcd.setCursor(0,1);
lcd.print(“U = “);
lcd.print(V1,0 );
lcd.print(” V”);
float y = T1*100;//избавляемся от запятой
int a = (int)(y);//меняем тип переменной с float на int
byte b =(byte)(a & 0xff);//младший байт температуры
HC12.write(b);//передаём младший байт;
//Serial.println(b);
byte c = (byte)(a>>8);//старший байт температуры
//Serial.println(c);
HC12.write(c);//передаём старший байт
int V = (int)V1;
byte v =(byte)(V & 0xff);
HC12.write(v);
if(Tr == 1)HC12.write(Trev);//посылаем в приёмник сигнал тревоги 75
else HC12.write(h);//посылаем код подтверждения 65
//Serial.println(h);
goto m2;
}
}
}

Вставка кода три обратных апострофа ``` до и после кода

Тест на IQ провален полностью.
По этой причине перемещаю в ЧЧ.

1 лайк

По инструкции - вещь мощная, а по исходникам - школотронство.

2 лайка

Практика - критерий истины. Это устройство работает у меня уже несколько месяцев и за это время не было никаких глюков. Учитывая, что у меня опыт программирования меньше 1года, я, размещая этот материал, надеялся на поддержку более опытных специалистов, а в ответ получил кучу оскорблений.

Оформи нормально. Код вставь как надо и положим обратно в “Проекты”. Никто тебя не обижает. Ты же сам показываешь неуважение.

В чем это должно было выражаться? “О, зер гут, малатес!!!”? Так это не по адресу, “более опытных специалистов” таким не впечатлить :wink:

1 лайк

Тщеславие ты своё почесать хотел и лавровый венок на голову, но над таким говнокодом в стиле VB можно тока паржать.
Upd. Я, кажецца, понял, почему на этом форуме часто задают вопросы по чужому коду, говоря, что автор не отвечает. Зачастую автор, глядя на такой вот свой код через год просто и сам не может разобраться, где и что надо поменять вопрошающему.

2 лайка

Даже неонки у ей унутре нету… Не говоря уж про думатель.

Вы знаете, мне 75 лет и в таком возрасте человек уже не думает о тщеславии. После окончания МЭИ и до выхода на пенсию, я занимался наладкой электроники АСУ ТП на ТЭС и АЭС.
По жизни сложилось так, что мне очень понадобилось такое устройство. Мои поиски в интернете
не увенчались успехом и все пришлось делать самому. В процессе этой работы я пользовался трудами очень многих людей, которые создавали библиотеки, модули, фрагменты кода, учебники. Поскольку регистратор без глюков выполняет все заложенные функции, я подумал, что это устройство может быть полезным и другим людям, которые не являются такими гуру как вы. Эти люди могут не знать, что такое ООП, указатели, структуры, перечисления, как создавать библиотеки и подпрограммы. Поверьте, если устройство работает нормально, то никого не интересует какой код крутится внутри устройства.
Поэтому у вас очень странная логика - получается, что любой человек, который захочет опубликовать свою работу, стремится к тщеславию. С уважением.

Какая наладка АСУ ТП, если вы не в силах ПРАВИЛЬНО разметить код на форуме !!! Чернобыльскую АЭС не вы чинили ???
Сравните два кода:

setup()
loop()

setup()
loop()
2 лайка