Чтение цифровых портов

Тема в разделе "Arduino & Shields", создана пользователем PAUK, 24 мар 2018.

Метки:
  1. parovoZZ

    parovoZZ Гуру

    Завершнием цикла for тогда, когда ардуинщик этого не ждет. Задействованная в проверке цикла переменная уничтожается.
     
  2. PAUK

    PAUK Нерд

    Если честно, то меня тоже это насторожило, но код взят из стандартного примера Arduino IDE:

    Код (C++):
    /*
      Fading

      This example shows how to fade an LED using the analogWrite() function.

      The circuit:
      - LED attached from digital pin 9 to ground.

      created 1 Nov 2008
      by David A. Mellis
      modified 30 Aug 2011
      by Tom Igoe

      This example code is in the public domain.

      http://www.arduino.cc/en/Tutorial/Fading
    */


    int ledPin = 9;    // LED connected to digital pin 9

    void setup() {
      // nothing happens in setup
    }

    void loop() {
      // fade in from min to max in increments of 5 points:
      for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
        // sets the value (range from 0 to 255):
        analogWrite(ledPin, fadeValue);
        // wait for 30 milliseconds to see the dimming effect
        delay(30);
      }

      // fade out from max to min in increments of 5 points:
      for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
        // sets the value (range from 0 to 255):
        analogWrite(ledPin, fadeValue);
        // wait for 30 milliseconds to see the dimming effect
        delay(30);
      }
    }
     
  3. parovoZZ

    parovoZZ Гуру

    Код должен быть написан осознанно, из головы, а не бездумно скопирован. Иначе рискуешь бултыхаться в лягушатнике всю оставшуюся жизнь.
     
  4. PAUK

    PAUK Нерд

    Хорошо поговорили, если бы был толк...
     
    Gritsan нравится это.
  5. Спасибо, как раз хотел следующим постом спросить что случилось бы со значением из прерывания, но вы сразу ответили на незаданный вопрос :)
     
  6. PAUK, почитал я ветку. Не знаю, будет ли мое мнение авторитетно на фоне остальных гиков, то мой ответ на заданный вначале темы вопрос такой
    кхм ...
    1. вот этот код (второй цикл for после задержки)
    Код (Text):

    if(sensorState == LOW){
              fadeValue =-1;
         }
     
    в том варианте как я его сейчас вижу, (имхо) не имеет шансов получить новое значение sensorState

    2. первое сравнение
    Код (Text):

    sensorState= digitalRead(sensorPin);

    // check if the sensor is on.
    if(sensorState == LOW){
     
    получит актуальное значение датчика,
    кусок кода 2 будет (скорее всего) работать корректно.
    кусок кода 1 - нет
    имхо самое простое исправление (но не самое красивое) - перед if из куска 2, который использует sensorState, ПЕРЕЧИТЫВАТЬ его любым доступным для вас способом.

    но повторюсь это имхо человека, быстро посмотревшего ваш код. Успехов !
     
    PAUK нравится это.
  7. SergeiL

    SergeiL Оракул Модератор

    А чего вы накинулись то? :)
    Нормальный код, в начале темы, все с первого взгляда должно работать! :)

    Единственное в setup(), нужно сделать начальную инициализацию ШИМ к примеру 0,
    и включить подтяжку на входе с датчика. Ну и digitalRead(sensorPin); поставить во второй for, вместо проверки переменной sensorState.
     
    Последнее редактирование: 27 мар 2018
    PAUK нравится это.
  8. Да, согласен (имхо) :)
     
    PAUK нравится это.
  9. PAUK

    PAUK Нерд

    Да, точно так и сделал, кроме подтяжки, так как подтяжка уже имеется в самом датчике. Всем спасибо!
     
  10. parovoZZ

    parovoZZ Гуру

    А куда смотреть? В убогой ИДЕ ардуино нет отладчика. Значит и посмотреть негде.
     
  11. SergeiL

    SergeiL Оракул Модератор

    Ну как негде. В голове трассироваться можно:)
     
  12. SergeiL

    SergeiL Оракул Модератор

    Не, посмотрел внимательнее нужно убирать delay(timeout); из цикла :(
    Иначе будете пропускать срабатывания датчика пока в delay() находитесь.
    В данном варианте, у Вас состояние датчика, проверяется 1 раз в 5 секунд.
     
  13. PAUK

    PAUK Нерд

    Вы очень внимательны, это тоже уже убрал, благодарю!
     
  14. SergeiL

    SergeiL Оракул Модератор

    Правильнее будет как-то так, чуть подправил. :)
    (Сразу поредупреждаю - не проверял, могут быть ошибки)
    Код (C++):
    // set pin numbers:
    const int sensorPin = 12;     // the number of the sensor pin
    const int PWMPin =  11;       // the number of the PWM out pin

    // variables will change:
    //int sensorState = 1;         // variable for reading the sensor status
    int brightness = 0;          // how bright the LED is when the programm start
    int timeout = 5000;          // how many time is full bright in milliseconds

    void setup() {
      // initialize the PWM pin as an output:
      pinMode(PWMPin, OUTPUT);
      analogWrite(PWMPin, 0);
      // initialize the sensor pin as an input:
      pinMode(sensorPin, INPUT);
    }

    void loop()
    {
      static uint32_t ON_millis = 0; // переменная для хранения времени включения
      static uint8_t ON_flag = 0;   // флаг включенного датчика

      // read the state of the sensor value:

      // check if the sensor is on.
      if (digitalRead(sensorPin) == LOW )
      {
              // Можете раскоментировать строчку ниже, тогда время будет считаться с момента пропадания  LOW на входе, а не с первого обнаружения LOW
              // то есть все последующие срабатывания входа будут увеличивать время. Светодиод выключится, если за время timeout LOW, обнаружено не было.
     
        // ON_millis=millis();  // 5 секунд с последнего обнаружения LOW
     
        if (!ON_flag)  // светодиод не включен - включаем
        {
          ON_flag=1;
          ON_millis=millis();  // 5 секунд с момента включения

            // fade in from min to max in increments of 1 points:
          for (int fadeValue = brightness ; fadeValue <= 255; fadeValue += 1)   // sets the value (range from 0 to 255):
          {
            brightness = fadeValue;    // how bright the LED is
            analogWrite(PWMPin, brightness);
              // wait for 2 milliseconds to see the dimming effect
            delay(2);
          }
        }
      }
      else if (millis() - ON_millis > timeout && ON_flag )  //если с моента включения прошл timeout и сейчас датчик в HIGH и светодиод включен - выключаем
      {
        ON_flag=0;
        // fade out from max to min in increments of 1 points:
        for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 1)       // sets the value (range from 0 to 255)
        {
          brightness = fadeValue;    // how bright the LED is
          analogWrite(PWMPin, brightness);
          // wait for 5 milliseconds to see the dimming effect
          delay(5);
          if (digitalRead(sensorPin) == LOW) {
              fadeValue = -1;
          }
        }
      }
    }
     
    Последнее редактирование: 28 мар 2018
    PAUK нравится это.
  15. mcureenab

    mcureenab Гуру

    Увы, это не так. Значение глобальной переменной (ячейки оперативной памяти, в которой хранится значение переменной) изменится после выполнения оператора присваивания до выхода из обработчика прерывания.

    Но на стороне функции, которая читает значение переменной без модификатора volatile компилятор может скопировать её значение в регистр процессора и далее читать не память переменной, а регистр.
    Возможно, компилятор сразу вычислит выражения с этой переменной и оптимизирует код.

    В итоге имеем неопределённое поведение.
     
  16. PAUK

    PAUK Нерд

    Большое Вам спасибо, я тоже за это время кое что изменил, взгляните пожалуйста:
    Код (C++):
    /*
    Reading sensor status and if it's LOW
    turn the LED on with PWM from 0 to 255
    and after timeout turn the LED off
    with PWM dimming from 255 to 0.
      */


    // set pin numbers:
    const byte sensorPin = 12;     // the number of the sensor pin
    const byte PWMPin = 11;        // the number of the PWM out pin

    // set on time in seconds
    #define ontime 5               // how many time is full bright in seconds

    // variables
    int brightness = 0;            // how bright the LED is when the programm start
    long timeout = ontime*1000;    // convert time is full bright seconds to milliseconds

    void setup() {
      // initialize the PWM pin as an output:
      pinMode(PWMPin, OUTPUT);
      // initialize the sensor pin as an input:
      pinMode(sensorPin, INPUT);
    }

    void loop() {
      analogWrite(PWMPin, brightness);
      // check if the sensor is on.
      if (digitalRead(sensorPin) == LOW) {
          // fade in from min to max in increments of 5 points:
          for (int fadeValue = brightness ; fadeValue <= 255; fadeValue += 5) {
          // sets the value (range from 0 to 255):
          brightness = fadeValue;    // how bright the LED is
          analogWrite(PWMPin, brightness);
          // wait for 2 milliseconds to see the dimming effect
          delay(2);
          }
          delay(timeout);
      }

      // fade out from max to min in increments of 5 points:
      for (int fadeValue = brightness ; fadeValue >= 0; fadeValue -= 5) {
          // sets the value (range from 0 to 255):
          brightness = fadeValue;    // how bright the LED is
          analogWrite(PWMPin, brightness);
          // wait for 5 milliseconds to see the dimming effect
          delay(5);
          if (digitalRead(sensorPin) == LOW) {
              fadeValue = -5;
          }
      }
    }
     
    Логика должна быть такой: при срабатывании сенсора начинает светиться светодиод от 0 до 255 и затем в течении 5 секунд на полной яркости, а потом должен начать медленно гаснуть, но если в это время сенсор снова сработает, то яркость опять должна увеличиться до максимальной и снова на 5 секунд.
     
  17. SergeiL

    SergeiL Оракул Модератор

    Да не за что! :)
    На первый взгляд - все правильно, должно работать! :)
    Я бы только перенес первый analogWrite(PWMPin, brightness) в конец setup()
    Ну и выход из второго for можно сделать по break;
    Оператор break позволяет прервать любой цикл ( for(), while(), do while() )
    в любом месте.
    Но это, необязательные правки.
    Код (C++):
    /*
    Reading sensor status and if it's LOW
    turn the LED on with PWM from 0 to 255
    and after timeout turn the LED off
    with PWM dimming from 255 to 0.
      */


    // set pin numbers:
    const byte sensorPin = 12;     // the number of the sensor pin
    const byte PWMPin = 11;        // the number of the PWM out pin

    // set on time in seconds
    #define ontime 5               // how many time is full bright in seconds

    // variables
    int brightness = 0;            // how bright the LED is when the programm start
    long timeout = ontime*1000;    // convert time is full bright seconds to milliseconds

    void setup() {
      // initialize the PWM pin as an output:
      pinMode(PWMPin, OUTPUT);
      // initialize the sensor pin as an input:
      pinMode(sensorPin, INPUT);
      analogWrite(PWMPin, brightness);
    }

    void loop() {
      // check if the sensor is on.
      if (digitalRead(sensorPin) == LOW) {
          // fade in from min to max in increments of 5 points:
          for (int fadeValue = brightness ; fadeValue <= 255; fadeValue += 5) {
          // sets the value (range from 0 to 255):
          brightness = fadeValue;    // how bright the LED is
          analogWrite(PWMPin, brightness);
          // wait for 2 milliseconds to see the dimming effect
          delay(2);
          }
          delay(timeout);
      }

      // fade out from max to min in increments of 5 points:
      for (int fadeValue = brightness ; fadeValue >= 0; fadeValue -= 5) {
          // sets the value (range from 0 to 255):
          brightness = fadeValue;    // how bright the LED is
          analogWrite(PWMPin, brightness);
          // wait for 5 milliseconds to see the dimming effect
          delay(5);
          if (digitalRead(sensorPin) == LOW) {
              break;
          }
      }
    }
     
     
    PAUK нравится это.
  18. PAUK

    PAUK Нерд

    Так лучше, я не знал про него. Вы реально помогли мне, благодарю!
     
    Последнее редактирование: 28 мар 2018
  19. fogary

    fogary Гик

    Можно и без break:
    Код (C++):
    void loop() {
      if (digitalRead(sensorPin) == LOW) {
        while (brightness < 255) {
          brightness += 5;  
          analogWrite(PWMPin, brightness);  
          delay(2);
        }

        delay(timeout);

        do {
          brightness -= 5;
          analogWrite(PWMPin, brightness);
          delay(5);
        } while ((brightness > 0) && (digitalRead(sensorPin) == HIGH));
      }
    }
     
  20. PAUK

    PAUK Нерд

    Да, если честно, то с самого начала Я так и написал, но потом переделал на опубликованный вариант, но тоже неплохая идея, спасибо!
    Только вот Я не определился на счёт второго цикла, он обязательно должен быть do while ?
     
    Последнее редактирование: 28 мар 2018