Делаю подсветку в коридор
- Войдите на сайт для отправки комментариев
Сб, 31/12/2016 - 21:37
Здравствуйте! Хочу сделать подсветку в коридор. Выключатели расположены крайне неудобно и постоянно приходится идти на ощупь
Нашёл в интернете код который при срабатывании датчика движения сравнивает состояние входа АЦП от фоторезистора и если всё ОК то включает реле на заданное время к примеру 5 сек. По истечению этого времени проверяется состояние входа от PIR датчика и если есть движение то - повтор заданного времени работы. В принципе всё отлично, но как то скучно. Моих познаний хватило лишь на добавление нескольких каналов на выход, последовательное их включение/выключение и начальная яркость пока выбрана -100 (потом подберу более оптимальну).
Нашёл в интернете код который при срабатывании датчика движения сравнивает состояние входа АЦП от фоторезистора и если всё ОК то включает реле на заданное время к примеру 5 сек. По истечению этого времени проверяется состояние входа от PIR датчика и если есть движение то - повтор заданного времени работы. В принципе всё отлично, но как то скучно. Моих познаний хватило лишь на добавление нескольких каналов на выход, последовательное их включение/выключение и начальная яркость пока выбрана -100 (потом подберу более оптимальну).
Помогите пожалуйста добавить ещё один функционал.
В основном мы просто пересекаем коридор и редко когда нужен полный накал свечения ламп/лед лент, поэтому было бы не плохо что бы ленты загорались к примеру в пол накала, а если задержались то после повторной проверки присутствия разгорались бы так же последовательно уже на полную мощность.
int const Pot = A5; //Потенцинометр 10к:
int const Light = A7; //Датчик света:
int const Led1 = 4;
int const Led2 = 5;
int const Led3 = 9;
int const Led4 = 10;
int const Pirsens = 3; // Цифровой датчик движения:
int const pause = 5000; // время работы 5 сек.
long unsigned int lowIn;
boolean lockLow = true;
boolean takeLowTime;
void setup() {
// Определяем входы и выходы:
pinMode(Pirsens, INPUT);
pinMode(Led1, OUTPUT);
pinMode(Led2, OUTPUT);
pinMode(Led3, OUTPUT);
pinMode(Led4, OUTPUT);
// определяем состояние:
digitalWrite(Led1, HIGH);
digitalWrite(Led2, HIGH);
digitalWrite(Led3, HIGH);
digitalWrite(Led4, HIGH);
}
void loop() {
int pirsensVal = digitalRead(Pirsens);
int lightVal = analogRead(Light);
int potVal = analogRead(Pot);
int lightLimit = map(potVal, 0, 1023, 200, 500);
if (pirsensVal == HIGH && lightVal < lightLimit) {
if (lockLow) {
lockLow = false;
analogWrite(Led1, 100);
delay(100);
analogWrite(Led2, 100);
delay(100);
analogWrite(Led3, 100);
delay(100);
analogWrite(Led4, 100);
delay(100);
}
takeLowTime = true;
} else {
if (takeLowTime) {
lowIn = millis();
takeLowTime = false;
}
if (!lockLow && millis() - lowIn > pause) {
lockLow = true;
digitalWrite(Led1, HIGH);
delay (100);
digitalWrite(Led2, HIGH);
delay (100);
digitalWrite(Led3, HIGH);
delay (100);
digitalWrite(Led4, HIGH);
}
}
}
Код написал но не проверял
/*viktor001.ino #1 датчик движения ->3 (Pirsens_pin) 1 есть движение / нет Датчик света -> A7 (Light_pin) опред дня/ночи потенциометр -> A5 (Pot_pin) задает с какого уровня нужна подсветка #2 светодиод 1 -> 4 (Led1_pin) 1 погашено/ аналог горит по уровню светодиод 2 -> 5 (Led1_pin) светодиод 3 -> 6 (Led1_pin) светодиод 4 -> 7 (Led1_pin) */ //#1 const int Pirsens_pin = 3; // Цифровой датчик движения: int Pirsens; const int Light_pin = A7; //Датчик света: const int Pot_pin = A5; //Потенцинометр 10к: //#2 const int Led1_pin = 4; // управление яркостью с помощью ШИМ int Led1;// 0 - горит / 1 горит в полнакала / 2 горит полностью const int Led1_time = 0; // время задержи зажигания //#3 const int Led2_pin = 5; int Led2;// 0 - горит / 1 горит в полнакала / 2 горит полностью const int Led2_time = 0; // время задержи зажигания //#4 const int Led3_pin = 9; int Led3;// 0 - горит / 1 горит в полнакала / 2 горит полностью const int Led3_time = 0; // время задержи зажигания //#5 const int Led4_pin = 10; int Led4;// 0 - горит / 1 горит в полнакала / 2 горит полностью const int Led4_time = 300; // время задержи зажигания void Out_Led(int Led_pin, int Led) { // фунция зажеч с нужным уровнем const int light0 = 0; // уровень не горит const int light50 = 100; // уровень горит 50% const int light100 = 255; // уровень горит 100% switch (Led) { case 0: analogWrite(Led1_pin, light0); break; case 2: analogWrite(Led1_pin, light50); break; default: analogWrite(Led1_pin, light100); } } void setup() { //#1 pinMode(Pirsens_pin, INPUT); //#2 pinMode(Led1_pin, OUTPUT); Out_Led(Led1_pin, Led1 = 0); //#3 pinMode(Led2_pin, OUTPUT); Out_Led(Led2_pin, Led2 = 0); //#4 pinMode(Led3_pin, OUTPUT); Out_Led(Led3_pin, Led3 = 0); //#5 pinMode(Led4_pin, OUTPUT); Out_Led(Led4_pin, Led4 = 0); } void loop() { //#1 Pirsens = digitalRead(Pirsens_pin) && analogRead(Light_pin) < map(analogRead(Pot_pin), 0, 1023, 200, 500); //#2 static uint32_t past_1 = 0 ; if (Led1 = 3 && millis() - past_1 >= 60000) { // 60сек if (! Pirsens) Out_Led(Led1_pin, Led1 = 2); past_1 = millis() ; } if (Led1 = 2 && millis() - past_1 >= 60000) { // 60сек if (Pirsens) Out_Led(Led1_pin, Led1 = 0); else Out_Led(Led1_pin, Led1 = 3); past_1 = millis() ; } if (Led1 = 1 && millis() - past_1 >= 500) {// 0.5 сек Out_Led(Led1_pin, Led1 = 2); past_1 = millis() ; } if (Led1 = 0 && Pirsens) { Led1 = 1; past_1 = millis() ; } //#3 // подобно коду в #2 //#4 // подобно коду в #2 //#5 // подобно коду в #2 }С Новым Годом! Спасибо за помощь, но программа не работает. При включении загораются Led1, 3, и 4. Горят постоянно и никакой реакции на движения.
Ну там ошибки. Надо тестировать на железе. Попробуйте протестировать и разобраться в этом коде. Он рабочий.
/*viktor001_cl.ino #1 кнопка -> 2 (btn1_pin) 0 нажата/ 1 нет #2 светодиод 1 -> 3 (Led1_pin) 1 погашено/ аналог горит по уровню светодиод 2 -> 5 (Led2_pin) светодиод 3 -> 6 (Led3_pin) светодиод 4 -> 9 (Led4_pin) Принцип кода: чем дольше держишь кнопку, тем ярче горят светодиоды(50%,100%) */ class Cl_Led { public: Cl_Led(int _pin, uint32_t _time_1, uint32_t _time_2); void setup(); void loop(int _btn); private: int pin;// нога на светодиод int Led;// величина на светодиоде const int light0 = 0; // уровень не горит const int light50 = 50; // уровень горит 50% const int light100 = 100; // уровень горит 100% void Out_Led(int _Led); uint32_t past_led; uint32_t time_1; // задержка времени вкл light0->light50 и обратно uint32_t time_2; // задержка времени вкл light50->light100 и обратно }; Cl_Led::Cl_Led(int _pin, uint32_t _time_1, uint32_t _time_2) { pin = _pin; time_1 = _time_1; time_2 = _time_2; } void Cl_Led::Out_Led(int _Led) { // функция управ.свет с нужным уровнем switch (Led = _Led) { case 0: analogWrite(pin, light0); break; case 1: analogWrite(pin, light0); break; case 2: analogWrite(pin, light50); break; default: analogWrite(pin, light100); } } void Cl_Led::setup() { past_led = 0; Out_Led(0); } void Cl_Led::loop(int _btn) { if (Led == 3 && millis() - past_led >= time_2) { past_led = millis() ; if ( _btn) Out_Led( 2); } if (Led == 2 && millis() - past_led >= time_2 ) { past_led = millis() ; if (_btn) Out_Led(0); else Out_Led(3); } if (Led == 1 && millis() - past_led >= time_1 ) { past_led = millis() ; Out_Led(2); } if (Led == 0 && ! _btn) { past_led = millis() ; Led = 1; } } //#1 const int btn1_pin = 2; //нога кнопки bool btn1;// инверс сост кнопки 1 нажата /0 нет //#2 const int Led1_pin = 3; // управление яркостью с помощью ШИМ Cl_Led Led1(Led1_pin, 500, 3000); // 0,1 - негорит / 2 горит в полнакала / 3 горит полностью const int Led2_pin = 5; // управление яркостью с помощью ШИМ Cl_Led Led2(Led2_pin, 700, 3000); // 0,1 - негорит / 2 горит в полнакала / 3 горит полностью const int Led3_pin = 6; // управление яркостью с помощью ШИМ Cl_Led Led3(Led3_pin, 1000, 3000); // 0,1 - негорит / 2 горит в полнакала / 3 горит полностью const int Led4_pin = 9; // управление яркостью с помощью ШИМ Cl_Led Led4(Led4_pin, 1500, 3000); // 0,1 - негорит / 2 горит в полнакала / 3 горит полностью void setup() { //#1 pinMode(btn1_pin, INPUT_PULLUP); //#2 Led1.setup(); Led2.setup(); Led3.setup(); Led4.setup(); } void loop() { //#1 btn1 = digitalRead(btn1_pin); //#2 Led1.loop(btn1); Led2.loop(btn1); Led3.loop(btn1); Led4.loop(btn1); }/*viktor001_v2_cl #1 датчик движения ->2 (Pirsens_pin) 1 есть движение / нет Датчик света -> A7 (Light_pin) опред дня/ночи потенциометр -> A5 (Pot_pin) задает с какого уровня нужна подсветка убрана (кнопка -> 2 (btn1_pin) 0 нажата/ 1 нет) #2 светодиод 1 -> 3 (Led1_pin) 1 погашено/ аналог горит по уровню светодиод 2 -> 5 (Led2_pin) светодиод 3 -> 6 (Led3_pin) светодиод 4 -> 9 (Led4_pin) Принцип кода: чем дольше держишь кнопку, тем ярче горят светодиоды(50%,100%) */ class Cl_Led { public: Cl_Led(int _pin, uint32_t _time_1, uint32_t _time_2);//(нога, время 0->50% ,время 50->100% ) void setup(); void loop(int _btn); private: int pin;// нога на светодиод int Led;// величина на светодиоде const int light0 = 0; // уровень не горит const int light50 = 50; // уровень горит 50% const int light100 = 100; // уровень горит 100% void Out_Led(int _Led); uint32_t past_led; uint32_t time_1; // задержка времени вкл light0->light50 и обратно uint32_t time_2; // задержка времени вкл light50->light100 и обратно }; Cl_Led::Cl_Led(int _pin, uint32_t _time_1, uint32_t _time_2) { //(нога, время 0->50% ,время 50->100% ) pin = _pin; time_1 = _time_1; time_2 = _time_2; } void Cl_Led::Out_Led(int _Led) { // функция управ.свет с нужным уровнем switch (Led = _Led) { case 0: analogWrite(pin, light0); break; case 1: analogWrite(pin, light0); break; case 2: analogWrite(pin, light50); break; default: analogWrite(pin, light100); } } void Cl_Led::setup() { past_led = 0; Out_Led(0); } void Cl_Led::loop(int _btn) { if (Led == 3 && millis() - past_led >= time_2) { past_led = millis() ; if ( _btn) Out_Led( 2); } if (Led == 2 && millis() - past_led >= time_2 ) { past_led = millis() ; if (_btn) Out_Led(0); else Out_Led(3); } if (Led == 1 && millis() - past_led >= time_1 ) { past_led = millis() ; Out_Led(2); } if (Led == 0 && ! _btn) { past_led = millis() ; Led = 1; } } //#1 const int Pirsens_pin = 2; // Цифровой датчик движения: bool Pirsens; const int Light_pin = A7; //Датчик света: const int Pot_pin = A5; //Потенцинометр 10к: //const int btn1_pin = 2; //нога кнопки //bool btn1;// инверс сост кнопки 1 нажата /0 нет //#2 const int Led1_pin = 3; // управление яркостью с помощью ШИМ Cl_Led Led1(Led1_pin, 500, 3000); // (нога, время 0->50% ,время 50->100% ) const int Led2_pin = 5; // управление яркостью с помощью ШИМ Cl_Led Led2(Led2_pin, 700, 3000); // (нога, время 0->50% ,время 50->100% ) const int Led3_pin = 6; // управление яркостью с помощью ШИМ Cl_Led Led3(Led3_pin, 1000, 3000); // (нога, время 0->50% ,время 50->100% ) const int Led4_pin = 9; // управление яркостью с помощью ШИМ Cl_Led Led4(Led4_pin, 1500, 3000); //(нога, время 0->50% ,время 50->100% ) void setup() { //#1 pinMode(Pirsens_pin, INPUT); // pinMode(btn1_pin, INPUT_PULLUP); //#2 Led1.setup(); Led2.setup(); Led3.setup(); Led4.setup(); } void loop() { //#1 Pirsens = digitalRead(Pirsens_pin) && analogRead(Light_pin) < map(analogRead(Pot_pin), 0, 1023, 200, 500); // btn1 = digitalRead(btn1_pin); //#2 Led1.loop(! Pirsens); Led2.loop(! Pirsens); Led3.loop(! Pirsens); Led4.loop(! Pirsens); }Светодиоды загораются независимо от освещённости. С циклом примерно три секунды становятся ярче, потом темнее и затем тухнут. Так как датчик движения держит на выходе высокий уровень минимум 5 сек. то заменил в коде время с 3000 на 6000. Теперь разгорается на 6 сек. и если нет движения то гаснет, если есть движение то увеличивается яркость. Затем ждём пока истечёт время и светодиоды должны последовательно потухнуть, но выключение происходит сначала понижением яркости, а потом уж окончательным. Ещё один момент. Повторно активировать включение возможно тольке после паузы. И иногда код ведёт себя крайне не стабильно. Тоесть при явном движении может потухнуть, не отработать некоторые светодиоды.
Светодиоды загораются независимо от освещённости. С циклом примерно три секунды становятся ярче, потом темнее и затем тухнут. Так как датчик движения держит на выходе высокий уровень минимум 5 сек. то заменил в коде время с 3000 на 6000. Теперь разгорается на 6 сек. и если нет движения то гаснет, если есть движение то увеличивается яркость. Затем ждём пока истечёт время и светодиоды должны последовательно потухнуть, но выключение происходит сначала понижением яркости, а потом уж окончательным. Ещё один момент. Повторно активировать включение возможно тольке после паузы. И иногда код ведёт себя крайне не стабильно. Тоесть при явном движении может потухнуть, не отработать некоторые светодиоды.
Думаю, что дело в засветке подсветкой датчика света.
Пишите данные с датчика освещённости в глобальную переменную при обнаружении движения, и НЕ обновляйте её пока подсветка горит.
замените цифры 500,700,1000,1500 на 0 и светодиоды будут реагировать сразу на движение. Или малыми величинами. Большие величины просто делают веселье в подсветке, какое вы и хотели, когда открыли тему.
Да с этими цифрами то всё нормально. Их можно опытным путём подобрать. Проблема в другом. 1) Срабатывает при любом освещении. 2) Если освещение 100% то гаснет сначала на 50% и потом через паузу до 0%. Если бы гасла без паузы то было бы очень замечательно, но так как эта же пауза заявлена и на разгорание то тут просто изменить константы не прокатит. 3) В режиме выключения иногда (чаще всего) 3 и 4 лед гаснут сразу в 0% - выглядит не симпатично. 4) После выключения код выдерживает паузу в 4-5 секунд. Только по истечении этой паузы можно опять активировать включение лед. В практическом применении это совсем плохо, можно оказаться в полной темноте.
Ну так "обрабатывай напильником". У меня нет вашего "железа" , так что практика и еще практика.
на 1- отработайте работу на кнопке. А потом сведите ваши датчики к иммтации работы кнопки.# Замечание нажатие кнопки 0
на 2- так и предусмотрено. 0-50-100-50-0
на 3 там все светодиоды равноцены. А класс даже стирает отличия подностью
на 4 . это вы путаете. то у вас см пунк 2, то смотри пунк 4
ПС: Я выложил эволюцию развития такого скетча(3 варианта). Разбирайтесь сами. Программирование это не только залить "чужой скетч", но и наладка под ваши условия и поиск глюков в чужом скетче. Приехать я к вам лично не смогу, даже если у меня было бы желание.
ПС2: А еще выкрутите ваш пирометр на мин паузу. Это пауза тоже сбивает работу.
Ну здесь мои глюки. Я пишу в своем стиле и под свою концепцию программирования. Не потому что не могу иначе, а потому что надо развивать именно эту. Попробуй разобраться со своим вариантом. Направление я указал, осталась ваша реализация. Может другие предложат другое. Я не возражаю, тем более это ваша тема, а не моя. Да и форум тоже не мой. Я такой же как и вы, приходящий.
Попробуйте такой код. Может его Вам будет проще понять
int const Pot = A5; //Потенцинометр 10к: int const Light = A7; //Датчик света: int const Led1 = 4; int const Led2 = 5; int const Led3 = 9; int const Led4 = 10; int const Pirsens = 3; // Цифровой датчик движения: //int const pause = 5000; // время работы 5 сек. boolean lockLow ; boolean takeLow; uint8_t nakal; void setup() { // Определяем входы и выходы: pinMode(Pirsens, INPUT); pinMode(Led1, OUTPUT); pinMode(Led2, OUTPUT); pinMode(Led3, OUTPUT); pinMode(Led4, OUTPUT); // определяем состояние: digitalWrite(Led1, LOW); digitalWrite(Led2, LOW); digitalWrite(Led3, LOW); digitalWrite(Led4, LOW); //Serial.begin(9600); } unsigned long currentPause[1]; //массив данных. Количество элементов - количеству таймеров bool fl_pause[1];//массив данных. Количество элементов - количеству таймеров //Функция дребезга или паузы boolean my_pausa(unsigned long time, byte nomer) //функция таймер, time-время задержки, nomer-номер таймера { bool x = 0; if (fl_pause[nomer] == 0)currentPause[nomer] = millis(), fl_pause[nomer] = 1; if (millis() - currentPause[nomer] >= time) x = 1, fl_pause[nomer] = 0; return x; } void vklucenie(uint8_t led, uint16_t vel) { analogWrite(led, vel); } void loop() { static bool _lockLow; int pirsensVal = digitalRead(Pirsens); int lightVal = analogRead(Light); int potVal = analogRead(Pot); int lightLimit = map(potVal, 0, 1023, 200, 500); static char var = 1; static char nul = 0; static unsigned char sto = 100; if (pirsensVal == HIGH && lightVal < lightLimit)//Движение, освещенность { if (!lockLow) { lockLow = 1; _lockLow = lockLow; } } else if(pirsensVal == LOW) { if(nakal > 210) lockLow = 0; else if(nakal >= 100)lockLow = 0; } if(lockLow && nakal <= 210) { takeLow=0; if(my_pausa(125, 0)) { switch (var) { case 1: vklucenie(Led1, nakal += 10); if(nakal >= sto)var++, nakal = nul; break; case 2: vklucenie(Led2, nakal += 10); if(nakal >= sto)var++, nakal = nul; break; case 3: vklucenie(Led3, nakal += 10); if(nakal >= sto)var++, nakal = nul; break; case 4: vklucenie(Led4, nakal += 10); if(nakal >= sto) { var = 1; nul= 110; sto=220; } break; } } } else if(lockLow != _lockLow && nakal >= 10) { if(!takeLow) { if(nakal == 100)sto = 0, nul = 100; else if(nakal > 200)sto=110, nul= 220; takeLow=1; } if(my_pausa(125, 0)) { switch (var) { case 1: vklucenie(Led1, nakal -= 10); if(nakal <= sto)var++, nakal = nul; break; case 2: vklucenie(Led2, nakal -= 10); if(nakal <= sto)var++, nakal = nul; break; case 3: vklucenie(Led3, nakal -= 10); if(nakal <= sto)var++, nakal = nul; break; case 4: vklucenie(Led4, nakal -= 10); if(nakal <= sto) { var = 1; nul = 110; sto = 0; } if(nakal == 0)_lockLow = lockLow; break; } } } }