Автоматическое освещение санузла

Unreal334
Offline
Зарегистрирован: 03.04.2015

Всем доброго дня!
Пытаюсь организовать автоматическое включение и выключение света в туалете.
Использую Arduino Nano, датчик движения, ультразвуковой дальномер (определяет есть ли кто на унитазе), передатчик на 433 МГц управляет верхним светом (радиовыключатель LIVOLO), часы реального времени, MOSFET транзистор (управляет светодиодной подсветкой в темное время суток, в скетче после 21-00), фоторезистор (датчик освещенности).
В программировании не силен, скетч собирал из разных кусков и он работает, все включается и выключается в автоматическом режиме, но если кто-то включит свет вручную то беда.
Надо помощь в описании процедуры проверки освещенности, т.е. если движения нет и на унитазе никого и вне зависимости от времени суток (мало ли кто включил верхний свет ночью) свет (подсветка) выключался, но так, чтобы если я захочу включить свет ночью мог дойти до санузла секунд за 10 (выключатель находится в коридоре)

Также подстраховать включение верхнего света, бывает, что и радиосигнал не с первого раза доходит.

И еще момент: как предусмотреть вариант, когда зашел в туалет в 20-50, а вышел в 21-05, все ли выключится?
Буду очень признателен за помощь.
Скетч ниже.


#include <DS1302.h>
#include <livolo.h>
#define fadePin 6                 //пин управления MOSFET транзистором
Livolo livolo(11);                // Передатчик FS1000A 433 МГц на пин 11
int calibrationTime = 10;//!!!!!         //Время калибровки датчика движения 30 сек (10-60 сек. по даташиту)
long unsigned int lowIn;          //Время, в которое был принят сигнал отсутствия движения(LOW)
long unsigned int pause = 7000;  //Пауза, после которой движение считается оконченным - 7 сек
boolean lockLow = true;           //Флаг. false = значит движение уже обнаружено, true - уже известно, что движения нет
boolean takeLowTime;              //Флаг. Сигнализирует о необходимости запомнить время начала отсутствия движения
  int move = 0;                   //Движение
  int time = 0;
    DS1302 rtc(7, 8, 12);         // Часы
    Time t;
    
  const int pinPhoto = A0;        // Фоторезистор с подтягивающим на А0
  int raw = 0;                    // Освещенность
    int TrigPin = 4;              // Пины 3, 4 ультразвукового дальномера
    int EchoPin = 3;
  int light;                      //переменная для хранения состояния света (вкл/выкл) 
  int pirPin = 2;                 //вывод подключения датчика движения
  int ledPin = 13;
  
void setup()
{
  pinMode(13, OUTPUT);
  pinMode(TrigPin,OUTPUT);
  pinMode(EchoPin,INPUT);
  pinMode(fadePin, OUTPUT);
  digitalWrite(pirPin, LOW);
  pinMode( pinPhoto, INPUT );
  delay(1000);
  
    //калибровка 30 сек
  for(int i = 0; i < calibrationTime; i++)
  {
    //Во время калибровки будет мигать сигнальный диод
    i % 2 ? digitalWrite(ledPin, HIGH) : digitalWrite(ledPin, LOW);
    delay(1000);
  }
  //По окончанию калибровки зажжем сигнальный диод 
  digitalWrite(ledPin, HIGH);
  delay(50);
  
  Serial.begin(9600);  
}

void loop()
{
  move = digitalRead(pirPin);
  raw = analogRead( pinPhoto );
  
  if(raw>=500)
  light = 1;
  
  if(raw<500)
  light = 0;
  delay(50);
  
  t = rtc.getTime();
  delay(50);
  
  int distance,duration;
  digitalWrite(TrigPin,HIGH);
  delayMicroseconds(11);
  digitalWrite(TrigPin,LOW);
  duration = pulseIn(EchoPin, HIGH);
  delay(50);
  




//Верхний свет с 9 до 21
//Если обнаружено движение
  if((digitalRead(pirPin) == HIGH) && (light == 0) && (t.hour >= 9) && (t.hour <= 20))
  {
    //Если до этого момента еще не включили свет
    if(lockLow)
    {
      lockLow = false;      
      //Включаем свет.
      livolo.sendButton(6400, 120); Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LightON");
      delay(50);
    }        
    takeLowTime = true;
  }

  //Ели движения нет
  if((digitalRead(pirPin) == LOW) && (duration > 3000) && (t.hour >= 9) && (t.hour <= 20))
  {      
    //Если время окончания движения еще не записано
    if(takeLowTime)
    {
      lowIn = millis();          //Сохраним время окончания движения
      takeLowTime = false;       //Изменим значения флага, чтобы больше не брать время, пока не будет нового движения
    }
    //Если время без движение превышает паузу => движение окончено
    if((!lockLow && millis() - lowIn > pause) && (light == 1)) //проверяем также освещенность, вдруг кто-то вышел и выключил свет вручную
    { 
      //Изменяем значение флага, чтобы эта часть кода исполнилась лишь раз, до нового движения
      lockLow = true;                
      livolo.sendButton(6400, 120); Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LightOFF");
      delay(50);
    }
  }
  
  
  
  
  
  
//Подсветка с 21 до 9
//Если обнаружено движение
  if((digitalRead(pirPin) == HIGH) && (light == 0) && ((t.hour = 21) || (t.hour = 22) || (t.hour = 23) || (t.hour = 0) || (t.hour = 1) || (t.hour = 2) || (t.hour = 3) || (t.hour = 4) || (t.hour = 5) || (t.hour = 6) || (t.hour = 7) || (t.hour = 8)))
  {
    //Если до этого момента еще не включили подсветку
    if(lockLow)
    {
      lockLow = false;
      //Включаем плавно подсветку.
        for(int i=0; i<=255; i++)
       {
       analogWrite(fadePin, i);
       delay(20);   //каждые 20мс увеличиваем значение на 1
       }
       Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx BackLightOn");
      delay(50);
    }
    takeLowTime = true;
  }

  //Ели движения нет
  if((digitalRead(pirPin) == LOW) && (duration > 3000) && ((t.hour = 21) || (t.hour = 22) || (t.hour = 23) || (t.hour = 0) || (t.hour = 1) || (t.hour = 2) || (t.hour = 3) || (t.hour = 4) || (t.hour = 5) || (t.hour = 6) || (t.hour = 7) || (t.hour = 8)))
  {      
    //Если время окончания движения еще не записано
    if(takeLowTime)
    {
      lowIn = millis();          //Сохраним время окончания движения
      takeLowTime = false;       //Изменим значения флага, чтобы больше не брать время, пока не будет нового движения
    }
    //Если время без движение превышает паузу => движение окончено
    if(!lockLow && millis() - lowIn > pause)
    { 
      //Изменяем значение флага, чтобы эта часть кода исполнилась лишь раз, до нового движения
      lockLow = true;                
      for(int i=255; i>=0; i--)//плавно гасим подсветку
       {
       analogWrite(fadePin, i);
       delay(20);
       } 
       Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx BackLightOff");
       delay(50);
    }
  }





// вывожу в порт для настройки
  Serial.print("Illumination ");
  Serial.print( raw );
  Serial.print("Svet ");
  Serial.println( light );
  
  Serial.print("Move ");
  Serial.print(move);
  Serial.print("Time no Move ");
  Serial.println(lowIn);
  
  Serial.print("Distance ");
  Serial.print(duration);
  Serial.print(" (");
  Serial.print(duration/29/2);
  Serial.println(" cm)");
  
  Serial.print(t.date, DEC);
  Serial.print(" ");
  Serial.print(rtc.getMonthStr());
  Serial.print(" ");
  Serial.print(t.year, DEC);
  Serial.println(".");
  Serial.println(rtc.getDOWStr());
  Serial.print(t.hour, DEC);
  Serial.print(":");
  Serial.print(t.min, DEC);
  Serial.print(":");
  Serial.println(t.sec, DEC);
  delay (500);
  
}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

зачем так сложно?

Ставишь эту штуку куда угодно в зоне 1,5 метров от толчка (можно и внутри стены/потолка, если они не металлические) и все. Нафиг тут Arduino?

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

 у меня это прекрасно работает, есть все регулировки

macros
Offline
Зарегистрирован: 07.11.2016

Tomasina пишет:

Ставишь эту штуку куда угодно в зоне 1,5 метров от толчка (можно и внутри стены/потолка, если они не металлические) и все.

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

macros
Offline
Зарегистрирован: 07.11.2016

knack пишет:

 у меня это прекрасно работает, есть все регулировки

мне эта штука не нравится, нужно периодически двигаться сидя на горшке)

valera678
Offline
Зарегистрирован: 04.11.2016

любопытно а если ультразвуковой дальномер поставить на уровне поясницы...он будет камни в почках колоть пока на горшке сидишь?

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

И генератор сверхнизких частот, что бы всё удачно прошло.

Unreal334
Offline
Зарегистрирован: 03.04.2015

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

Unreal334
Offline
Зарегистрирован: 03.04.2015

macros пишет:

knack пишет:

 у меня это прекрасно работает, есть все регулировки

мне эта штука не нравится, нужно периодически двигаться сидя на горшке)

для этого дальномер и прикрутил

Unreal334
Offline
Зарегистрирован: 03.04.2015

Tomasina пишет:

зачем так сложно?

Ставишь эту штуку куда угодно в зоне 1,5 метров от толчка (можно и внутри стены/потолка, если они не металлические) и все. Нафиг тут Arduino?

я так понимаю это как датчик движения (присутствия), только не PIR, а на радио (может есть где описание на русском, а то не нашел)

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

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Unreal334 пишет:

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

у меня так, ловять чуть ли не из - за угла, хорошие пиры тем более за 35р.

Unreal334
Offline
Зарегистрирован: 03.04.2015

Очень симпатично. А что это? Просто вставка?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

Unreal334
Offline
Зарегистрирован: 03.04.2015
Товарищи, вопрос остается.
Я думаю, что ардуино должен стремиться выключить свет (подсветку), а наличие человека в санузле должно этому препятствовать.
Только я не знаю как описать, чтобы при отсутствии движения (digitalRead(pirPin) == LOW), включенном свете (light == 1), отсутствии человека на унитазе (duration > 3000) в течении, например 10 сек свет (подсветка) выключался.
Если я забиваю в loop строчку
 
if((digitalRead(pirPin) == LOW) && (light == 1) && (duration > 3000))
  {livolo.sendButton(6400, 120); Serial.println("ALLLightOff"); delay(50);}
 
то включая свет вручную, ардуино автоматически его отключает, так как я еще в коридоре и все условия выполняются)
 
Unreal334
Offline
Зарегистрирован: 03.04.2015

ua6em пишет:

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

Это не про моих домашних)

Двери постоянно не закрываются, свет частенько не выключается (что жена, что дети).

Порка, возможно, что-то и исправила бы), но вы же знаете, очень трудно измениться)

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Unreal334 пишет:

Очень симпатично. А что это? Просто вставка?

да заглушка, из той же серии что и розетки и выключатели.

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Я автоматические двери обслуживал, там стоят микроволновые датчики, вещь конечно, через пластмарру бьют реагируют на мясо :)

Unreal334
Offline
Зарегистрирован: 03.04.2015

knack пишет:

Я автоматические двери обслуживал, там стоят микроволновые датчики, вещь конечно, через пластмарру бьют реагируют на мясо :)

Это такого плана, что Tomasina советовал?

macros
Offline
Зарегистрирован: 07.11.2016

Unreal334 пишет:

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

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

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Unreal334 пишет:

knack пишет:

Я автоматические двери обслуживал, там стоят микроволновые датчики, вещь конечно, через пластмарру бьют реагируют на мясо :)

Это такого плана, что Tomasina советовал?

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

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

лучше у самого Tomasina спросить, если он юзал.

Unreal334
Offline
Зарегистрирован: 03.04.2015

macros пишет:

Unreal334 пишет:

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

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

а как в моем коде реализовать это, со всеми этими переменными туго пока, только начинаю учится

может напишите пару строк, если не трудно

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

да, по моей ссылке СВЧ-датчик (со змейкой на плате). Его особенность (кому плюс, а кому и минус) - ему пофиг на стены (не капитальные), срабатывает на все, что движется в зоне 3-6 метров. Поэтому место установки надо выбирать очень вдумчиво, чтобы не реагировал на соседей, жену на кухне и пр.

Самый простой и надежно работающий способ уже предлагали выше - обычный PIR-датчик движения и большая задержка отключения. Не нужно выключать свет сразу после ухода посетителя (это не так просто однозначно дигностировать), достаточно отключать лампу после 2-3 минут неактивности (PIR-датчики с двумя крутилками это умеют, там есть перемычка "продлить время, если снова обнаружено движение, ну или поставить для совсем тупых PIR просто увеличить таймаут до 6-7 минут). Этого хватит чтобы вдумчиво сделать свои дела, ну а любителям посидеть по Wi-Fi свет не очень-то и нужен :)

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

Ну а если ардуинку привлекать, то предлагаю такой алгоритм - в loop отдельно и независимо анализируем все факторы (движение есть? свет сейчас включен? время включения истекло? на улице светло? сколько прошло с последнего включения? и др.), для каждого из них ставим "оценку" - записываем в отдельную переменную 0 или 1. И свет отключается только в том случае, если сумма всех этих переменных равна нулю. Эта логика легко переводится в код, легко расширяется в части функционала, легко настраивается, проста в понимании для новичка. Выглядит сложно, но на самом деле это гораздо результативнее сложного составного if(), предлагаемого в посте #13, в котором потом замучаешься отыскивать варианты компоновки условий и их зависимости.

P.S. у меня в комнате медитации все проще - три галогенки, два реле и двуклавишный выключатель. Посетители сами при входе выбирают комфортный режим - ярко (все лампы коммутируются впараллель), или тускло (все лампы коммутируются последовательно). Как показала двухлетняя практика, это удобнее любой автоматики, ибо бывает что и ночью гости приходят и иногда по другими причинам нужен яркий свет, причем длительное время (уборка и пр).

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

Ответим на простой вопрос: Зачем выключать свет в туалете? Наверно для того что бы не нагорало на счетчик, а значит на кошелек. То что на 5 минут будет гореть больше, экономию большую не принесет. Сложнее если все легли спать, а свет горит всю ночь.  Так что решение банально. Вместо лампы на верху ставим лампу с реле времени в !!! ПОЛЧАСА. То есть человек включил выключателем свет, то он горит максимум пол часа и выключается.  Да если человеку не надо больше торчать в туалете, то он может уходя выключить свет ВЫКЛЮЧАТЕЛЕМ, если склероз его не замучал. А если протупил забыл, то что бы снова включить надо ВЫКЛЮЧИТЬ и ВКЛЮЧИТЬ снова. ДЛя любителей сидет больше пол часа в туалете(или совмещеном с ванной), то можно поставить датчик движения над толчком (и ванной тоже). Раз в пол часа человек точно пошевельнется.

Unreal334
Offline
Зарегистрирован: 03.04.2015

Ребята, все класс. Факторы, 0 и 1 все понятно, но проблема в том что мне не хватает знания языка программирования и самому очень тяжело доходить, поэтому и прошу помощи, а именно строчку кода и комментарий, если не затруднит. Что есть то есть, помогите с кодом.

Unreal334
Offline
Зарегистрирован: 03.04.2015

macros пишет:

Unreal334 пишет:

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

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


Понравилась идея, как описать?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/*
 //#1 5 секунд не работает 5 секунд работает и дальше
светодиод 1->2 (led_pin) 1 вкл/0 выкл
кнопка 2->4 (btn_pin) 0 вкл/1 выкл
*/
//#1
const int led_pin = 2;
bool led; //состояние реле 1 вкл/ 0 нет
const uint32_t time_OFF = 30 * 60 * 1000 ; // время выключения пол часа.
const int btn_pin = 4;

void setup() {
  //#1
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, led = 1);// вкл свет
  pinMode(btn_pin, INPUT_PULLUP);
}

void loop() {
  //#1 10сек вычислит. поток 1
  static uint32_t past_1 = 0 ;
  if ( millis() - past_1 >= time_OFF ) // если прошло time_OFF времени
    digitalWrite(led_pin, led = 0); // выкл свет
  if (! digitalRead(btn_pin)) { // если датчик сработал
    past_1 = millis() ;  // то передвинуть время фиксации последнего включения
    digitalWrite(led_pin, led = 1);// вкл свет
  }
}
Logik
Offline
Зарегистрирован: 05.08.2014

qwone пишет:

Ответим на простой вопрос: Зачем выключать свет в туалете? Наверно для того что бы не нагорало на счетчик, а значит на кошелек. То что на 5 минут будет гореть больше, экономию большую не принесет. Сложнее если все легли спать, а свет горит всю ночь.  Так что решение банально. Вместо лампы на верху ставим лампу с реле времени в !!! ПОЛЧАСА. То есть человек включил выключателем свет, то он горит максимум пол часа и выключается.  Да если человеку не надо больше торчать в туалете, то он может уходя выключить свет ВЫКЛЮЧАТЕЛЕМ, если склероз его не замучал. А если протупил забыл, то что бы снова включить надо ВЫКЛЮЧИТЬ и ВКЛЮЧИТЬ снова. ДЛя любителей сидет больше пол часа в туалете(или совмещеном с ванной), то можно поставить датчик движения над толчком (и ванной тоже). Раз в пол часа человек точно пошевельнется.

Ага. Начинать нужно с экономного и долговечного источника света. А это светодиод. Для с/у 5Вт нормально так. Если по движению включать его да хоть на полчаса, то получим пару часов в сутки, ну пусть 4часа, с запасом. 20Вт*час в сутки 600Вт*час в месяц 7КВт*час за год. Посчитайте по своим тарифам срок окупаемости проекта, дай бог долгих лет шоб дожить. Вывод прост - таймер отключающий через некоторое время отсутствия движения (он сразу в датчике с 2-я крутилками есть)- это максимум что имеет смысл.

Unreal334
Offline
Зарегистрирован: 03.04.2015

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

Барон
Offline
Зарегистрирован: 17.11.2016

У меня стоит датчик движения со встроенным таймером - покупал на рынке, вобще без проблем. настраиваешь один раз таймер и все.. зашел - свет врубился, сел на толчек, 5 минут в танчики играешь, таймер отсчитывает время, один черт за 5 минут двинешся )) единственное что, скорее всего таймер там приметивный наверное, тоесть задержка не бывает строго 2 минуты (как пример) может быть 1.5 минуты или 2.5. но приловчиться можно. очень удобная весчь  -вышел, вентилятор и свет отработали свое и все погасло.. городить на ардуине думаю нет смысла....

Визуально похож на этот http://www.mitinor.ru/product_804.html

Да это он, не видел описание..

Unreal334
Offline
Зарегистрирован: 03.04.2015

Всем доброго дня!

Долго меня не было, вернулся к автоматическому освещению санузла - настроен закончить начатое), но нужна помощь!

#include <DS1302.h>
#include <livolo.h>
#define fadePin 6                 //пин управления MOSFET транзистором
Livolo livolo(11);                // Передатчик FS1000A 433 МГц на пин 11
int calibrationTime = 10;//!!!!!         //Время калибровки датчика движения 30 сек (10-60 сек. по даташиту)
long unsigned int lowIn;          //Время, в которое был принят сигнал отсутствия движения(LOW)
long unsigned int pause = 7000;  //Пауза, после которой движение считается оконченным - 7 сек
boolean lockLow = true;           //Флаг. false = значит движение уже обнаружено, true - уже известно, что движения нет
boolean takeLowTime;//Флаг. Сигнализирует о необходимости запомнить время начала отсутствия движения
  int move = 0;                   //Движение
  int time;
  int autolight = 0;              //Флаг. Сигнализирует о том - кто включил или выключил свет (ардуино или вручную)
    DS1302 rtc(7, 8, 12);         // Часы
    Time t;


  const int pinPhoto = A0;        // Фоторезистор с подтягивающим на А0
  int raw = 0;                    // Освещенность
    int TrigPin = 4;              // Пины 3, 4 ультразвукового дальномера
    int EchoPin = 3;
  int light;                      //переменная для хранения состояния света (вкл/выкл) 
  int pirPin = 2;                 //вывод подключения датчика движения
  int ledPin = 13;
  
void setup()
{
  pinMode(13, OUTPUT);
  pinMode(TrigPin,OUTPUT);
  pinMode(EchoPin,INPUT);
  pinMode(fadePin, OUTPUT);
  digitalWrite(pirPin, LOW);
  pinMode( pinPhoto, INPUT );
  delay(1000);
  
    //калибровка 30 сек
  for(int i = 0; i < calibrationTime; i++)
  {
    //Во время калибровки будет мигать сигнальный диод
    i % 2 ? digitalWrite(ledPin, HIGH) : digitalWrite(ledPin, LOW);
    delay(1000);
  }
  //По окончанию калибровки зажжем сигнальный диод 
  digitalWrite(ledPin, HIGH);
  delay(50);
  
  Serial.begin(9600);  
}

void loop()
{
  move = digitalRead(pirPin);
  raw = analogRead( pinPhoto );
  t = rtc.getTime();
   
  int distance,duration;
  digitalWrite(TrigPin,HIGH);
  delayMicroseconds(11);
  digitalWrite(TrigPin,LOW);
  duration = pulseIn(EchoPin, HIGH);
  delay(50);
  
    if(raw >= 750) // 500 нужное значение
  {light = 1;}
  else {light = 0;delay(50);}
  

//Проверка состояния верхнего света если кто-то включил свет вручную, но не дошел до туалета то через 10 сек свет выключится автоматически
if((digitalRead(pirPin) == LOW) && (light == 1) && (duration > 3000) && (autolight == 0))
{
    Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LightOFFautomatic");
    livolo.sendButton(6400, 120);
    
    }
  

//Верхний свет с 9 до 21
//Если обнаружено движение
  if((digitalRead(pirPin) == HIGH) && (light == 0) && (t.hour >= 9) && (t.hour <= 20))
  {
    //Если до этого момента еще не включили свет
    if(lockLow)
    {
      lockLow = false;      
      //Включаем свет.
      livolo.sendButton(6400, 120); Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LightON");
      autolight = 1;
      delay(50);
    }        
    takeLowTime = true;
  }

  //Ели движения нет
  if((digitalRead(pirPin) == LOW) && (duration > 3000) && (t.hour >= 9) && (t.hour <= 20))
  {      
    //Если время окончания движения еще не записано
    if(takeLowTime)
    {
      lowIn = millis();          //Сохраним время окончания движения
      takeLowTime = false;       //Изменим значения флага, чтобы больше не брать время, пока не будет нового движения
    }
    //Если время без движение превышает паузу => движение окончено
    if((!lockLow && millis() - lowIn > pause) ) //проверяем также освещенность, вдруг кто-то вышел и выключил свет вручную
    { 
      //Изменяем значение флага, чтобы эта часть кода исполнилась лишь раз, до нового движения
      lockLow = true;
      if(light == 1)
      {livolo.sendButton(6400, 120); Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LightOFF");
      autolight = 0; delay(50);}
      else {autolight = 0; Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Light Allready OFF");
      delay(50);}
    }
  }
  
  
  // вывожу в порт для настройки

  Serial.print("Illumination ");
  Serial.println( raw );
  Serial.print("Svet ");
  Serial.println( light );
  
  Serial.print("Move ");
  Serial.println(move);
  Serial.print("Autolight ");
  Serial.println(autolight);
  
  Serial.print("Distance ");
  Serial.print(duration);
  Serial.print(" (");
  Serial.print(duration/29/2);
  Serial.println(" cm)");
  
  Serial.print(t.date, DEC);
  Serial.print(" ");
  Serial.print(rtc.getMonthStr());
  Serial.print(" ");
  Serial.print(t.year, DEC);
  Serial.println(".");
  Serial.println(rtc.getDOWStr());
  Serial.print(t.hour, DEC);
  Serial.print(":");
  Serial.print(t.min, DEC);
  Serial.print(":");
  Serial.println(t.sec, DEC);
  delay (500);
}

Вопрос: Как описать без delay, чтобы при выполнении условия в строке 68 прошло 10 сек и проверив еще раз условие в строке 68 (движения нет, свет горит, на унитазе никого, и свет включил не микроконтроллер) свет выключался?

valera678
Offline
Зарегистрирован: 04.11.2016

счас вас будут бить тапком и совать носом в миллис)

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
i % 2 ? digital...

тут разве if не нужен?

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

Tomasina пишет:

i % 2 ? digital...

тут разве if не нужен?

я запретил

Unreal334
Offline
Зарегистрирован: 03.04.2015

valera678 пишет:

счас вас будут бить тапком и совать носом в миллис)

с millis пробывал, но что-то совсем печально у меня с этим

Unreal334
Offline
Зарегистрирован: 03.04.2015

а вообще если тыкните в millis строкой кода - буду даже рад

кратенько, я думаю вам не сложно?)

arDubino
Offline
Зарегистрирован: 12.01.2017

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

bwn
Offline
Зарегистрирован: 25.08.2014

valera678 пишет:

счас вас будут бить тапком и совать носом в миллис)

А что в миллисе плохого? В принципе можно никого не бить и никуда не совать, пускай сам головой об экран бьется. Если конечно Клапауций не запретит.

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

bwn пишет:

Если конечно Клапауций не запретит.

я запрещаю.

bwn
Offline
Зарегистрирован: 25.08.2014

Клапауций 823 пишет:

bwn пишет:

Если конечно Клапауций не запретит.

я запрещаю.

Разъясни, ты за имущество или голову ТС беспокоишься?

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

bwn пишет:

Разъясни, ты за имущество или голову ТС беспокоишься?

за Россию - космолёты должны продолжать падать в Туву, иначе не избежать ядерной бомбардировки Москвы.

Unreal334
Offline
Зарегистрирован: 03.04.2015

Ребят), ну опять одно и тоже, просишь помощи - стёб и споры между собой, что лучше из вариантов, в которых я ни х...я не понимаю) я понимаю, что я наверное тысячный с этим вопросом, ну сделайте ctr+c ctl+v и если у меня это заработает - я буду счастлив и вам всем премного благодарен

bwn
Offline
Зарегистрирован: 25.08.2014

Нате лучше удочку, нихрена там сложного нет.

ZIA
ZIA аватар
Offline
Зарегистрирован: 04.02.2017
if (millis()-timePreviousMeassure >=60000){
   countPerMinute = count;
   radiationValue = countPerMinute * CONV_FACTOR;
   timePreviousMeassure = millis();
   count = 0; // счетчик обнулим тут, для правильности счёта, вывод на экран ведь время занимает

 

Unreal334
Offline
Зарегистрирован: 03.04.2015

bwn пишет:

Нате лучше удочку, нихрена там сложного нет.

Спасибо, сделал как в примере

#define  BLINK_INTERVAL  5000UL  // интервал между включение/выключением светодиода (5 секунд)
#define PRINT_INTERVAL 1000UL  // периодичность вывода времени в Serial (1 cекунда)
#include <DS1302.h>
#include <livolo.h>
#define fadePin 6                 //пин управления MOSFET транзистором
Livolo livolo(11);                // Передатчик FS1000A 433 МГц на пин 11
int calibrationTime = 10;//!!!!!         //Время калибровки датчика движения 30 сек (10-60 сек. по даташиту)
long unsigned int lowIn;          //Время, в которое был принят сигнал отсутствия движения(LOW)
long unsigned int pause = 7000;  //Пауза, после которой движение считается оконченным - 7 сек
long unsigned int timePreviousMeassure;
long unsigned int countPerMinute;
boolean lockLow = true;           //Флаг. false = значит движение уже обнаружено, true - уже известно, что движения нет
boolean takeLowTime;              //Флаг. Сигнализирует о необходимости запомнить время начала отсутствия движения
  int move = 0;                   //Движение
  int time;
  int autolight = 0;              //Флаг. Сигнализирует о том - кто включил или выключил свет (автоматом или вручную)
    DS1302 rtc(7, 8, 12);         // Часы
    Time t;
    
    unsigned long currentTime;
    unsigned long loopTime;

  const int pinPhoto = A0;        // Фоторезистор с подтягивающим на А0
  int raw = 0;                    // Освещенность
    int TrigPin = 4;              // Пины 3, 4 ультразвукового дальномера
    int EchoPin = 3;
  int light;                      //переменная для хранения состояния света (вкл/выкл) 
  int pirPin = 2;                 //вывод подключения датчика движения
  int ledPin = 13;
  
void setup()
{
  pinMode(13, OUTPUT);
  pinMode(TrigPin,OUTPUT);
  pinMode(EchoPin,INPUT);
  pinMode(fadePin, OUTPUT);
  digitalWrite(pirPin, LOW);
  pinMode( pinPhoto, INPUT );
  delay(1000);
  
  currentTime = millis();       // считываем время, прошедшее с момента запуска программы
  loopTime = currentTime;
  
    //калибровка 30 сек
  for(int i = 0; i < calibrationTime; i++)
  {
    //Во время калибровки будет мигать сигнальный диод
    i % 2 ? digitalWrite(ledPin, HIGH) : digitalWrite(ledPin, LOW);
    delay(1000);
  }
  //По окончанию калибровки зажжем сигнальный диод 
  digitalWrite(ledPin, HIGH);
  delay(50);
  
  Serial.begin(9600);  
}

void loop()
{ 
  move = digitalRead(pirPin);
  raw = analogRead( pinPhoto );
  t = rtc.getTime();
   
  int distance,duration;
  digitalWrite(TrigPin,HIGH);
  delayMicroseconds(11);
  digitalWrite(TrigPin,LOW);
  duration = pulseIn(EchoPin, HIGH);
  delay(50);
  
    if(raw >= 750) // 500 нужное значение
  {light = 1;delay(50);}
  else {light = 0;delay(50);}
  
  //Проверка состояния верхнего света если кто-то включил свет вручную но не дошел до туалета то через 10 сек свет выключится автоматически
if((digitalRead(pirPin) == LOW) && (light == 1) && (duration > 3000) && (autolight == 0))
{
  static unsigned long prevBlinkTime = 0; // время когда последний раз переключали диод
  if(millis() - prevBlinkTime > BLINK_INTERVAL) {
    prevBlinkTime = millis();  // 
    if((digitalRead(pirPin) == LOW) && (light == 1) && (duration > 3000) && (autolight == 0))
    {livolo.sendButton(6400, 120);
    Serial.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LightOFFautomatic");
  }
  }
}
  
  
  // вывожу в порт для настройки
  Serial.print("Illumination ");
  Serial.println( raw );
  Serial.print("Svet ");
  Serial.println( light );
  
  Serial.print("Move ");
  Serial.println(move);
  Serial.print("Autolight ");
  Serial.println(autolight);
  
  Serial.print("Distance ");
  Serial.print(duration);
  Serial.print(" (");
  Serial.print(duration/29/2);
  Serial.println(" cm)");
  
  Serial.print(t.date, DEC);
  Serial.print(" ");
  Serial.print(rtc.getMonthStr());
  Serial.print(" ");
  Serial.print(t.year, DEC);
  Serial.println(".");
  Serial.println(rtc.getDOWStr());
  Serial.print(t.hour, DEC);
  Serial.print(":");
  Serial.print(t.min, DEC);
  Serial.print(":");
  Serial.println(t.sec, DEC);
  delay (500);
}

проблема в том, что при включении света вручную, выполняется условие в строке 76 и свет СРАЗУ выключается (а мне надо, чтобы он выключился через 5 сек), причем бьёт ошибку

Error inside Serial.serialEvent()
java.io.IOException: Bad file descriptor in nativeavailable
at gnu.io.RXTXPort.nativeavailable(Native Method)
at gnu.io.RXTXPort$SerialInputStream.available(RXTXPort.java:1532)
at processing.app.Serial.serialEvent(Serial.java:215)
at gnu.io.RXTXPort.sendEvent(RXTXPort.java:732)
at gnu.io.RXTXPort.eventLoop(Native Method)
at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1575)
 
Что не так делаю?
Питание передатчика на 433 отдельное, земли соединил. Или в коде накосячил?

 

Unreal334
Offline
Зарегистрирован: 03.04.2015

RX и TX свободны, USB подключил к аккумулятору, ардуинка не перезагружается, но свет при повторных нажатиях отключается хаотично, то сразу, то через 2сек, то через 5-7

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

Tomasina пишет:

i % 2 ? digital...

тут разве if не нужен?

А зачем?

В принципе, все равно много лишнего. Лучше так:

digitalWrite(pin, i % 2);

 

Unreal334
Offline
Зарегистрирован: 03.04.2015

Ребята, помогайте, сам не справлюсь!

valera678
Offline
Зарегистрирован: 04.11.2016

Unreal334 пишет:

Ребята, помогайте, сам не справлюсь!

Справишься...Ты  ж мужик!!!

Unreal334
Offline
Зарегистрирован: 03.04.2015

valera678 пишет:

Unreal334 пишет:

Ребята, помогайте, сам не справлюсь!

Справишься...Ты  ж мужик!!!

Если не знаете, лучше ничего не писать.

Поможет, кто знает? Или лень?