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

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

  1. Alex20280

    Alex20280 Нерд

    Здравствуйте.

    Купил сенсорную кнопку Heltec (белая на фото). Но возникли сложности с ее работой.
    Подключаю плюск 3,3V, земля и сигнальный пин на D3 ардуино нано.
    Если к ней не касаться, она не работает, но если прикоснусь, то она мигает разными цветами и срабатывает раз за разом, тем самым все время тригерит сервопривод.
    До этого использовал другую кнопку (синяя на фото) и она работала коректно. Код не менялся.
    Код (C++):

    #define ctsPin 3
    #include <Servo.h>
    #define PIN_SERVO 5

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

    void loop()
    {
    int ctsValue = digitalRead(ctsPin);
    if (ctsValue == HIGH){
    feed(); //Сервопривод
    }

    }
    В чем может быть проблема? Спасибо.
     

    Вложения:

  2. b707

    b707 Гуру

    а как она еще должна действовать? цикл loop() исполняется очень быстро , каждый раз читает сигнал с кнопки - и если там HIGH - тригерит серву. За время. пока вы прикасаетесь к кнопке - этот цикл успевает обернутся тысячи раз.
    Все работает именно так, как написано в программе
     
    Igor68, arkadyf и Andrey12 нравится это.
  3. Alex20280

    Alex20280 Нерд

    Вы предлагаете ставить задержку? А где именно, в самом if или за ним?
     
  4. a1000

    a1000 Гуру

    В таком случае добавляется флаг для отслеживания была-ли нажата кнопка в предыдущей итерации
    Код (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
    }

    void loop()
    {
    int ctsValue = digitalRead(ctsPin);
    if (ctsValue == HIGH && flag)
      {
        feed(); //Сервопривод
        flag = false;  //сбрасываем флаг
      }
    if (ctsValue == LOW)
      {
        flag = true;  //устанавливаем флаг
      }
    }
     
    Igor68, b707, arkadyf и 2 другим нравится это.
  5. parovoZZ

    parovoZZ Гуру

    Там используются обрезки полноценной микросхемы из семейства TTP. У них параметры жёстко заданы при производстве с целью сокращения внешних ног. Возможно, что в твоём случае прописан триггерный режим работы: нажал - кнопка сработала, нажал ещё раз - кнопка отпустила.
     
  6. akl

    akl Гуру

    вроде это должно задаваться установкой резистора - и судя по фото, место под этот резистор на модуле имеется.
     
  7. a1000

    a1000 Гуру

    Скорее всего это выведена нога AHLB, которая определяет полярность выхода. 0 или 1 при касании сенсора. На китайских платках обозначают буквой "А"
    [​IMG]
    По умолчанию при "нажатии" 1. Если нужен 0 - на ногу надо подать Vcc, для чего площадки замыкают соплёй припоя.
    На площадки "В" выведена нога TOG. Если контакты не замкнуты то простой режим, если замкнуть (также на Vcc) - режим триггера.
    Нашёл описание белой кнопки. Написано работает в режиме триггера. Исправить в принципе можно отпаяв (откусив, перерезав) ногу TOG.
    [​IMG]
     
    akl и Andrey12 нравится это.
  8. ivan_alexoff

    ivan_alexoff Гик

    У меня такая же кнопка, только одноцветная и немного иначе монтаж на плате
    и работает именно в триггерном режиме
     
  9. Igor68

    Igor68 Гуру

    Только вот flag ключевое слово надо проверять всегда и прежде уровня ctsValue. Одним словом переделать всё конкретно. Но и этот вариант рабочий, только добавить ещё флаг активности исполнения
     
    Последнее редактирование: 18 сен 2020
  10. Alex20280

    Alex20280 Нерд

    Спасибо. Код работает, серво срабатывает только один раз, но вот кнопка после нажатия продолжает сетиться все время.
     
  11. Alex20280

    Alex20280 Нерд

    Можете подсказать что именно тут нужно отпаять/перерезать?
     

    Вложения:

  12. a1000

    a1000 Гуру

    Предложите свой вариант. Я ведь ещё учусь, хотелось посмотреть как правильно.
    На микросхеме есть маркировка?
     
  13. Alex20280

    Alex20280 Нерд

    Кажется написано 02А-4
     
  14. a1000

    a1000 Гуру

    Зря вас обнадёжил. По ходу там не TTP223-BA6. Как пишут люди там AT42QT1012, а эта микросхема работает только в режиме триггера.
     
    Andrey12 нравится это.
  15. Alex20280

    Alex20280 Нерд

    Выходит только програмно нужно отключать ее.
     
  16. a1000

    a1000 Гуру

    Скажем так, не отключать а игнорировать не нужные срабатывания.
     
  17. 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;
        feed(); //Сервопривод
        flag = false;  //сбрасываем флаг
      }
      else if ((ctsValue == LOW)  && (ctsValue_old != LOW)
      {
        ctsValue_old = LOW;
        flag = true;  //устанавливаем флаг
      }
    }
     
    Ну хотя бы так... ну или используйте ранее объявленный флаг
     
    Последнее редактирование: 19 сен 2020
  18. a1000

    a1000 Гуру

    Все мы учимся постоянно. Есть такая притча
    Однажды юный ученик философа Анаксимена спросил его, почему с каждым годом он всё больше сомневается в том, о чем раньше говорил без сомнений.
    Анаксимен начертил на песке два круга - маленький и большой - и объяснил:
    - Маленький круг - это мои знания в юности. Большой круг - это то, что я знаю и понимаю сегодня. С годами круг моих знаний увеличивается. Всё, что вне круга знаний - это незнание. Чем шире круг знаний, тем больше он соприкасается с незнанием и порождает всё больше сомнений и вопросов.
     
    KindMan и parovoZZ нравится это.
  19. a1000

    a1000 Гуру

    По коду. На мой взгляд эта конструкция немного сложновата
    Код (C++):
    else if ((ctsValue == LOW)  && (ctsValue_old != LOW)
      {
        ctsValue_old = LOW;
        flag = true;  //устанавливаем флаг
      }
    Давайте посмотрим как это будет в ASM.
    У нас 3 цифровой порт. Это нога PD3. Пусть мы будем сохранять PIND в R16. Следовательно надо контролировать состояние 2 бита R16.
    Код (C++):
    .def ctsValue = r16      // Присваиваем символические имена регистрам
    .def ctsValue_old = r17
    //......
    //......
    //......
    //......
    //......
    SBRC ctsValue,2       //проверяем состояние ноги с кнопкой
    RJMP exit             //если HIGH - уходим
    CPI ctsValue_old, 0b00000000 //сравниваем значение ctsValue_old с LOW
    BREQ exit             //если LOW - уходим
    LDI ctsValue_old, 0b00000000 //если оба условия выполнены ctsValue_old в LOW
    exit:                 //метка выхода
    //......
    //......
    //......
    Теперь предложенная мной конструкция
    Код (C++):
    if (ctsValue == LOW)
      {
        flag = true;  //устанавливаем флаг
      }
    и в ASM
    Код (C++):
    .def ctsValue = r16   // Присваиваем символические имена регистрам
    .def flag = r17       // Флаг в бите №0
    //......
    //......
    //......
    //......
    //......
    SBRC ctsValue,2       //проверяем состояние ноги с кнопкой
    RJMP exit             //если HIGH - уходим
    SBR  flag,0           //если LOW - устанавливаем флаг
    exit:                 //метка выхода
    //......
    //......
    //......
    Как по мне прощще.
     
  20. a1000

    a1000 Гуру

    Пока писал код для предыдущего поста возник один глобальный вопрос.
    Общепринято сохранять значение функции digitalRead() в переменную типа int. Так делается и во всех официальных примерах. Зачем????
    Функция digitalRead() возвращает однобитовое значение, а nt - имеет размер ДВА БАЙТА!!!! Это целых 16 бит.
    Как это будет представлено внутри МК
    HIGH - 0000000000000001
    LOW - 0000000000000000
    На мой взгляд нерационально.