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

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

Метки:
  1. PAUK

    PAUK Нерд

    Доброго времени суток!
    У меня вопрос на счёт чтения цифрового порта.
    Может кому-то покажется глупо, но я не знаю, и подскажите пожалуйста.
    Если в начале скетча до цикла for применить функцию sensorState = digitalRead(sensorPin); и если затем переменную sensorState использовать в цикле for, будет ли она меняться в соответствии с состоянием на входе sensorPin до выхода из цикла for?
    Привожу мой код, будет ли он корректно работать?

    Код (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);
      // initialize the sensor pin as an input:
      pinMode(sensorPin, INPUT);
    }

    void loop() {
      // read the state of the sensor value:
      sensorState = digitalRead(sensorPin);

      // check if the sensor is on.
      if (sensorState == LOW) {
          // 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);
          }
      }
         
      delay(timeout);
         
      // 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 (sensorState == LOW) {
              fadeValue = -1;
          }
      }
    }
     

    Вложения:

  2. Asper Daffy

    Asper Daffy Иксперд

    Если прийти в банкомат и выгрести всё с карты в карман, а потом уйти оттуда. Будет ли количество денег в кармане изменяться в соответствии с текущим состоянием счёта карты?
     
  3. mcureenab

    mcureenab Гуру

    Код (C++):
    sensorState = digitalRead(sensorPin);
    Значение функции C/C++ не вычисляется без вызова. Чтобы вычислить функцию x нужно написать

    x (аргументы).

    А чтобы значение сохранилось в переменной v, нужно вызвать оператор присваивания.

    v = x (аргументы);


    Значение переменной может изменяться без явного присваивания. Например, в прерывании.
     
  4. parovoZZ

    parovoZZ Гуру

    Чтобы работало так, как ты хочешь (т.е. в переменную положили значение порта, а потом отслеживать только значение переменной), необходимо использовать указатели. То бишь относительную адресацию вместо абсолютной. Но я тебе этого не говорил - чтобы это осознать, необходимо выйти из под власти ардуино.
    В твоём примере кода нет никакого смысла в переменной sensorStat, если значение и так лежит в регистре порта. Ни к чему, кроме как к утечке памяти, это не приведёт. Впрочем, компилятор эту переменную вырежет.
     
  5. citRUS_oleg

    citRUS_oleg Нерд

    а можно поинтересоваться, "sensor" - это кнопка?
     
  6. mcureenab

    mcureenab Гуру

    ??? Какая утечка? Какие указатели? При чём тут всё это?
     
    Gritsan нравится это.
  7. fogary

    fogary Гик

    Так у Вас значение fadeValue будет выходить за диапазон допустимых значений. Т. е. в первом случае, последнее значение fadeValue будет: 256, а во-втором: -1.
    А так, не будет:
    Код (C++):
          for (int fadeValue = brightness ; fadeValue < 255; fadeValue++) {
          // sets the value (range from 0 to 255):
    . . .
      for (int fadeValue = 255 ; fadeValue > 0; fadeValue--) {
          // sets the value (range from 0 to 255):
    Что, по Вашему замыслу делает этот кусок кода?
    Код (C++):
    if (sensorState == LOW) {
      fadeValue = -1;
    }
     
    Последнее редактирование: 26 мар 2018
  8. PAUK

    PAUK Нерд

    К сожаления мне нужно это сделать без прерываний, получится?
     
  9. PAUK

    PAUK Нерд

    Это датчик присутствия.
     
  10. PAUK

    PAUK Нерд

    А как это будет проявляться?
    Завершает цикл если датчик снова сработал.
     
  11. parovoZZ

    parovoZZ Гуру

    Внимательно первый пост читал? ТС хочет некую переменную. которая бы самостоятельно отслеживала регистр порта. Без относительной адресации это сделать невозможно. Но это бессмысленно и не профессионально - текущее значение порта лежит в его регистре. Чтение регистра порта ничем не отличается от чтения регистра, в котором лежит переменная. Спрашивается - зачем плодить сущности? Зачем на это тратить целый байт памяти? Скажу по секрету - компилятор поумнее ардуинщиков (программистами их назвать как-то язык не поворачивается) - весь этот бред будет оптимизирован.
     
    Андрей Ипатов нравится это.
  12. PAUK

    PAUK Нерд

    Вы предлагаете каждый раз, когда нужно узнать состояние порта, использовать digitalRead(sensorPin);
     
  13. b707

    b707 Гуру

    Нет, Паровоз предлагает другое - вместо переменной SensorState работать напрямую с содержимым регистра. Но по смыслу это ровно то же самое - каждый раз, когда вам нужна SensorState - ее нужно ЗАНОВО СЧИТАТЬ из порта. Можно методом digitalRead(sensorPin);, а можно как предлагает Паровоз.
    И об этом вам твердят уже 10 сообщений - а до вас все не доходит.
     
    Андрей Ипатов нравится это.
  14. parovoZZ

    parovoZZ Гуру

    Лучше использовать макрос на сях. Я это где-то уже выкладывал.
    АЛУ не может оперировать переменными в ОЗУ (поправьте. В архитектуре 8051 именно так). Поэтому из ОЗУ переменная заносится в один из РОН для совершения любой булевой операции. Но регистр порта тот же РОН со статичным адресом, заданном при производстве.
     
  15. PAUK

    PAUK Нерд

    Я что то нигде не увидел примера по этому поводу.
     
  16. mcureenab

    mcureenab Гуру

    Потому что Паровоз предлагает читать регистр порта, а не состояние пина. А это разные вещи.
     
  17. PAUK

    PAUK Нерд

    Да, это понятно, но как это сделать. Так я тоже могу предложить слетать на Аляску.
     
  18. Позвольте вклиниться в обсуждение ...
    mcureenab, я правильно понимаю, что если переменная меняется внутри прерывания, то при ее объявлении обязателен модификатор доступа volatile ? или есть случаи объявления, когда он не нужен ?
    Вот например, сылка на русский офдок
    http://arduino.ru/Reference/AttachInterrupt
    Те примеры которые я видел содержали объявление меняемой переменной до функции setup.
    Поправьте если не прав,
    1. получается что меняемая в прерывании переменная - статичная
    и объявляется до setup с модификатором
    2. судя по офдокам все меняемые прерыванием переменные содержат модификатор volatile
     
    Последнее редактирование: 27 мар 2018
  19. fogary

    fogary Гик

    Это вопрос к знатокам низкоуровневых команд. В самой функции проверок диапазона нет.
     
  20. parovoZZ

    parovoZZ Гуру

    Да. В этом случае компилятор не применяет никакой оптимизации к такой переменной. В противном случае, при выходе из прерывания значение переменной становится прежним (до прерывания).
     
    Андрей Ипатов нравится это.