Поппавка в Цикличном повтор включения

himikat
Offline
Зарегистрирован: 21.06.2016

unsigned long tim_e;
byte transPin = 5;  // инициализируем пин для транзистора
byte PirPin = 8;  // PIR инициализируем пин для получения сигнала от пироэлектрического датчика движения
boolean pirState = LOW;  // состояние датчика
boolean val = 0;  // переменная для чтения состояния пина
int fadeValue = 0; // переменная для плавного вкл ленты
//int ledstrip = 7;    // LED connected to digital pin 5

void setup() {
  Serial.begin (9600);
  pinMode(transPin, OUTPUT);  // объявляем светодиод в качестве  OUTPUT
  pinMode(PirPin, INPUT);  // объявляем датчик в качестве INPUT
}
void loop() {
  //if (millis() - tim_e > 2000) {
 // tim_e = millis ();
  val = digitalRead(PirPin);  // считываем значение с датчика
  //pirState = HIGH; // включаем флаг значения датчика на HIGH
 while (val == HIGH) {
  //switch (val){
 // case HIGH :
  
    Serial.println("efefefe");
    for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 50) // цикл на плавное вкдючение
    {
      analogWrite(transPin, fadeValue); // выводим цикл на контакт транзистора
      delay(50);// задержка для плавного вывода
     }
     delay (10000); // ждем 15 сек
     pirState = LOW;
//     break;
 // case (LOW):
 }
    while (val == LOW){
   digitalWrite (transPin, LOW);
  }
  }
// if (millis() < tim_e) tim_e = millis();
//}

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

sadman41
Offline
Зарегистрирован: 19.10.2016

himikat пишет:

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

Судя по описанию он зажигает ленту во время действия (какого, кстати?) объекта, срабатывая каждый раз. Т.е. действует ровно так, как вы и хотите.

himikat
Offline
Зарегистрирован: 21.06.2016

во время прохождения обьекта мимо датчика , допустим я подношу руку к датчику , он срабатывает --> загорается лента --> цикл на плавное включение --> тухнет по интервалу времени и сразу же загорается вновь --> цикл на плавное включение --> и так не сколько раз пока , хотя движение было только одно и обьект в зоне не был

sadman41
Offline
Зарегистрирован: 19.10.2016

На 18-ю строку: Serial.println(val); return;

Машите рукой, смотрите как меняется число в мониторе порта. Датчик может реагировать на что-то еще.

himikat
Offline
Зарегистрирован: 21.06.2016

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

himikat
Offline
Зарегистрирован: 21.06.2016

Я вот думаю как можно это расписать как счетчик от ложных срабатываний 

если есть срабатывание , то счетчик +1 

если счетчик >1 и есть срабатывание тогда шим сигнал на 255 (продолжает быть вкл транзистор , то есть горит лена на макс)

 

himikat
Offline
Зарегистрирован: 21.06.2016

а вот как это описать в коде 

himikat
Offline
Зарегистрирован: 21.06.2016

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

sadman41
Offline
Зарегистрирован: 19.10.2016

Можт ложные от засветки самой лентой?

Включение с таймаутом - оптимальней, думаю, чем геморроится. Сделать выключатель по типу blink без delay, а стартовый момент апдейтить по каждому дерганью. Тогда отключится через некоторое время после окончания мельтешения перед сенсором.

himikat
Offline
Зарегистрирован: 21.06.2016

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

himikat
Offline
Зарегистрирован: 21.06.2016

Проблема была решена. Заключалась в том что 

Инфракрасный датчик движения HC-SR505

Датчик выдает единицу на выход при срабатывании, и сохраняет ее в течение 8 секунд. 

То есть как я понял просто при видимости обьекта в течении 8 сек еще раз он просто по окончании затухании ленты слал еще 1 и в итоге получался повторяющися цикл

unsigned long tim_e=0;
byte transPin = 5;  // инициализируем пин для транзистора
byte PirPin = 8;  // PIR инициализируем пин для получения сигнала от пироэлектрического датчика движения
boolean pirState = LOW;  // состояние датчика
boolean val = 0;  // переменная для чтения состояния пина
int fadeValue = 0; // переменная для плавного вкл ленты
byte count = 0;

void setup() {
  Serial.begin (9600);
  pinMode(transPin, OUTPUT);  // объявляем светодиод в качестве  OUTPUT
  pinMode(PirPin, INPUT);  // объявляем датчик в качестве INPUT
}
void loop() {
  if (millis() - tim_e > 2000) { // каждые 2 секунд смотрим
  tim_e = millis (); // приравниваем текущее с настоящим
  val = digitalRead(PirPin);  // считываем значение с датчика
   //count = count + 1;
  if ( val == HIGH ){ // сравниваем значения  переменной val
    
    Serial.println(val);
        for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 20) // цикл на плавное вкдючение
    {
      analogWrite(transPin, fadeValue); // выводим цикл на контакт транзистора
      delay(50);// задержка для плавного вывода
     }
     delay (8000); // ждем 15 сек    
      digitalWrite (transPin, HIGH);
   }
  else 
    Serial.println(val);
   digitalWrite (transPin, LOW);
   }
  //}
 if (millis() < tim_e) // если больше 50 дней то сбрасываем время в 0
 tim_e = millis();
}
//}

 

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

Уберите 35 строку и все что к ней относится. Здесь за это сцаными тряпками гоняют. Хотите знать больше? Ищите темы "Переполнение миллис".))))

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Может так

unsigned long tim_e;
byte transPin = 5;  // инициализируем пин для транзистора
byte PirPin = 8;  // PIR инициализируем пин для получения сигнала от пироэлектрического датчика движения
//boolean pirState = LOW;  // состояние датчика
boolean val = 0;  // переменная для чтения состояния пина
//int fadeValue = 0; // переменная для плавного вкл ленты

void setup() {
  Serial.begin (9600);
  pinMode(transPin, OUTPUT);  // объявляем светодиод в качестве  OUTPUT
  pinMode(PirPin, INPUT);  // объявляем датчик в качестве INPUT
}
void loop() {
  val = digitalRead(PirPin);  // считываем значение с датчика
 if(val == HIGH) {
    Serial.println("efefefe");
    for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 50) // цикл на плавное вкдючение
    {
      analogWrite(transPin, fadeValue); // выводим цикл на контакт транзистора
      delay(50);// задержка для плавного вывода
     }
     delay (10000); // ждем 15 сек
 }
  else if(val == LOW){
   digitalWrite (transPin, LOW);
  }
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Всегда пытался понять - для чего второе условие?

val = digitalRead(PirPin);

 if(val == HIGH) {
   ...
 } else if(val == LOW){
   ...
 }

 

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

sadman41 пишет:

Всегда пытался понять - для чего второе условие?

Скорее потому что есть еще состояние "наверное" ;) #14

a5021
Offline
Зарегистрирован: 07.07.2013

Зря смеетесь. Могу ошибиться, но кажись в видеолекциях по программированию из МФТИ (или не менее авторитетного источника) лектор объяснял, что при проверках лучше каждое значение проверять отдельно, а в итоговом else вызывать функцию FAIL(). Здесь, ввиду слишком простого случая, это совершенно излишне, но хорошим тоном в однообразном стиле может быть.

myVar = myFunc();
if (myVar == 0) {
  // ..
} else if (myVar == 1) {
  // ..
} else {
  __FAIL();
}
sadman41
Offline
Зарегистрирован: 19.10.2016

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

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

a5021 пишет:

Зря смеетесь. Могу ошибиться, но кажись в видеолекциях по программированию из МФТИ (или не менее авторитетного источника) лектор объяснял, что при проверках лучше каждое значение проверять отдельно, а в итоговом else вызывать функцию FAIL().

Ну, что "объяснял", я не подвергаю ни малейшим сомнениям. Сомнения вызывает другое: поняли ли Вы эти объяснения, или решили делать так всегда вне зависимости от того, нужно это или не нужно.

 

PS. Кстати, в лучае логических переменных разумнее пользоваться if(myVar) либо if(!myVar) безо всяких "==".

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

andriano пишет:

PS. Кстати, в лучае логических переменных разумнее пользоваться if(myVar) либо if(!myVar) безо всяких "==".

Истинно, но когда только начинаешь знакомится с программированием, такие конструкции вводят в ступор. В объяснениях для новичков, лучше  описывать явно. ИМХО.

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

Неявно: if(myVal)

Явно: if(myVal == 1)

Очень явно: if((myVal == 1) == 1)

Совсем явно: if(((myVal == 1) == 1) == 1)

нет предела совершенству...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

Всегда пытался понять - для чего второе условие?

val = digitalRead(PirPin);

 if(val == HIGH) {
   ...
 } else if(val == LOW){
   ...
 }

Ну, как для чего? Описания же нет, может она volatile?

kalapanga
Offline
Зарегистрирован: 23.10.2016

А ещё красивее и читабельнее будет если переменные осмысленно обзывать. Чтобы было не if(myVal), а например if(buttonPressed) или if(motionDetected).

sadman41
Offline
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:

Ну, как для чего? Описания же нет, может она volatile?

А какая опасность в чтении волатильной uint8_t? Мне так, для ума...

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

ЕвгенийП пишет:

Ну, как для чего? Описания же нет, может она volatile?

А какая опасность в чтении волатильной uint8_t? Мне так, для ума...

Пмсм, Евгений имел в виду неатомарность операций, и тот случай, когда между if и else if переменная с квантификатором volatile поменяла своё значение (в прерывании, например).

З.Ы. А вот реально не хватает иногда мьютексов и семафоров "искаропки", программирование на взрослых компах развращает :)

himikat
Offline
Зарегистрирован: 21.06.2016

При данном коде 

unsigned long tim_e=0;
byte transPin = 5;  // инициализируем пин для транзистора
byte PirPin = 8;  // PIR инициализируем пин для получения сигнала от пироэлектрического датчика движения
boolean pirState = LOW;  // состояние датчика
boolean val = 0;  // переменная для чтения состояния пина
int fadeValue = 0; // переменная для плавного вкл ленты
byte count = 0;

void setup() {
  Serial.begin (9600);
  pinMode(transPin, OUTPUT);  // объявляем светодиод в качестве  OUTPUT
  pinMode(PirPin, INPUT);  // объявляем датчик в качестве INPUT
}
void loop() {
  if (millis() - tim_e > 5000) { // каждые 5 секунд смотрим
  tim_e = millis (); // приравниваем текущее с настоящим
  val = digitalRead(PirPin);  // считываем значение с датчика
  if ( val == HIGH ){ // сравниваем значения  переменной val
    Serial.println(val);
        for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 20) // цикл на плавное вкдючение
    {
      analogWrite(transPin, fadeValue); // выводим цикл на контакт транзистора
      delay(70);// задержка для плавного вывода
     }
     delay (5000); // ждем 15 сек    
         }
  else 
    Serial.println(val);
   digitalWrite (transPin, LOW);
   }
  //}
 if (millis() < tim_e) // если больше 50 дней то сбрасываем время в 0
 tim_e = millis();
}
//}

заметил идут сбои ( повторение цикла на плавное включение светодиода )

sadman41
Offline
Зарегистрирован: 19.10.2016

DIYMan пишет:

Пмсм, Евгений имел в виду неатомарность операций, и тот случай, когда между if и else if переменная с квантификатором volatile поменяла своё значение (в прерывании, например).

Это тоже понятно. Волатильные переменные я откидываю в ATOMIC, а потом только анализирую. 

Однако, я считал, что:
a) uint8_t считывается за такт и прерывание тут никак не попортит картину;
b) если анализ состояния начался, то игра с волатилью и несколькими условиями как раз и может породить состояние "наверное", когда не выполнится ни одна из ветвей, так как пока допрыгает МК до else - волатиль уже может перевернуться в HIGH. Первая ветка не выполнится, потому что переменная была LOW, а вторая ветка - потому что переменная уже успела стать HIGH.

himikat
Offline
Зарегистрирован: 21.06.2016

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

unsigned long tim_e=0;
byte transPin = 5;  // инициализируем пин для транзистора
byte PirPin = 8;  // PIR инициализируем пин для получения сигнала от пироэлектрического датчика движения
boolean pirState = LOW;  // состояние датчика
boolean val = 0;  // переменная для чтения состояния пина
int fadeValue = 0; // переменная для плавного вкл ленты
byte count = 0;

void setup() {
  Serial.begin (9600);
  pinMode(transPin, OUTPUT);  // объявляем светодиод в качестве  OUTPUT
  pinMode(PirPin, INPUT);  // объявляем датчик в качестве INPUT
}
void loop() {
 if (millis() - tim_e > 2000) { // каждые 5 секунд смотрим
 tim_e = millis (); // приравниваем текущее с настоящим
 val = digitalRead(PirPin);  // считываем значение с датчика
 switch (val){ // сравниваем значения  переменной val
  case (HIGH) :
    Serial.println(val);
    digitalWrite(transPin, HIGH); // выводим цикл на контакт транзистора
        //for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 20) // цикл на плавное вкдючение
  //  {
   //   analogWrite(transPin, fadeValue); // выводим цикл на контакт транзистора
   //   delay(50);// задержка для плавного вывода
    // }
    // delay (5000); // ждем 15 сек
     break;
  case (LOW):
   Serial.println(val);
   digitalWrite (transPin, LOW);
   break;
  }
  //}
}
}

 

himikat
Offline
Зарегистрирован: 21.06.2016

+ у меня стал нагреваеться датчик движения и стал выдавать всегда 0

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Волатильные переменные я откидываю в ATOMIC, а потом только анализирую. 

BTW, а есть ли у нас на форуме инфа для новичков, как кошерно работать с volatile? Что-то этот момент я упустил, а процитированное напомнило о, что называется. 

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

DIYMan пишет:

sadman41 пишет:

Волатильные переменные я откидываю в ATOMIC, а потом только анализирую. 

BTW, а есть ли у нас на форуме инфа для новичков, как кошерно работать с volatile? Что-то этот момент я упустил, а процитированное напомнило о, что называется. 

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DIYMan пишет:
кошерно работать с volatile?

Это в сымысле, что в Шабат не работать никак?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ЕвгенийП пишет:

DIYMan пишет:
кошерно работать с volatile?

Это в сымысле, что в Шабат не работать никак?

И это тоже :)

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

himikat пишет:

+ у меня стал нагреваеться датчик движения и стал выдавать всегда 0

Ищите, куда шаловливыми проводами потыкали или пином на OUTPUT. Чудес не бывает.

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

kalapanga пишет:

А ещё красивее и читабельнее будет если переменные осмысленно обзывать. Чтобы было не if(myVal), а например if(buttonPressed) или if(motionDetected).

Так в данном примере как раз правильно названо: "myVal" говорит о том, что это не реальный код, а демонстрационный пример.

himikat
Offline
Зарегистрирован: 21.06.2016

Пересобрал все на прото шилде нано , такая же беда . Постоянно горит сигнал на 1 , независимо от pir  датчика (HC-SR505,HC-SR501) 

unsigned long tim_e=0;
byte transPin = 5;  // инициализируем пин для транзистора
byte PirPin = 8;  // PIR инициализируем пин для получения сигнала от пироэлектрического датчика движения
boolean pirState = LOW;  // состояние датчика
boolean val = 0;  // переменная для чтения состояния пина
int fadeValue = 0; // переменная для плавного вкл ленты
byte count = 0;

void setup() {
  Serial.begin (9600);
  pinMode(transPin, OUTPUT);  // объявляем светодиод в качестве  OUTPUT
  pinMode(PirPin, INPUT);  // объявляем датчик в качестве INPUT
}
void loop() {
 //if (millis() - tim_e > 2000) { // каждые 5 секунд смотрим
 //tim_e = millis (); // приравниваем текущее с настоящим
 val = digitalRead(PirPin);  // считываем значение с датчика
 switch (val){ // сравниваем значения  переменной val
  case (HIGH) :
    Serial.println(val);
    digitalWrite(transPin, HIGH); // выводим цикл на контакт транзистора
        //for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 20) // цикл на плавное вкдючение
  //  {
   //   analogWrite(transPin, fadeValue); // выводим цикл на контакт транзистора
   //   delay(50);// задержка для плавного вывода
    // }
    // delay (5000); // ждем 15 сек
     break;
  case (LOW):
   Serial.println(val);
   digitalWrite (transPin, LOW);
   break;
  }
  //}
}
//}

 

himikat
Offline
Зарегистрирован: 21.06.2016

501 датчик не греется но все равно выдает постоянно 1 , 505 греется микросхема

himikat
Offline
Зарегистрирован: 21.06.2016

При том что вчера все работало отлично насчет греется или нет не помню , но то то работало все отлично это да. Менял только чуть код

himikat
Offline
Зарегистрирован: 21.06.2016

проверил еще на 1 датчике 501 , все работает правильно .

a5021
Offline
Зарегистрирован: 07.07.2013

andriano пишет:
Ну, что "объяснял", я не подвергаю ни малейшим сомнениям. Сомнения вызывает другое: поняли ли Вы эти объяснения, или решили делать так всегда вне зависимости от того, нужно это или не нужно.

Я вообще-то там уже описал, когда и как это может быть полезно. Читайте, а не предавайтесь сомнениям по поводу, понял ли лично я и как понял. Все, что касается меня лично, вас совершенно не должно волновать.

Цитата:
Кстати, в лучае логических переменных разумнее пользоваться if(myVar) либо if(!myVar) безо всяких "==".

Иногда разумнее, иногда нет.