Boolean и оператор if...else

Тема в разделе "Arduino & Shields", создана пользователем Jogovskiy, 11 янв 2021.

  1. a1000

    a1000 Гуру

    Ну так объясняйте понятно с самого начала. Даже тут додумывать надо. Пишите ясно и понятно. Свет включается и отключается нажатием кнопки. Если свет включен, на датчик не реагируем, если свет выключен, автоматический режим. Нате вам скетч
    Код (C++):
    int switchPin = 12;
    int ledPin = 11;
    int PIR=10;
    boolean lastButton = LOW;
    boolean currentButton = LOW;
    boolean ledOn = false;

    void setup()
    {
      pinMode(switchPin, INPUT);
      pinMode(ledPin, OUTPUT);
    }

    boolean debounce(boolean last)
    {
      boolean current = digitalRead(switchPin);
      if (last != current)
      {
        delay(5);
        current = digitalRead(switchPin);
      }
      return current;
    }

    void loop()
    {
      currentButton = debounce(lastButton);
      if (lastButton == LOW && currentButton == HIGH)
      {
        ledOn = !ledOn;
      }
      lastButton = currentButton;

      if(digitalRead(PIR)== HIGH && ledOn == LOW)
      {
        digitalWrite(LED, HIGH);
      }

      digitalWrite(ledPin, ledOn);

    }
    Только у вас кнопка к питанию подтянута, а тут к земле. Я думаю сможете переделать.
     
  2. a1000

    a1000 Гуру

    Глянул с утра, немного не так.
    Код (C++):
      if(digitalRead(PIR)== HIGH && ledOn == LOW)
      {
       ledOn = HIGH;
      }
     
  3. Jogovskiy

    Jogovskiy Нерд

    Код (C++):
    boolean LEDflag=false;

    const int LED=11;
    const int button=12;
    const int PIR=10;
    const int YLED=9; //желтый

    int val=0; //переменная значения напряжения фдиода
    int tek_button=LOW;
    int pred_button=LOW;

    void setup() {

    pinMode(LED, OUTPUT);
    pinMode(button, INPUT);
    pinMode(PIR, INPUT);
    pinMode(YLED, OUTPUT); //

    }
    //фильтр дребезга позаимствованный
    boolean debounce(boolean last)
    {
      boolean current = digitalRead(button);
      if(last !=current)
      {
        delay(5);
        current = digitalRead(button);
      }
      return current;
    }

    void loop() {

      tek_button=digitalRead(button);
    if (tek_button == HIGH && pred_button == LOW)
    {
      LEDflag=!LEDflag;
    }
    digitalWrite(LED, LEDflag);
    pred_button=tek_button;


    if(digitalRead(PIR) == HIGH){
      digitalWrite(LED, HIGH);   }
    else {
      digitalWrite(LED,LOW);
    }
    //желтый диод от фоторезистора
    val=analogRead (A1);

    if(val<300){
      digitalWrite(YLED, HIGH);
    }
    else {
      digitalWrite(YLED, LOW);
    }
    //следующая
    }
     
    Всем спасибо, результат своих дел прилагаю.
    Однако про номер строчки кода никто не ответил, самому считать?
     
  4. parovoZZ

    parovoZZ Гуру

    Строчка кода в IDE дурины или где?
     
  5. Jogovskiy

    Jogovskiy Нерд

    Когда на сайт добавляешь.
    Для удобства указать на ошибку
     
  6. a1000

    a1000 Гуру

    А что вы там вообще наваяли? Оно работает?
    Жёлтый светодиод вы включаете и выключаете по одному граничному значению. В момент перехода через 300 он будет хаотично моргать. Вряд-ли вы так задумывали. Надо включать если меньше 300 а выключать когда больше 310. Со значениями надо поэксперементировать для получения желаемого эфекта.
    Вы хотели
    Ну так у вас совсем не так. При включенном свете датчик никак не блокируется. Да и эти два куска кода очень сильно конфликтуют друг с другом. Очеь часто будут возникать моменты когда кнопка будет включать свет а датчик откючать и наоборот.
    А функцию антидребезга недостаточно просто вставить в код. К ней надо обращаться. У вас это где?
    Ну и вопрос - чем вас мой код не устроил?
     
  7. parovoZZ

    parovoZZ Гуру

    То, что хочет ТС, очень просто реализуется через машину состояний. Делать это через if.... да ну нафик.
    А если машину состоний опрашивать через конечное время, то и от функции антидребезга можно отказаться. Также на машине состояний очень просто отслеживаются длинные, короткие, одинарные, двойные и прочие нажатия. Зачем делать бессмысленные проверки с частотой 5 кГц, если это можно делать 1 раз в 20-50 мс.
     
  8. Jogovskiy

    Jogovskiy Нерд

    С желтым диодом отдельная история, но спасибо за замечание.
    Про мой код, да как ни странно оно работает как я и хотел (одно но, от кнопки диод светится тусклее, чем когда включается ПИР) ,однако при увеличение программы( подключения еще датчика влажности и серво, диод начал еще слабее гореть). Думаю, что это как-то связано с тем, что я использую правду/ложь. вместо 1/0. но никакой литературы по этому поводу не нашел.

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

    Сейчас пытаюсь побороть то, что диод тусклее светит и не терялась программная фиксация кнопки.
     
  9. Jogovskiy

    Jogovskiy Нерд

    Вариант неплохой, прочитал про конечные автоматы.
    То есть перед функцией напишу everyMillis(1000, цикл {} ) и он будет выполняться каждую секунду
     
  10. parovoZZ

    parovoZZ Гуру

    Конечные автоматы никак не связаны с
    Теория там, конечно же, с виду сложная, так как разработана под логику (ПЛИС). Реализация на МК в разы проще.
     
  11. Jogovskiy

    Jogovskiy Нерд

    Сложно, не понял, но направление милис рассмотрю
     
  12. a1000

    a1000 Гуру

    Ну да, немного затупил. В железе не проверял, доверился интуиции.
    Могли-бы и подправить
    Код (C++):
    int switchPin = 12;
    int ledPin = 11;
    int PIR=10;
    boolean lastButton = LOW;
    boolean currentButton = LOW;
    boolean ledOn = false;

    void setup()
    {
      pinMode(switchPin, INPUT);
      pinMode(ledPin, OUTPUT);
    }

    boolean debounce(boolean last)
    {
      boolean current = digitalRead(switchPin);
      if (last != current)
      {
        delay(5);
        current = digitalRead(switchPin);
      }
      return current;
    }

    void loop()
    {
      currentButton = debounce(lastButton);
      if (lastButton == LOW && currentButton == HIGH)
      {
        ledOn = !ledOn;
      }
      lastButton = currentButton;

      if(digitalRead(PIR)== HIGH && ledOn == LOW)
      {
       ledOn = HIGH;
      }
      if(digitalRead(PIR)== LOW && ledOn == LOW)
      {
       ledOn = LOW;
      }

      digitalWrite(ledPin, ledOn);

    }
    Это ни на что не влияет. HIGH / LOW, FALSE / TRUE это всё условности языка высокого уровня.
     
  13. Jogovskiy

    Jogovskiy Нерд


    И все равно нет.
    загружаю скетч (дописываю, что ПИР это вход),загружаю.
    от кнопки работает, нажал включилось, нажал выключилось. Если срабатывает ПИР, то свет включается, но сам не выключается. После 5 секунд его можно выключить кнопкой, если опять не сработает датчик.
    Ну оно и логично ledOn - это же состояние диода. последнее условие если ПИР 0 и состояние диода 0 { отключаем диод },
    а состояние диода то 1.
    Если поменять, что ПИР 0, а состояние 1, тогда ПИР работает как нужно, но кнопка игнорируется.
     
  14. Jogovskiy

    Jogovskiy Нерд

    Для меня загадка почему он по моему алгоритму не выключается
    первый if это кнопка, работает нормально
    Второй if если пир 1, то свет 1 (диод горит)
    Третий if, если пир 0, кнопка 0, диод 1 (диод тухнет, сам, а он не тухнет)
    Почему программа работает по другому алгоритму, не понимаю почему

    Код (C++):
    void loop() {

      if(digitalRead(button) ==HIGH && flag == 0){
        digitalWrite(LED, !digitalRead(LED));
        flag=1;
      }
      if(digitalRead(button) ==LOW && flag == 1){
        flag=0;
      }


    if(digitalRead(PIR) == HIGH){
      digitalWrite(LED, HIGH);   }
    if(digitalRead(PIR)==LOW && (button) ==LOW && (LED) == HIGH) {
      digitalWrite(LED,LOW);
    }
     
  15. a1000

    a1000 Гуру

    Стыдно мне товарищи, совсем расслабился.
    Код проверенный в работе.
    Код (C++):
    int switchPin = 12;
    int ledPin = 11;
    int PIR=10;
    boolean lastButton = LOW;
    boolean currentButton = LOW;
    boolean ledOn = false;
    boolean flag = false;

    void setup()
    {
      pinMode(switchPin, INPUT);
      pinMode(ledPin, OUTPUT);
    }

    boolean debounce(boolean last)
    {
      boolean current = digitalRead(switchPin);
      if (last != current)
      {
        delay(5);
        current = digitalRead(switchPin);
      }
      return current;
    }

    void loop()
    {
      currentButton = debounce(lastButton);
      if (lastButton == LOW && currentButton == HIGH)
      {
        ledOn = !ledOn;
        flag = ledOn;
      }
      lastButton = currentButton;

      if(digitalRead(PIR)== HIGH && !flag)
      {
       ledOn = HIGH;
      }
      if(digitalRead(PIR)== LOW && !flag)
      {
       ledOn = LOW;
      }

      digitalWrite(ledPin, ledOn);

    }
     
    Jogovskiy нравится это.
  16. parovoZZ

    parovoZZ Гуру

    я в своих темах-статьях описывал неоднократно.

    лучше смотреть в сторону программных таймеров. Использовать голый миллис крайне не удобно и код кривой.
     
  17. fogary

    fogary Гик

    Код в реальности такой, точь-в-точь? digitalRead перед (button) и (LED) не забыли дописать?
    Иначе, условие: (button) == LOW - не выполнится никогда, а условие: (LED) == HIGH - будет верно всегда, но до его проверки никогда не дойдет.
     
  18. Jogovskiy

    Jogovskiy Нерд

    да,это работает! СПАСИБО ! Вопрос только для понимая, флаг это состояние кнопки?
    то есть
    если пир 1, состояние кнопки инвертировалось >> оно горит
    если пир 0, состояние кнопки инвертировалось >> оно не горит
    или не так?
     
  19. Jogovskiy

    Jogovskiy Нерд

    А как ваши темы/статьи найти, в профиле где-то не увидел, или искать на форуме по похожим названиям. Сайтом пользоваться только начинаю
     
  20. Jogovskiy

    Jogovskiy Нерд

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