Проблема с PIR датчиком
- Войдите на сайт для отправки комментариев
Доброго времени суток. Вродебы простая задача но столкнулся со след. проблемой - есть вот такой датчик
http://arduino.shopium.ua/products/arduino-pir-sensor/ , по срабатыванию датчика должен включаться свет в комнате с пом. реле,на ардуину залил стандартный скетч из примеров
//Время калибровки датчика (10-60 сек. по даташиту)
int calibrationTime = 30;
//Время, в которое был принят сигнал отсутствия движения(LOW)
long unsigned int lowIn;
//Пауза, после которой движение считается оконченным
long unsigned int pause = 1000;
//Флаг. false = значит движение уже обнаружено, true - уже известно, что движения нет
boolean lockLow = true;
//Флаг. Сигнализирует о необходимости запомнить время начала отсутствия движения
boolean takeLowTime;
int pirPin = 41; //вывод подключения PIR датчика
int ledPin = 50; //вывод сигнального диода
int relayPin = 40; //реле пин
int PhotoRPin = A8; //Фоторезистор
int PhotoRValue;
void setup()
{
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
pinMode(relayPin, OUTPUT);
//!ВНИМАНИЕ! При использовании n-p-n реле необходимо в след. строчке поменять HIGH на LOW
digitalWrite(relayPin, LOW);
delay(4000);
digitalWrite(pirPin, LOW);
//дадим датчику время на калибровку
for(int i = 0; i < calibrationTime; i++)
{
//Во время калибровки будет мигать сигнальный диод
i % 2 ? digitalWrite(ledPin, HIGH) : digitalWrite(ledPin, LOW);
delay(1000);
}
//По окончанию калибровки зажжем сигнальный диод
digitalWrite(ledPin, HIGH);
Serial.println("SENSOR ACTIVE");
delay(50);
dht.begin();
}
void loop()
{
{
PhotoRValue = analogRead(PhotoRPin);
Serial.println(PhotoRValue);
delay(1000);
}
//Если обнаружено движение
if(digitalRead(pirPin) == HIGH)
{
//Если до этого момента еще не включили реле
if(lockLow)
{
lockLow = false;
//Включаем реле.
//!ВНИМАНИЕ! При использовании n-p-n реле необходимо в след. строчке поменять LOW на HIGH
if (PhotoRValue<50)
{
digitalWrite(relayPin, HIGH);
digitalWrite(ledPin, HIGH);
delay(50);
}
}
takeLowTime = true;
}
//Ели движения нет
if(digitalRead(pirPin) == LOW)
{
//Если время окончания движения еще не записано
if(takeLowTime)
{
lowIn = millis(); //Сохраним время окончания движения
takeLowTime = false; //Изменим значения флага, чтобы больше не брать время, пока не будет нового движения
}
//Если время без движение превышает паузу => движение окончено
if(!lockLow && millis() - lowIn > pause)
{
//Изменяем значение флага, чтобы эта часть кода исполнилась лишь раз, до нового движения
lockLow = true;
digitalWrite(relayPin, LOW);
digitalWrite(ledPin, LOW);
delay(50);
} }}
Проблема в следующем - при движении датчик срабатывает и свет включается но через определённый интервал (выставленный физически регулятором на самом датчике ) свет гаснет не зависимо от того было ли движение в течении этого времени или нет. По логике нужно так , что после первого движения включается свет , потом если через время, например 3 минуты, движения небыло - свет выключается, если за это время было движение, то отсчёт опять обнуляется и опять ждём 3 минуты. Но сейчас срабатывает только на первое движение а на последующие нет реакции(если они входят в этот отведённый интервал установленный регулятором на датчике). Помогите пожалуйста решить проблему.
кстати переменную
longunsignedintpause = 1000;ставил значение и 180000, езультат тотже (((К сожалению , отклика так и не дождался, но есть положительный момент, сам переписал код и он рабочий. вот код , если кому интересно
// Рабочая версия #include <LiquidCrystal.h> LiquidCrystal lcd(3, 4, 25, 24, 23, 22); #include "DHT.h" #define DHTPIN 2 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); //Время калибровки датчика (10-60 сек. по даташиту) int calibrationTime = 30; //Время, в которое был принят сигнал движения(HIGH) long unsigned int timee; //Пауза, после которой движение считается оконченным // 5 минут , таймер-резистр самого датчика стоит на минимуме 5 сек. long unsigned int pause = 300000; int pirPin = 41; //вывод подключения PIR датчика int ledPin = 50; //вывод сигнального диода (реле включено) int ledPin2 = 44; //вывод сигнального диода 2 (нет движения) int relayPin = 40; //реле пин int PhotoRPin = A8; //Фоторезистор int PhotoRValue; void setup() { Serial.begin(9600); lcd.begin(16, 2); lcd.print("Microklimat:"); pinMode(pirPin, INPUT); pinMode(ledPin, OUTPUT); pinMode(ledPin2, OUTPUT); pinMode(relayPin, OUTPUT); digitalWrite(relayPin, LOW); delay(500); digitalWrite(pirPin, LOW); //дадим датчику время на калибровку for(int i = 0; i < calibrationTime; i++) { //Во время калибровки будет мигать сигнальный диод i % 2 ? digitalWrite(ledPin, HIGH) : digitalWrite(ledPin, LOW); delay(1000); } //По окончанию калибровки зажжем сигнальный диод digitalWrite(ledPin, LOW); digitalWrite(ledPin2, LOW); Serial.println("SENSOR ACTIVE"); delay(50); dht.begin(); } void loop() { //выводим температуру и влажность на екранчик lcd.setCursor(0, 1); float h = dht.readHumidity(); float t = dht.readTemperature(); if (isnan(t) || isnan(h)) { lcd.print("Temp-ra error"); } else { lcd.print("C="); lcd.print(t); lcd.print(" H="); lcd.print(h); } { PhotoRValue = analogRead(PhotoRPin); delay(1000); } //Если обнаружено движение if(digitalRead(pirPin) == HIGH) { // Записываем время когда началось дижение timee=millis(); digitalWrite(ledPin2, LOW); // Проверяем освещённость в комнате if (PhotoRValue<50) { //Включаем реле. digitalWrite(relayPin, HIGH); digitalWrite(ledPin, HIGH); // delay(50); } } //Ели движения нет if(digitalRead(pirPin) == LOW) { digitalWrite(ledPin2, HIGH); //Если время без движение превышает паузу => движение окончено if(millis()- timee > pause) { digitalWrite(relayPin, LOW); digitalWrite(ledPin, LOW); // delay(50); } } }Взяли датчик с логическим выходом есть/нет движения, но при этом проверяете уровень освещённости в первом случае, а во втором выводите температуру и влажность на экран.. Минимизируйте скетч до "только датчик движения", тогда и получите ответ. В трёхстраничном листинге с хвостами непонятно от чего разбираться желания ни у кого нет.
датчик и так должен работать, без ардуино
на нем есть два подстроечных сопротивления Sx - чувствительность и Tx - время
первым устанавливаете чуствительность, вторым время которое будет включен датчик после срабатывания, подаете питание на датчик, к выходу цепляете мосфет с нагрузкой (в вашем случае реле) я поставил светодиодную ленту. Вот вам готовое устройство...
покупал подобный датчик только на ebay, очень похож на Ваш только питание у него до 20в.
это корректно?
Сори за большой код, в последней редакции я выложил с подробными комментариями, с температурой и датчиком освещённости и реле, вдруг кому понадобится. msng - что касается того, что датчик должен работать и без дуины, то это да но в пределах своего аппаратного таймера (макс 5 мин) а мне нужно чтобы с момента последнего движения начинался отсчёт, если использовать его без дуины, то датчик выключает реле по любому после 5 минут, что есть не удобно. По крайней мере у меня так было. Tomasina
Взято из примера (неработающего), так как компилятор не ругался, так его и оставил, по умолчанию работает, но как я понимаю можно оставить в таком виде
для начала выставите минимальное время на датчике аппаратно, потом выясните какой тип переменн
ой в millis(), убедитесь, что это не int и переназначте переменную pause и timee правильным типом.Можно, разрешаем.
Меньше памяти, меньше ног, меньше uart, меньше прерываний.
Эсли все это не существенно - используйте Уно вместо Меги.
Подскажите,такая проблема у меня в терминале все время идут записи "motion detected" и L постоянно мигает. В чем проблема?
Проблема или в скетче, или в железе.
Можно по подробнее плиз,в скетче все номально а датчик движения у менятакой ,ниже фото датчика,на ардуино он все время подет единичку
Ну раз в скетче всё нормально, то замеряйте выход (который на ардуину идет) мультиметром, тоже будет все время единичку выдавать?
Мультиметр ничего не дает,хотя он работает. Не понимаю в чем дело,датчик сам работает мигает когда движение есть,а сигнальный выход (2 провода желтый и зеленый) все время подает единичку на ардуино и на ардуино L все время мигает,хотя он должен мигать каогда есть движение. (Просто я "чайник" в этом деле)
Может Что-то поможет Вам из моего небогатого опыта.
Я далеко не специалист по датчикам движения, но вот на дня себе собирал упражнение с использованием простого датчика для ардуинки, активно гуглил и тут читал.
Может Вам поможет поискать где-то подробнее вот такое мое наблюдение, подтвержденное тут на форуме в какой-то статье: когда датчик сработал и идет время аппаратной задержки (ваши 3 минуты) он нихрена не ловил новых движений в принципе, точнее не выдавал в ничего кроме 1 во все время задержки. Т.е. как я читал и опробовал, задержка нужна для того, чтобы пока она есть подключенное устройство, например реле, было активно. Вряд ли там есть какая-то сложная логика. Может у Вас устройство наворочено более чем http://ru.aliexpress.com/item/1pcs-High-Quality-HC-SR501-Infrared-PIR-Mo...
Я у себя ставил задержку на датчике в минимум, а лампочку засвечивал программно ардуинкой. в это время сигналы от датчика накапливал. Кода не дам, не сохранил, меня в конце концов устроила аппаратная задержка датчика, а то, что я наваял - слегка где-то глючило :)
Вот мой код на сегодня, если интересно. В следующей версии избавился от Delay по многочисленным советам тутошних Гуру, чего и вам советую, а то во время после чтения датчика в строке 67, ничего другого у вас не происходит.
/* Подключены устройства - Arduino Nano v3 - LCD 20x4 i2c - RTC DS1307 i2c Подключены датчики - DHT 11 температура и влажность - LN35 температура - PIR движения - Photo фоторезистор + 10 kOm Ну и еще - КТ 973 (2 шт) , резистор 2.2kOm, диод на обратный ток, на линии 12В - КТ 972 (2 шт) резистор 10kOm,на линии 12В - Спикер с конденсатором на 10 mf */ //подключаем библиотеки #include <Wire.h> #include <RTClib.h> #include "DHT.h" #include <LiquidCrystal_I2C.h> //назначаем пины // ВХОДЫ #define DHTPIN A0 // Датчик Температуры и влажности int tempPin = A1; // Датчик Температуры LN 35 int photoPin = A2; // Датчик освещенности - фоторезистор? плюс на выход REF (1.1в) int pirPin = A3; // Датчик движения //ВЫХОДЫ int spkPin = 6; // Спикер int lednightPin = 9; // Транзистор включающий Ночник int ledtablePin = 10; // Транзистор включающий Стол int fanPin = 11; // Транзистор включающий Кулер // Объявляем что можем RTC_DS1307 RTC; // Часы LiquidCrystal_I2C lcd(0x27,20,4); // адрес LCD #define DHTTYPE DHT11 // DHT 11 //#define DHTTYPE DHT22 // D 22 (AM2302) DHT dht(DHTPIN, DHTTYPE, 6); // И переменные float tempC; //для датчика температуры LN35 int reading; //для датчика температуры LN35 int t; // для DHT int h; // для DHT int Light; // Для фоторезистора int LightR; long unsigned int lowIn; // для датчика движения long unsigned int pause = 5000; // для датчика движения boolean lockLow = true; // для датчика движения boolean takeLowTime; // для датчика движения int FAN_pwm = 100; // Значение от 0...255 (0 - 5в) /////******************************************************************************* void setup() { Serial.begin(9600); Wire.begin(); dht.begin(); /// Starting DHT RTC.begin(); //RTC.adjust(DateTime(__DATE__, __TIME__)); // установка времени на часах по времени компьютера // Запускаем приветствие на LCD lcd.init(); lcd.backlight(); lcd.clear(); lcd.setCursor(0, 1); lcd.print(" P R I V E T "); lcd.setCursor(0, 2); lcd.print(" SWEET HOME"); delay (1000); lcd.clear(); // Режимы входов-выходов, включаем подтягивающие резисторы, где надо // устанавливаем начальные значения вкл/выкл pinMode(pirPin, INPUT); digitalWrite(pirPin, LOW); //было в примере pinMode (tempPin, INPUT); // digitalWrite (tempPin, HIGH); /// если включаю - перестает меняться значение на датчике, 1023 pinMode(photoPin, INPUT); // digitalWrite(photoPin,LOW); pinMode (spkPin, OUTPUT); pinMode (lednightPin, OUTPUT); // digitalWrite(lednightPin, HIGH); // тут KT972, закрыт при HIGH pinMode (ledtablePin, OUTPUT); // digitalWrite(ledtablePin, HIGH); // тут KT972, закрыт при HIGH pinMode (fanPin, OUTPUT); // digitalWrite(fanPin, LOW); // тут KT973, закрыт при LOW // пикнем любым способом, tone проще tone (spkPin, 700, 100); //noTone (SPK_pin); // отключает сигнал, если нет длительности //analogWrite (SPK_pin, 10); delay(500); analogWrite (SPK_pin, 0); } //////// Ц И К Л ///////////////////////////////// void loop() { READ_DATA(); LCDPRN (); PIR_start(); // FAN_start(); TABLE_start (); delay(500); } ////Подпрограммы **************************************************************** ////////????????????????????????????????????????????????????????????????///////// void READ_DATA (){ // delay(250); analogReference(INTERNAL); reading = analogRead(tempPin); //// чтение показаний датчика LN35 //tempC = (reading/1024.0)*5000/10; // для расчета с опорным напряжением по дефолту (5в) tempC = reading/9.31; // для расчета с опорным напряжением INTERNAL (1.1в) h = dht.readHumidity(); // Чтение DHT 11 t = dht.readTemperature(); // delay(250); // вроде как рекомендуют паузу между чтением аналоговых выходов ? analogReference(DEFAULT); Light = analogRead(photoPin); // Чтение фоторезистора LightR = Light; } /////////////////////////////////////// void PIR_start(){ if(digitalRead(pirPin) == HIGH && Light > 500){ analogWrite(lednightPin, 180); //the led visualizes the sensors output pin state } if(digitalRead(pirPin) == LOW){ analogWrite(lednightPin, 255); // digitalWrite(lednightPin, HIGH); } } /////////////////////////////////////// void TABLE_start (){ if (Light < 500){ // digitalWrite (ledtablePin, HIGH); analogWrite (ledtablePin, 255); } else if (Light > 500){ analogWrite (ledtablePin, 150); } if (Light > 700) { analogWrite (ledtablePin, 50); } } ///////////////////////////////////////////////////////////////////////// void LCDPRN (){ DateTime now = RTC.now(); lcd.setCursor(0,0); lcd.print(now.day(), DEC); lcd.print('/'); lcd.print(now.month(), DEC); lcd.print('/'); lcd.print(now.year(), DEC); lcd.setCursor(11, 0); lcd.print(' '); if (now.hour() <10) { lcd.print(' '); } lcd.print(now.hour(), DEC); lcd.print(':'); lcd.setCursor(15, 0); if (now.minute() <10) { lcd.print('0'); } lcd.print(now.minute(), DEC); lcd.print(':'); lcd.setCursor(18, 0); if (now.second() <10) { lcd.print('0'); } lcd.print(now.second(), DEC); lcd.setCursor(0, 1); lcd.print("TEMP:"); if (t>=0&t<10) lcd.print(' '); if (t<0&t>-10) lcd.print(' '); lcd.print(t); lcd.print("C HUMID:"); lcd.print(h); lcd.print("% "); lcd.setCursor(0, 3); lcd.print("L "); lcd.setCursor(2, 3); lcd.print(LightR); lcd.setCursor(7, 3); lcd.print(" SHELF "); lcd.setCursor(14, 3); lcd.print(tempC); //lcd.print(reading); } ///////////////////////////////////////////////////////////////// void FAN_start(){ if (tempC <=25 ){ FAN_pwm = 0; analogWrite (fanPin, FAN_pwm); // digitalWrite (fanPin, LOW); // lcd.setCursor(16, 3); // lcd.print(" -"); } if (tempC > 25 ){ FAN_pwm = 150; analogWrite (fanPin, FAN_pwm); // lcd.setCursor(16, 3); // lcd.print(" *"); } if (tempC > 28 ){ FAN_pwm = 200; // lcd.setCursor(16, 3); // lcd.print("**"); analogWrite (fanPin, FAN_pwm); } if (tempC >34 ){ FAN_pwm = 255; // lcd.setCursor(16, 3); // lcd.print("**"); analogWrite (fanPin, FAN_pwm); tone (spkPin, 2000, 500); } }Если в Вашем PIR стоит микросхема BISS0001 (скорее всего это так), то у неё два режима работы выходной логики. 1. - добавление времени включения к текущему на первоначально заданную величину тоесть при попадании сигнала в зону захвата PIR датчика (а он довольно чувствительный, хватает небольшого движения руки) происходит продление выходного сигнала (на выходе будет постоянно присутствовать "1"). 2. - блокировка датчика PIR на время установленой задержки тоесть отрабатывается полное времы задержки и происходит переход выхода в "0" и только после этого появляется возможность повторного включения. Режимы работы выбираются перемычками на плате или прямой подачей иправляющего сигнала на ножку микросхемы (в даташите всё есть).
Помогите разобраться. Без реле все работает нормально. подключаю реле, реле включается при движении и все когда гаснет диод движения, оно щелкает и остается включенным, так до бесконечности.