Автоматический свет (ардуино+датчик движения+дальномер)

Использование системы в различных ситуациях, вопросы программирования сценариев.

Модератор: immortal

Ответить
Unreal
Сообщения: 15
Зарегистрирован: Чт сен 08, 2016 3:01 pm
Благодарил (а): 8 раз
Поблагодарили: 0

Автоматический свет (ардуино+датчик движения+дальномер)

Сообщение Unreal » Пн дек 05, 2016 2:20 pm

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

Код: Выделить всё

#include <DS1302.h>
#include <livolo.h>
Livolo livolo(11);                // Передатчик FS1000A 433 МГц на пин 11
int calibrationTime = 30;         //Время калибровки датчика движения 30 сек (10-60 сек. по даташиту)
long unsigned int lowIn;          //Время, в которое был принят сигнал отсутствия движения(LOW)
long unsigned int pause = 10000;  //Пауза, после которой движение считается оконченным - 10 сек
boolean lockLow = true;           //Флаг. false = значит движение уже обнаружено, true - уже известно, что движения нет
boolean takeLowTime;              //Флаг. Сигнализирует о необходимости запомнить время начала отсутствия движения

    DS1302 rtc(7, 8, 12);         // Часы
    Time t;
    
  const int pinPhoto = A0;        // Фоторезистор с подтягивающим на А0
  int raw = 0;                    // Освещенность
    int TrigPin = 4;              // Пины 3, 4 ультразвукового дальномера
    int EchoPin = 3;
    
  int relayPin = 10;              //реле подсветки
  int pirPin = 2;                 //вывод подключения датчика движения
  
  int ledPin = 13;
  
void setup()
{
  pinMode(13, OUTPUT);
  pinMode(TrigPin,OUTPUT);
  pinMode(EchoPin,INPUT);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH);  //для моего реле устанавливаю выкл
  delay(4000);
  digitalWrite(pirPin, LOW);
  pinMode( pinPhoto, INPUT );
  
    //калибровка 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()
{
  
  raw = analogRead( pinPhoto );
  delay(50);
  t = rtc.getTime();
  delay(50);
  int distance,duration;
  digitalWrite(TrigPin,HIGH);
  delayMicroseconds(11);
  digitalWrite(TrigPin,LOW);
  duration = pulseIn(EchoPin, HIGH);
  delay(50);
  

  //при обнаружении движения (до 21-00) и если свет не горит - включаем свет
  if((digitalRead(pirPin) == HIGH) && (raw < 500) && (t.hour < 21))
    {if(lockLow) //Если до этого момента еще не включили свет
    {lockLow = false;  livolo.sendButton(6400, 120);  delay(100);}        // код на включение и выключение на самом деле один, для отладки поставил разные 
    takeLowTime = true;}
  
  //при обнаружении движения (после 21-00) и если свет не горит - включаем подсветку
  if((digitalRead(pirPin) == HIGH) && (raw < 500) && (t.hour >= 21))
  {if(lockLow)
    {lockLow = false;  digitalWrite(relayPin, LOW);   delay(50);}        
    takeLowTime = true;}

//если движения больше нет и на унитазе никого (до 21-00) выключаем свет
    if(digitalRead(pirPin) == LOW)
  {if(takeLowTime)
    {lowIn = millis(); takeLowTime = false;}
    if((!lockLow && millis() - lowIn > pause) && (duration > 3000) && (t.hour < 21))
    { lockLow = true; livolo.sendButton(6400, 92); delay(50);}
//если движения больше нет и на унитазе никого (после 21-00) выключаем подсветку
    if(digitalRead(pirPin) == LOW)
  {if(takeLowTime)
    {lowIn = millis(); takeLowTime = false;}
    if((!lockLow && millis() - lowIn > pause) && (duration > 3000) && (t.hour >= 21))
    { lockLow = true; digitalWrite(relayPin, HIGH); delay(50);}
    
  }

}
// вывожу в порт для настройки
  Serial.print("Illumination ");
  Serial.println( raw );
  
  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 (1000);
  
}
Ответить