Сенсорная кнопка все время срабатывает

Тема в разделе "Arduino & Shields", создана пользователем Alex20280, 18 сен 2020.

  1. akl

    akl Гуру

    тащемта, оно как раз возвращает int
    Код (C++):

    int digitalRead(uint8_t pin)
    {
        uint8_t timer = digitalPinToTimer(pin);
        uint8_t bit = digitalPinToBitMask(pin);
        uint8_t port = digitalPinToPort(pin);

        if (port == NOT_A_PIN) return LOW;

        // If the pin that support PWM output, we need to turn it off
        // before getting a digital reading.
        if (timer != NOT_ON_TIMER) turnOffPWM(timer);

        if (*portInputRegister(port) & bit) return HIGH;
        return LOW;
    }
    зачем его так сделали - непонятно. возможно ради какой-нибудь совместимости
     
  2. a1000

    a1000 Гуру

    Взял базовый тестовый пример DigitalReadSerial
    Код (C++):
    int pushButton = 2;

    // the setup routine runs once when you press reset:
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
      // make the pushbutton's pin an input:
      pinMode(pushButton, INPUT);
    }

    // the loop routine runs over and over again forever:
    void loop() {
      // read the input pin:
      int buttonState = digitalRead(pushButton);
      // print out the state of the button:
      Serial.println(buttonState);
      delay(1);        // delay in between reads for stability
    }
    Поменял тип переменной buttonState
    Код (C++):
    int pushButton = 2;

    // the setup routine runs once when you press reset:
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
      // make the pushbutton's pin an input:
      pinMode(pushButton, INPUT);
    }

    // the loop routine runs over and over again forever:
    void loop() {
      // read the input pin:
      boolean buttonState = digitalRead(pushButton);
      // print out the state of the button:
      Serial.println(buttonState);
      delay(1);        // delay in between reads for stability
    }
    Всё скомпилировалось, загрузилось и заработало.
    А в функции
    Код (C++):
    int digitalRead(uint8_t pin)
    какой-то не порядок. Объявлена как int, а возвращает
    Код (C++):
    return LOW;
    .
    .
    .
    return HIGH;
    Может так и должно быть? Я в тонкости С не вникал. Из Arduino в ASM шагнул. Там с этим проще. Никакой типизации переменных. Прикинул что получится - выделил необходимую память и всё.
     
  3. akl

    akl Гуру

    LOW и HIGH не имеют типа, это всего лишь дефайны
    Код (C++):

    #define HIGH 0x1
    #define LOW  0x0
     
    то есть голые цифры, а не переменные.
     
    issaom нравится это.
  4. a1000

    a1000 Гуру

    Но в булевую переменную влезли без проблем.
     
  5. Igor68

    Igor68 Гуру

    Совсем забыл, но наверное и сами догадались про это:
    Код (C++):
    #define ctsPin 3
    #include <Servo.h>
    #define PIN_SERVO 5

    boolean flag = true;   //флаг нажатия кнопки

    void setup()
    {
      Serial.begin(9600);
      pinMode(ctsPin, INPUT);
      feedServo.attach(5); // привязываем сервопривод к аналоговому выходу 5
    }

    int ctsValue_old = LOW;
    void loop()
    {
      int ctsValue = digitalRead(ctsPin);
      if ((ctsValue == HIGH)  && (ctsValue_old != HIGH)
      {
        ctsValue_old = HIGH;
        //это если надо переключать при переходе от LOW в HIGH
       /*
          if(flag)
             flag = false;
          else
             flag = true;
       */

      }
      else if ((ctsValue == LOW)  && (ctsValue_old != LOW)
      {
        ctsValue_old = LOW;
       //это если надо переключать при переходе от HIGH в LOV
       /*
          if(flag)
             flag = false;
          else
             flag = true;
       */

      }
    }
     
    т.е в одном случае при нажатии кнопки, в другом при отпускании. Что по смыслу практически одно и то же
     
  6. Igor68

    Igor68 Гуру

    Можно и в ASM, только система команд у меня не на слуху.
     
  7. parovoZZ

    parovoZZ Гуру

    она с лёгкостью заменяется на конструкцию вида
    Код (C++):
    uint8_t BUTTON_PRESS = (PORTC.IN & PIN5_bm);
    В старых авэрах названия битов и регистров другие.
    Выполнение 3 или 4 такта.
     
  8. Igor68

    Igor68 Гуру

    И никаких delay вообще не надо... раскоментировать нужное(только одно нужное) и всё - схема flip-flop готова. Флагом flag что-то вкючать/выключать. Типа:
    Код (C++):
    ...
    ...
    if(flag)
       ServoOn();
    else
       ServoOff();
    ...
    ...
     
    Последнее редактирование: 20 сен 2020
  9. Igor68

    Igor68 Гуру

    Так применяйте маску типа:
    Код (C++):

    #define _bit0   0x01
    #define _bit1   0x02
    #define _bit2   0x04
    #define _bit3   0x08
    #define _bit4   0x10
    #define _bit5   0x20
    #define _bit6   0x40
    #define _bit7   0x80
    uint8_t mask;
    //
    ..
    //установка флага
    mask  |= _bit1;
    ..
    //сброс флага
    mask  &= (~(_bit1));

    //проверка флага
    if(mask & _bit1) {
       //что-то делаем
    } else {
       //делаем что-то другое или ничего(тогда секция else вообще не нужна)
    }

     
    На все 8 возможных флага 1 байт(по биту на каждый)
     
    Последнее редактирование: 20 сен 2020
  10. issaom

    issaom Гуру

    Если вы про это пример:
    Код (C++):
    void loop(){
      // считываем значения с входа кнопки
      buttonState = digitalRead(buttonPin);
      // проверяем нажата ли кнопка
      // если нажата, то buttonState будет HIGH:
      if (buttonState == HIGH) {
        // включаем светодиод
        digitalWrite(ledPin, HIGH);
      }
      else {
        // выключаем светодиод
        digitalWrite(ledPin, LOW);
      }
    }
    То его вообще можно переписать в одну строчку переписать:
    Код (C++):
    void loop(){
        digitalWrite(ledPin, digitalRead(buttonPin));
    }
    Вот только новичкам будет сложно понять что тут происходит ))) поэтому везде пишут просто int. Не все знают как хранятся числа внутри железяк, да и для сборки девайса типа который будет включать вентилятор в ванной если влажность превысила определенное значение это вообще не принципиально.
     
  11. a1000

    a1000 Гуру

    Написать можно, синтаксис разрешает. Но компилятор снова развернёт всё в предыдущую портянку и наплодит кучу кода. Функции digitalRead и digitalWrite отработают от начала и до конца.
    По digitalRead - будет вычислен таймер (для вводов с ШИМ), вычеслен порт, вычеслен пин. Проверена корректтность заданного пина, В случае необходимости остановлен таймер ШИМ, и уже потом проверено состояние нужного пина и в зависимости от результата выдаётся на гора HIGH или LOW.
    Функция digitalWrite тоже проводит такие-же вычисления и проверки по номеру заданного ней пина, выполняет магию с таймером и только потом, на основании полученного результата от digitalRead выставляет ledPin в нужное состояние.
    Что можно сделать, если писать сразу в ASM?
    С помощью инструкции SBIC "щупаем" нужный нам бит непосредственно в регистре PINx нужного нам порта. По результатам устанавливаем или сбрасываем нужный бит в регистре PORTх нужного порта. И все! Уложимся менее чем в 10 тактов. А строку
    Код (C++):
    digitalWrite(ledPin, digitalRead(buttonPin));
    компилятор растянет тактов на 50-80.
     
    parovoZZ нравится это.
  12. b707

    b707 Гуру

    через регистры все это можно написать и на Си - причем тактов едва ли будет больше
     
  13. parovoZZ

    parovoZZ Гуру

    В Си нету побитовой записи в регистр. Только через конструкцию «read-modify-write”. Догадается ли компилятор такую конструкцию заменить на одну операцию SBIC - gcc так не делает. Впрочем, в atxmega и новых AVR есть регистры, на которые отображены биты IO регистров. Но такое я видел только у Atmel.
     
    Igor68 нравится это.