Как улучшить работу кнопки включения/выключения

У меня есть простая схема, включающая и выключающая свет по нажатию кнопки. Он работает вполне нормально, но есть небольшая проблема с самим нажатием кнопки, он не полностью надежен. Включить свет — это хорошо, но выключить его сложно. В основном однократное нажатие почти никогда не работает. Мне нужно щелкнуть в нужный момент, чтобы выключить их, или лучше продолжать нажимать кнопку до нужного момента. Если я держу слишком долго, он также не работает или работает неправильно. Вот код цикла:

void loop() {
    int buttonState = digitalRead(BUTTON_PIN);
    if (buttonState == 1) active = not active;

    if (active) {
      
       ... led setup

      FastLED.show();
      FastLED.delay(1000 / UPDATES_PER_SECOND);
    } else {
      fill_solid( leds, NUM_LEDS, CRGB::Black);
      FastLED.show();
// FastLED.clear();
    }  
}

Что мне нужно сделать, чтобы он работал должным образом, а именно:

  • включение света одним нажатием
  • еще один щелчок или удерживание на некоторое время выключает свет навсегда, и они остаются выключенными до следующего щелчка.

, 👍-1

Обсуждение

использовать библиотеку Bounce2, @Juraj

Он называется "Debouncing" - по-моему, для него даже есть библиотека., @KIIV

Я второй Юрай. Библиотека Bounce2 отлично с этим справляется., @chrisl


1 ответ


0

Я думаю, что здесь происходит несколько вещей. Дебаунс уже упоминался, и я вовсе не хочу его сбрасывать со счетов — на эту тему есть масса информации.

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

конфигурация коммутатора

Для демонстрации я использовал эту простую настройку с переключателем:

Затем я изменил пример из библиотеки FastLED, чтобы просто переключать один светодиод (из 12 светодиодов, общего, неопиксельного кольца [без часов]) и запустил его на UNO (я знаю, что вы используете нано, но я думаю, что это все еще должно работать), используя этот код.

#include <FastLED.h>

#define NUM_LEDS 1

int LEDon = 0;
#define DATA_PIN 6

int switchPin = 8;

CRGB leds[NUM_LEDS];

void setup() {
  // ## Бестактные типы ##
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // предполагается порядок GRB
  pinMode(switchPin, INPUT);
  // начинаем с выключенным светодиодом (не обязательно)
  leds[0] = CRGB::Black;
  FastLED.show();
}

void loop() {
  if ( digitalRead(switchPin) == HIGH) { // переключатель нажат
    if (LEDon == 0) {
      LEDon = 1;
      leds[0] = CRGB::Red;
      FastLED.show();
    }
    else {
      LEDon = 0;
      leds[0] = CRGB::Black;
      FastLED.show();
    }
    while (digitalRead(switchPin) == HIGH); // ждем, пока переключатель не будет отпущен
  }
}

У меня нет большого опыта работы с этой библиотекой (она кажется очень мощной) и я не знаю, можете ли вы прочитать состояние (включено/выключено/цвет/интенсивность) светодиодов, поэтому я просто забился переменная (LEDon) для примера. Это работает нормально. Нет пропущенных нажатий, и вам нужно отпустить кнопку, прежде чем вы сможете нажать ее снова.

Обратите внимание, что я выполняю только минимальное количество действий, необходимое для поиска нажатия кнопки.

Библиотеки — это прекрасно, но вам нужно хорошо разбираться в их использовании. Я думаю, что вы выполняете трудоемкую обработку, из-за которой вы пропускаете нажатия, поэтому вы говорите: «Мне нужно нажать в нужный момент, чтобы отключить их, или лучше продолжайте нажимать кнопку до нужного момента”.

Я также думаю, что вы неправильно определяете прессу. В коде я специально ищу кнопку, которую нужно отпустить. Поскольку некоторое время тратится на обработку после обнаружения нажатия кнопки, мне не нужно явно устранять дребезг переключателя — для этого примера. Это не означает, что вам всегда это сойдет с рук.

Подумайте о том, насколько функционально расплывчато ваше определение прессы, • включение света одним нажатием • еще один щелчок или удержание на некоторое время выключает свет навсегда, и они остаются выключенными до следующего щелчка

Со всем уважением рекомендую вам:

Узнайте как можно больше о библиотеке. Взгляните, например, на это обсуждение FastLED.delay() https://github.com/FastLED/FastLED/issues /1206

Сделайте все возможное в setup().

Делайте как можно меньше времени между проверкой нажатия (или подумайте об использовании прерывания).

Надеюсь, это поможет.

,