Кнопка для запуска 5-кратной вспышки

Следующий код работает таким образом, что светодиод начинает мигать только при нажатии кнопки в течение одной секунды. Я хочу изменить это и сделать светодиодную вспышку в течение 5 раз, сразу при нажатии, независимо от того, удерживается ли кнопка "долго" или сразу же отпущена. Кто-нибудь может мне помочь? Кстати, я использую библиотеку LC_baseTools. Мне удалось сделать это с другой библиотекой с doFlash(5), но я должен работать с LC basetools в этом сценарии, и я не могу понять, как это сделать.

#include <mechButton.h>
#include <blinker.h>
 
#define BUTTON_PIN   11
#define LED_PIN      13
#define BLINK_MS     500.0
#define HOLD_MS      1000
 
mechButton  theButton(BUTTON_PIN);                    // Освобожденный объект кнопки. (Кнопка крючка между выводом и заземлением)
blinker     theBlinker(LED_PIN,BLINK_MS/2,BLINK_MS);  // A fire and forget blinker object.
timeObj     pushTimer(HOLD_MS);                       // Объект таймера
     
void setup(void) {
   theBlinker.setOnOff(false);            // Убедитесь, что мигалка выключена.
   theButton.setCallback(btnClicked);     // обратный вызов для кнопки.
}
     
// This gets called when the button is clicked.
void btnClicked(void) {
   if (!theButton.trueFalse()) {    // Если он был заземлен..
      pushTimer.start();            // Запуск таймера.
      theBlinker.setPercent(100);   // Установите мигалку в положение full on.
      theBlinker.setOnOff(true);    // Запустите его.
   } else {                         // Иначе, кнопка отпущена..
      theBlinker.setOnOff(false);   // Выключите мигалку.
   }
}
     
     
void loop(void) {
   idle();                             // idle запускает материал в фоновом режиме (button & binker)
   if (!theButton.trueFalse()) {       // Если кнопка в данный момент нажата..
      if (pushTimer.ding()) {          // Если таймер истек..
         theBlinker.setPercent(50);    // Начинай мигать!
      }
   }
}

, 👍0

Обсуждение

Я не знаю библиотеки, но, кажется, вы используете "pushTimer", чтобы получить такое длительное поведение прессы. Почему бы просто не использовать его, удалив внутренний оператор if в loop()? вы пробовали это?, @chrisl

@christl я не так хорошо разбираюсь, чтобы быть честным, но я попытаюсь смешать его с удалением этой части, посмотрим, что из этого выйдет, @Varonne

это послеобеденное хобби, я паяю и обжимаю, и arduino выходит из скуки lockdown, я только что занялся этими хобби, и, честно говоря, arduino полностью вне моей юрисдикции, я бы заплатил кому-то, чтобы, по крайней мере, направить меня на то, как это сделать, и у меня есть еще несколько идей, но нет знаний о кодировании, поэтому я думаю, что это неизбежно придет ко мне, заплатив кому-то, чтобы сделать это :D У меня нет времени, с моими обычными обязанностями и работой, чтобы заняться программированием arduino, это не так "кусок пирога", как многие люди предлагают., @Varonne

опять же, возьмите курс кодирования, @Juraj

@Varonne подумайте о пешеходном переходе ... пешеход непосредственно не просит водителей остановиться ... пешеход поднимает флаг " в виде красного светофора ... водители следят за красным светом........ положите слой разделения между нажатием кнопки и миганием светодиода ... нажатие кнопки устанавливает флаг, ничего больше .... светодиодный код мигания наблюдает за флагом и мигает, когда флаг поднимается .... флаг может иметь значение 5 ... когда код blink видит, что флаг ненулевой, он мигает светодиод один раз и уменьшает значение флага .... на следующей итерации loop()` он делает это снова ... и т. Д., @jsotola


2 ответа


1

Прежде всего, учитывая ваш комментарий: "У меня нет времени [...] заниматься программированием arduino" - Если вы не научитесь кодировать, то не сможете работать с кодом (а это включает в себя создание библиотек, которые вы найдете в Интернете). А обучение требует времени, это так просто.

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

#define BUTTON_PIN   11
#define LED_PIN      13

bool button_was_pressed=false;

void setup(){
  pinMode(LED_PIN,OUTPUT);
}

void loop() {
  if (digitalRead(BUTTON_PIN)) {
    if(!button_was_pressed) {
      for (int i=0;i<5;i++) {
        digitalWrite(LED_PIN,HIGH);
        delay(50);
        digitalWrite(LED_PIN,LOW);
        delay(50);
      }
    }
    button_was_pressed=true;
  }
  else {
    button_was_pressed=false;
  }
}

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

Мой совет заключается в том, что вы изучаете программирование структурированным образом, например, просматривая учебники. Сайт вопросов и ответов не является подходящим местом для этого, так как мы отвечаем только на вопросы.

,

Спасибо @Sim Сын по какой - то причине ваш код получает ошибку при компиляции, "если (digitalRead(BUTTON_PIN) {- ошибка: ожидаемое первичное выражение перед '}' токен", @Varonne

@Varonne отсутствует закрывающая скобка, @jsotola

@Varonne ответ, предоставленный VE7JRO, содержит гораздо лучший код. Мой был просто предназначен для того, чтобы показать вам, как такая вещь может быть реализована., @Sim Son


1

Мне удалось сделать это с другой библиотекой с "doFlash(5)", но я должен работать с LC basetools в этом сценарии, и я не могу понять, как это сделать.

Похоже, вам все еще разрешено писать код Arduino в своем скетче, так почему бы не использовать "концепцию" BlinkWithoutDelay и просто написать свой собственный код.

Я бы предпочел решение ООП для светодиодной мигающей части вашего требования.

// Arduino IDE 1.8.9.
// Sketch uses 1126 bytes (3%) of program storage space.
// Global variables use 25 bytes (1%) of dynamic memory.
class Flasher{

  private:

    byte ledPin;
    byte ledState;
    unsigned int flashCounter;
    unsigned long highTime;
    unsigned long lowTime;
    unsigned long previousMillis;

  public:

    Flasher(byte ledPinNumber, unsigned long ledOnTime, unsigned long ledOffTime){
      ledPin = ledPinNumber;
      ledState = LOW;
      highTime = ledOnTime;
      lowTime = ledOffTime;
      previousMillis = 0;
      pinMode(ledPinNumber, OUTPUT);
      digitalWrite(ledPinNumber, LOW);
    }

    void Update(){

      // Проверка, не пришло ли время изменить состояние светодиода.
      unsigned long currentMillis = millis();

      if((ledState == HIGH) && (currentMillis - previousMillis >= highTime) && ((flashCounter > 0))){
        ledState = LOW;
        previousMillis += highTime;
        digitalWrite(ledPin, ledState);
        if(flashCounter > 0){flashCounter--;}
      }
      else if((ledState == LOW) && (currentMillis - previousMillis >= lowTime) && ((flashCounter > 0))){
        ledState = HIGH;
        previousMillis += lowTime;
        digitalWrite(ledPin, ledState);
        if(flashCounter > 0){flashCounter--;}
      }
    }

    void Start(unsigned int flashNumberOfTimes){
      flashCounter = flashNumberOfTimes * 2;
      ledState = LOW;
      digitalWrite(ledPin, ledState);
    }

    void Stop(){
      Start(0);
    }

    void SetPinHighTime(unsigned long pinHighTime){
      highTime = pinHighTime;
    }

    void SetPinLowTime(unsigned long pinLowTime){
      lowTime = pinLowTime;
    }

};

// Flasher object_name(Pin Number, ON Time MS, OFF Time MS);
Flasher led1(LED_BUILTIN, 500, 500);

void setup(){

  // Мигнуть светодиодом 5 раз.
  led1.Start(5);

}

void loop(){

  // Вызовите функцию обновления как можно быстрее.
  led1.Update();

}

,

Смотрите мой комментарий по https://arduinoprosto.ru/q/60861/40646., @hcheung