Не правильная работа реле.
- Войдите на сайт для отправки комментариев
Вс, 16/10/2016 - 15:22
Добрый день, форумчане.
требуется подсказка в алгоритме работы реле.
/*Вентиляция ванной комнаты, срабатывающая при выключении света в ванне
с энкодером для изменением времени работы. Индикация
на 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
Помогите!
Дополнительный блок питания параллельный выключателю
Это как? Если блок питания включён параллельно вылючателю, то при замыкании выключателя блок закорачивается?
Давайте схему включения.
Не. В разрыв фазы :) . Тогда он запускается
повесьте на пин 2 и земля кнопку и отрабртайте программу. Сейчас вроде на отжатие кнопки работает.
Не. В разрыв фазы :) . Тогда он запускается
а смысл. тогда идет перезапуск программы. предыдущее значение теряется, да и прерывание не к чему. отсчет вести можно сразу с запуска.
Да в том то и дело, что от земли срабатывает, а от 1 не хочет. Не могу найти косяк. Уже мозги "замылились" :(
сенсор как у вас устроен?
Да не сенсор. Это от предыдущей программы коментарий остался. Просто должна от 1 срабатывать. Эти 5 вольт я подаю с блока питания, который встроил в выключатель света. Минус на землю а плюс на pin2 При выключении света запускается блок питания и дает 1 на pin2. Таймер запускается (должен запускаться)
тогда у вас артефакт
скорее всего надо так
вешать понижающий резистор пин 2 - земля.
но таймер должен запускаться не от пина 2 , а с самого начала.
Нет. Если подтяжку убираю, реле срабатывает и не выключается.
/*Вентиляция ванной комнаты, срабатывающая при выключении света в ванне с энкодером для изменением времени работы. Индикация на 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); // пауза, чтобы сегменты "разгорелись" }Кривовато у вас программа(на мой взгляд )написана. Так и хочется под себя написать. А там и убрать косяки.
Да вроде простенькая, а подиж ты. .
Упростил программу до минимума, но работать не хочет от сигнала на 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"
Упростил программу до минимума, но работать не хочет от сигнала на 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"
Потому, что Вы сами написали:
Ну я упростил еще немножко. Вроде работает.
/* вентилятор -> 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); //выключаем реле }По крайней мере первые 48 дней будет работать.
qwone, ты походу местный троль.... свои баги навязываешь всем и каждому. Учи матчасть, позорище.
qwone, ты походу местный троль.... свои баги навязываешь всем и каждому. Учи матчасть, позорище.
Выпей яду,Сольери.
Упростил программу до минимума, но работать не хочет от сигнала на pin2
Я Вам ещё неделю назад сказал, "давайте схему подключения". Вы же в секретность играете. Давно бы проблема решилась. Но, дело Ваше, если Вам не нужно или Вам нравится заставлять всех на шарах гадать - дело Ваше.
Такая кривая схема что не хочет прикрепляться
Вячеслав, мне уже даже как-то неудобно писать, но это не схема. Вот Вы там написали БП 5В - и куда он подключён? Реле - прекрасно, но куда включена его обмотка, а куда контакты и что там делает питание в 5В? Правильно ли я понимаю по этой "схеме", что одну из линий 220 Вы завели на землю Ардуины? Кроме того, подписи пинов совершенно нечитабельны. Вы нормальную принципиальную схему можете нарисовать?
220в идет на свет в ванне. На контакты выключателя ( параллельно выключателю) запытываю блок питания 5в. При выключении света в ванне, запитывается блок питания и дает 5в на pin2. Реле 5в запитана от Ардуины. Управление реле на pin6. Реле электромеханическое. На контактах цепляется вентилятор 220в Включается таймер 3-5 минут(в скетче 3с,). И до следующего включения светв в ванне, таймер ждет
Так вот и нарисуйте это нормально. Иначе Вам ещё две недели будут пальцем в небо тыкать безо всякого толку.