Странности с digitalWrite()

Мужик из полиуретана
Offline
Зарегистрирован: 12.09.2015

Сделал гигростат для увлажнителя влажности, с часами, двумя датчиками температуры\влажности,  дисплеем 1602 и кнопкой для переключения целевой влажности

Реле встроил сразу в розетку удлиннителя, используемого для увлажнителя и подцепил 220В на средний контакт,а контакт от розетки на нормально замкнутый, чтобы удлиннителем, в случае чего, можно было нормально пользоваться и отключив его от ардуины.

По логике должно быть так - 5В на управляющем контакте реле нет - увлажнитель работает, 5В есть - увлажнитель отключается.

Все работает, но один нюанс мне взрывает мозг. Почему-то когда digitalWrite(RELAY, HIGH) - то на управляющем контакте реле 0В, а когда digitalWrite(RELAY, LOW) - то на нем уже 5В.  

Может я чего не понимаю, почему вдруг выход инвентированным стал? %)

Код прилагаю.

// подключаем все библиотеки
#include "DHT.h"                
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <LiquidCrystal.h>

#define RELAY 3        //пин управляющего контакта реле


#define BUTTONPIN 2              // пин кнопки
#define DHTPINa 8                // номер пина первого dht22
#define DHTPINb 9               // номер пина второго dht22


DHT dhta(DHTPINa, DHT22);        // и для dht22
DHT dhtb(DHTPINb, DHT22); 

LiquidCrystal lcd(12, 11, 10, 5, 4, 6, 7);  //подключаем экран

boolean counter_temp = true;               // переменная- счетчик для чередования вывода данных с датчиков
float prevhumydity;                     // переменная предыдущего значения влажности
float targethumydity;                   // переменная целевой влажности

boolean relay_state;                  // переменная состояния реле : true - увлажнитель включен


byte L_kr_lit[8] =               //рисуем нужную кириллицу, буква л
 {
   B00000,
   B00000,
   B01111,
   B00101,
   B00101,
   B10101,
   B01001,
   B00000,
 };

byte Ts_kr_lit[8] =               //рисуем нужную кириллицу, буква л
 {
   B10001,
   B10001,
   B10001,
   B10001,
   B10001,
   B10001,
   B11111,
   B00001,
 };
 

 
byte Arrow_Up[8] =            //рисуем значок градуса и С
 {
   B00100,
   B01110,
   B11111,
   B10101,
   B00100,
   B00100,
   B00100,
   B00000,
 }; 

byte Arrow_Down[8] =            //рисуем значок градуса и С
 {
   B00100,
   B00100,
   B00100,
   B10101,
   B11111,
   B01110,
   B00100,
   B00000,
 }; 
   
byte Cels_kr_lit[8] =            //рисуем значок градуса и С
 {
   B11000,
   B11000,
   B00010,
   B00101,
   B00101,
   B00100,
   B00101,
   B00010,
 }; 


void setup() 
{
  pinMode(BUTTONPIN, OUTPUT);                               // Кнопка и прерывание для нее
  attachInterrupt(0, blink, RISING);

  lcd.createChar(2, L_kr_lit);  // создаем чары для наших нарисованных букв и символов
  lcd.createChar(7, Cels_kr_lit);
  lcd.createChar(3, Arrow_Up);
  lcd.createChar(4, Arrow_Down);
  lcd.createChar(5,Ts_kr_lit);
  lcd.begin(16, 2);             // инициализируем экран
               // при включении обнуляем счетчик записи 

  
  dhta.begin();                 // запускаем оба DHT
  dhtb.begin();

  setSyncProvider(RTC.get);     // и модуль часов
  
   pinMode(RELAY, OUTPUT);         // Управление реле, дефолтом реле включаем
  digitalWrite(RELAY, HIGH);
  relay_state = true;
  prevhumydity = 0.0;
  targethumydity = 30.0;
}

void blink()
{
  targethumydity = targethumydity + 5.0;
   if (targethumydity >= 80.0) targethumydity = 30.0;  //функция кнопки, можно задать влажность от 30 до 75 с шагом в 5%
}


void loop() 
{
  float h1 = dhta.readHumidity();
  float h2 = dhtb.readHumidity();                                                        
  float t1 = dhta.readTemperature();
  float t2 = dhtb.readTemperature();

  if (isnan(h1) || isnan(t1) || isnan(h2) || isnan(t2) ) 
  // на случай если не удалось считать данные с датчика - выдадим моргающее 10 раз сообщение о ошибке
  {
    for (int i=0; i < 10; i++)
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print( "Sensor Error" );
      delay(200);
      lcd.clear();
      delay(200);
    }
  return;
  }
  
  float humydity;                    // переменная для средней влажности
  humydity = ((h1+h2)/2.0);           // получаем и записываем среднюю влажность
 
  int temp;                         // переменная для средней температуры
  temp = ((t1+t2)/2);

  lcd.clear();                      // очистим для начала экран
  lcd.setCursor(0, 0);              // зададим координаты 
  lcd.print( "B:" );        // пишем выводим влажность
  lcd.print((int)humydity);                                         
  lcd.print("%");
  
  if (prevhumydity > humydity) lcd.print("\4");                  // сравниваем, выросла влажность или упала, выводим стрелки или ничего
  if (prevhumydity < humydity) lcd.print("\3");
  if (prevhumydity == humydity) lcd.print(" "); 
                                                             
  lcd.print( "T:" );        // пишем температуру и значок температуры
  lcd.print(temp);                                         
  lcd.print("\7");     
      
  lcd.setCursor(11, 0);             // переходим на вторую строку
  if (hour() < 10)     // для красивого отображения часов и минут меньше 10 (например, не 2:5, а 02:05)
    {lcd.print("0");}
  lcd.print( hour() );              // пишем часы и минуты
  lcd.print( ":" );
  if (minute() < 10)
    {lcd.print("0");}
  lcd.print( minute() );
  
  lcd.setCursor(0, 1); // сразу переходим на вторую строку
  if (counter_temp)
  // в зависимости от счетчика показываем либо влажность первого датчика и меняем счетчик, либо второго и опять меняем счетчик
  {
    counter_temp = false;
    lcd.print( "B1:" );       
    lcd.print((int)h1);
    lcd.print( "% " );                 
  }
  else
  {
    counter_temp = true;
    lcd.print( "B2:" );        // пишем "Темп.:"
    lcd.print((int)h2);
    lcd.print( "% " );              // и наш значок градусов     
  }  
  
  lcd.print( "\5e\2bB:" );        // пишем целевую влажность
  lcd.print((int)targethumydity);
  lcd.print( "%" );     
  
  prevhumydity = humydity;             //обновляем предыдущее значение влажности
  
  if (humydity >= (targethumydity + 2.5))           // если влажность выше целевой на 2.5% - подаем питание на управляющий контакт реле, увлажнитель отключается
  { 
  digitalWrite(RELAY, LOW);
  relay_state = false;
  }
  
  if ( humydity <= (targethumydity - 2.5) && relay_state == false )  // Если ниже целевой на 2.5% и увлажнитель не работает(реле включено) - включаем его
  { 
  digitalWrite(RELAY, HIGH);
  relay_state = true;
  }

  }

P.S. На самом деле зимой в квартире гигростат нафиг не нужен - один увлажнитель (Mystery MAH-2603) - даже если работает сутками в небольшой комнате(16 кв.м.) однокомнатой квартиры, то при открытой двери держит около 40%, при закрытой - около 55%. 

Logik
Offline
Зарегистрирован: 05.08.2014

А Вы реле напрямую к ардуинке вцепили или транзистор какой имеется?

Мужик из полиуретана
Offline
Зарегистрирован: 12.09.2015

Logik пишет:

А Вы реле напрямую к ардуинке вцепили или транзистор какой имеется?

С транзистором конечно,  такой модуль:

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

uragan
Offline
Зарегистрирован: 23.02.2015

Если модуль синего цвета - то у него обратная логика. Прямая у красного.