Не правильная работа реле.

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Добрый день, форумчане.

требуется подсказка в алгоритме работы реле.

/*Вентиляция ванной комнаты, срабатывающая при выключении света в ванне
с энкодером для изменением времени работы. Индикация
на 7-сегментном индикаторе со сдвиговым регистром. Сигнал берем с блока питания (5в) который цепляем
параллельно выключателю в ванне. При выключении света
блок питания запусается
*/
#define relay (8)//цепляем  реле  
#define sens   (2) //  сенсор

//Описываем энкодер:
int val;
int encoder0PinA = 3;// Pin  CLK энкодера
int encoder0PinB = 4;// Pin DT энкодера
int encoder0Pos = 0;
int encoder0PinALast = LOW;
int n = LOW;

//Описываем индикатор 7-сегментный
int latchPin = 6;     // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
int clockPin = 7;    // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
int dataPin = 5;     // Пин "данных" подключен к QH (SDI, DS) входу 74HC595
int TimeLight = 5;    // time для разогрева сегментов

byte SegDisplay;      // Переменная для вывода символов на индикаторе
byte RazrDisplay;     // Переменная для включения разрядов

// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[15] = {
  B11000000, B11111001, B10100100, B10110000, B10011001,   // 0 1 2 3 4
  B10010010, B10000010, B11111000, B10000000, B10010000,   // 5 6 7 8 9
  B01111111, B10111111, B10011100, B10100111,   // ., -, °, С
  B11111111
}; 		                       // all segm.
byte g_registerArray[4] = {1, 2, 4, 8}; //массив цифр, указывающий разряды
char pos[4] = {14, 14, 14, 14}; //массив цифр для каждого индикатора
unsigned long time;
unsigned long currentTime;
unsigned long loopTime;
bool b = 0;
//Переменные для внешнего прерывания реле
volatile byte flag = 0;
unsigned long prevmillis;

void setup() {
  //Объявляем режимы брызгалки
  pinMode(2, INPUT_PULLUP);//Дата сенсора
  pinMode(8, OUTPUT);//Дата реле
  digitalWrite(relay, HIGH); //включаем реле
  //Объявляем режимы пинов энкодера
  pinMode (encoder0PinA, INPUT);
  pinMode (encoder0PinB, INPUT);
  Serial.begin (9600);
  // pin 4-х битного индикатора
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  currentTime = millis();       //  время, прошедшее с момента запуска программы
  loopTime = currentTime;
  attachInterrupt(0, my_func, RISING); //прерывание  с LOW на HIGH когда выкл. выключен
  //attachInterrupt(0, my_func, FALLING);
  //attachInterrupt(0, my_func, HIGH);
}

void loop() {
  //читаем энкодер
  n = digitalRead(encoder0PinA);
  if ((encoder0PinALast == LOW) && (n == HIGH)) {
    if (digitalRead(encoder0PinB) == LOW) {
      encoder0Pos--;
    } else {
      encoder0Pos++;
    }
    //выводим в сериал данные энкодера и на дисплей
    Serial.print (encoder0Pos);
    Indicate(3, 14);
    if (b ^= 1)

      pos[0] = 13;
    pos[1] = encoder0Pos % 10 ;
    pos[2] = encoder0Pos / 10;
    pos[3] = 14;

  }
  encoder0PinALast = n;

  //Работа реле
  if (1 == flag)
  { // пришел сигнал на сработку (5в)
    prevmillis = millis();

    digitalWrite(relay, LOW); //включаем реле
    flag = 2;
  }

  if (2 == flag)
  {
    if ( millis() - prevmillis >= encoder0Pos * 1000)
    { //если счёт n секунд вышел, то
      
      digitalWrite(relay, HIGH); //отключаем реле
      flag = 0; //сбрасываем флаг работы
    }
  }
  for (int i = 0; i < 4; i++) Indicate(i, pos[i]);
}


void my_func() { //отжали
  flag = 1; //ставим флаг что работа идёт..
}
void Indicate(int r, int x) // Функция собственно, отображения цыфр на индикаторе.
{
  SegDisplay = g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
  RazrDisplay = g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
  digitalWrite(latchPin, LOW);   // устанавливаем синхронизацию "защелки" на LOW
  shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay);  // Записываем информацию для первого регистра (Номер символа)
  shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
  // shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay);  // Записываем информацию для первого регистра (Номер символа)
  digitalWrite(latchPin, HIGH);  //"защелкиваем" регистр, тем самым устанавливая значения на выходах

  delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}



вентиляция должна срабатывать при выключении света в ванне. Дополнительный блок питания параллельный выключателю дает 1 на контроллер. Но прерывание не получается ни с LOW с HIGH ни наоборот, ни на HIGH. Ставлю любой оператор, а всегда срабатывает от LOW

Помогите!

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вячеслав 151 пишет:

Дополнительный блок питания параллельный выключателю 

Это как? Если блок питания включён параллельно вылючателю, то при замыкании выключателя блок закорачивается? 

Давайте схему включения.

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Не.  В разрыв фазы :)  . Тогда он запускается

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

повесьте на пин 2 и земля кнопку и отрабртайте программу. Сейчас вроде на отжатие кнопки работает.

Вячеслав 151 пишет:

Не.  В разрыв фазы :)  . Тогда он запускается

а смысл. тогда идет перезапуск программы. предыдущее значение теряется, да и прерывание не к чему. отсчет вести можно сразу с запуска.

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Да в том то и дело, что от земли срабатывает, а от 1 не хочет. Не могу найти косяк. Уже мозги "замылились"  :(

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

сенсор как у вас устроен?

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Да не сенсор. Это от предыдущей программы коментарий остался. Просто должна от 1 срабатывать. Эти 5 вольт я подаю с блока питания, который встроил в выключатель света.  Минус на землю а  плюс на pin2 При выключении света запускается блок питания и дает 1 на pin2. Таймер запускается (должен запускаться)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

тогда у вас артефакт 

pinMode(2, INPUT_PULLUP);//Дата сенсора

скорее всего надо так

pinMode(2, INPUT);//Дата сенсора 

 

вешать понижающий резистор пин 2 - земля.

но таймер должен запускаться не от пина 2 , а с самого начала.

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Нет. Если подтяжку убираю, реле срабатывает и не выключается.

/*Вентиляция ванной комнаты, срабатывающая при выключении света в ванне
с энкодером для изменением времени работы. Индикация
на 7-сегментном индикаторе со сдвиговым регистром. Сигнал берем с блока питания (5в) который цепляем
параллельно выключателю в ванне. При выключении света
блок питания запусается
*/
#define relay (8)//цепляем  реле  
#define sens   (2) //  сенсор

//Описываем энкодер:
int val;
int encoder0PinA = 3;// Pin  CLK энкодера
int encoder0PinB = 4;// Pin DT энкодера
int encoder0Pos = 0;
int encoder0PinALast = LOW;
int n = LOW;

//Описываем индикатор 7-сегментный
int latchPin = 6;     // Пин "защелки" первого регистра подключен к RCLK (SS, ST_CP) входу
int clockPin = 7;    // Пин "тактовый" подключен к SCLK (CLK, SH_CP) входу 74HC595
int dataPin = 5;     // Пин "данных" подключен к QH (SDI, DS) входу 74HC595
int TimeLight = 5;    // time для разогрева сегментов

byte SegDisplay;      // Переменная для вывода символов на индикаторе
byte RazrDisplay;     // Переменная для включения разрядов

// Настройка комбинации для отображения каждого номера на индикаторе
// Массив цифр, генерирующий на сегментах цифры в двоичной системе исчисления
byte g_digits[15] = {
  B11000000, B11111001, B10100100, B10110000, B10011001,   // 0 1 2 3 4
  B10010010, B10000010, B11111000, B10000000, B10010000,   // 5 6 7 8 9
  B01111111, B10111111, B10011100, B10100111,   // ., -, °, С
  B11111111
}; 		                       // all segm.
byte g_registerArray[4] = {1, 2, 4, 8}; //массив цифр, указывающий разряды
char pos[4] = {14, 14, 14, 14}; //массив цифр для каждого индикатора
unsigned long time;
unsigned long currentTime;
unsigned long loopTime;
bool b = 0;
//Переменные для внешнего прерывания реле
volatile byte flag = 0;
unsigned long prevmillis;

void setup() {
  //Объявляем режимы брызгалки
  pinMode(2, INPUT_PULLUP);//+5в на сработку.
  //pinMode(2, INPUT);//+5в на сработку.
  pinMode(8, OUTPUT);//Дата реле
  digitalWrite(relay, HIGH); //включаем реле инверторное
  //Объявляем режимы пинов энкодера
  pinMode (encoder0PinA, INPUT);
  pinMode (encoder0PinB, INPUT);
  Serial.begin (9600);
  // pin 4-х битного индикатора
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  currentTime = millis();       //  время, прошедшее с момента запуска программы
  loopTime = currentTime;
  attachInterrupt(0, my_func, RISING); //прерывание  с LOW на HIGH когда выкл. выключен
  //attachInterrupt(0, my_func, FALLING);
  //attachInterrupt(0, my_func, HIGH);
}

void loop() {
  //читаем энкодер
  n = digitalRead(encoder0PinA);
  if ((encoder0PinALast == LOW) && (n == HIGH)) {
    if (digitalRead(encoder0PinB) == LOW) {
      encoder0Pos--;
    } else {
      encoder0Pos++;
    }
    //выводим в сериал данные энкодера и на дисплей
    Serial.print (encoder0Pos);
    Indicate(3, 14);
    if (b ^= 1)

      pos[0] = 13;
    pos[1] = encoder0Pos % 10 ;
    pos[2] = encoder0Pos / 10;
    pos[3] = 14;

  }
  encoder0PinALast = n;

  //Работа реле
  if (1 == flag)
  { // пришел сигнал на сработку (5в)
    prevmillis = millis();

    digitalWrite(relay, LOW); //включаем реле
    flag = 2;
  }

  if (2 == flag)
  {
    if ( millis() - prevmillis >= encoder0Pos * 1000)
    { //если счёт n секунд вышел, то

      digitalWrite(relay, HIGH); //отключаем реле
      flag = 0; //сбрасываем флаг работы
    }
  }
  for (int i = 0; i < 4; i++) Indicate(i, pos[i]);
}


void my_func() { //
  flag = 1; //ставим флаг что работа идёт..
}
void Indicate(int r, int x) // Функция собственно, отображения цыфр на индикаторе.
{
  SegDisplay = g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
  RazrDisplay = g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
  digitalWrite(latchPin, LOW);   // устанавливаем синхронизацию "защелки" на LOW
  shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay);  // Записываем информацию для первого регистра (Номер символа)
  shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
  // shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay);  // Записываем информацию для первого регистра (Номер символа)
  digitalWrite(latchPin, HIGH);  //"защелкиваем" регистр, тем самым устанавливая значения на выходах

  delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}


 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Кривовато у вас программа(на мой взгляд )написана. Так и хочется под себя написать. А там и убрать косяки.

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Да вроде простенькая, а подиж ты. .

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Упростил программу до минимума, но работать не хочет от сигнала на pin2


//Вентилятор для ванны. При выключении света, запитывается б/п 5в
//этот сигнал даем на pin2 

#define button 2    // сигнал с вылючателя 
#define relay  6    // реле  с HIGH в молчании.

int  flag = 0;

void setup()
{
  pinMode(button, INPUT_PULLUP);   // управляющий сигнал на вход  вкл.подтягивающий резистор.
  pinMode(relay, OUTPUT);          // режим реле на вентилятор
}

void loop()
{
  if (digitalRead(2) == HIGH && flag == 0)
  { // выключили свет и пошло питание от б/п
    digitalWrite(relay, HIGH);
    flag = 1;
    delay(3000);//время работы вентилятора
    digitalWrite(relay, LOW); //включаем реле
  }
  if (digitalRead(2) == LOW)//когда включается свет в ванне
  //б/п 5в выключается ставим флаг=0
  {
    flag = 0;
  }

}

почему то реле срабатывает только от "0"

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Вячеслав 151 пишет:

Упростил программу до минимума, но работать не хочет от сигнала на pin2


//Вентилятор для ванны. При выключении света, запитывается б/п 5в
//этот сигнал даем на pin2 

#define button 2    // сигнал с вылючателя 
#define relay  6    // реле  с HIGH в молчании.

int  flag = 0;

void setup()
{
  pinMode(button, INPUT_PULLUP);   // управляющий сигнал на вход  вкл.подтягивающий резистор.
  pinMode(relay, OUTPUT);          // режим реле на вентилятор
}

void loop()
{
  if (digitalRead(2) == HIGH && flag == 0)
  { // выключили свет и пошло питание от б/п
    digitalWrite(relay, HIGH);
    flag = 1;
    delay(3000);//время работы вентилятора
    digitalWrite(relay, LOW); //включаем реле
  }
  if (digitalRead(2) == LOW)//когда включается свет в ванне
  //б/п 5в выключается ставим флаг=0
  {
    flag = 0;
  }

}

почему то реле срабатывает только от "0"

Потому, что Вы сами написали:

if (digitalRead(2) == HIGH && flag == 0)
qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну я упростил еще немножко. Вроде работает.

/*
вентилятор -> 6 (Fan_pin)
*/
const int Fan_pin = 6; // пин вентелятора
uint8_t Fan;// состояние вентилятора
const int time_OFF = 3000; // время отключения 3 секунды=3000миллисекунд
uint8_t past;

void setup() {
  pinMode(Fan_pin, OUTPUT);
  digitalWrite(Fan_pin, Fan = 1); //включаем реле
  past = millis();
}

void loop() {
  if (Fan&&(millis() >= past + time_OFF))
    digitalWrite(Fan_pin, Fan = 0); //выключаем реле
}

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

qwone пишет:
Вроде работает.

По крайней мере первые 48 дней будет работать.

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Andy пишет:

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

Выпей яду,Сольери.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вячеслав 151 пишет:

Упростил программу до минимума, но работать не хочет от сигнала на pin2

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

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Такая кривая схема что не хочет прикрепляться 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вячеслав, мне уже даже как-то неудобно писать, но это не схема. Вот Вы там написали БП 5В - и куда он подключён? Реле - прекрасно, но куда включена его обмотка, а куда контакты и что там делает питание в 5В? Правильно ли я понимаю по этой "схеме", что одну из линий 220 Вы завели на землю Ардуины? Кроме того, подписи пинов совершенно нечитабельны. Вы нормальную принципиальную схему можете нарисовать?

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

220в идет на свет в ванне. На контакты выключателя ( параллельно выключателю) запытываю блок питания 5в. При выключении света в ванне, запитывается блок питания и дает 5в на pin2. Реле 5в запитана от Ардуины. Управление реле на pin6. Реле электромеханическое. На контактах цепляется вентилятор 220в  Включается таймер 3-5 минут(в скетче 3с,). И до следующего включения светв в ванне, таймер ждет

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так вот и нарисуйте это нормально. Иначе Вам ещё две недели будут пальцем в небо тыкать безо всякого толку.