0

The following code operates in a way that LED starts to flash only if the pushbutton is pushed for one second. I want to change this and make the LED flash for 5 times, immediately on push, regardless if the button is held "long" or released immediately. Can anyone help me out with this? I'm using the LC_baseTools library btw. I managed to do this with another library with doFlash(5) but I have to work with LC basetools in this scenario and I can't figure out how to do it.

#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);                    // A debounced button object. (Hook button between pin & ground)
blinker     theBlinker(LED_PIN,BLINK_MS/2,BLINK_MS);  // A fire and forget blinker object.
timeObj     pushTimer(HOLD_MS);                       // A timer object
     
void setup(void) {
   theBlinker.setOnOff(false);            // Make sure the blinker is acutally off.
   theButton.setCallback(btnClicked);     // Set the callback for the button.
}
     
// This gets called when the button is clicked.
void btnClicked(void) {
   if (!theButton.trueFalse()) {    // If it has been grounded..
      pushTimer.start();            // Start the timer.
      theBlinker.setPercent(100);   // Set the blinker to full on.
      theBlinker.setOnOff(true);    // Fire it up.
   } else {                         // Else, button released..
      theBlinker.setOnOff(false);   // SHut off the blinker.
   }
}
     
     
void loop(void) {
   idle();                             // idle runs the stuff in the background (button & binker)
   if (!theButton.trueFalse()) {       // If the button is currently pressed..
      if (pushTimer.ding()) {          // If the timer has expired..
         theBlinker.setPercent(50);    // Start blinking!
      }
   }
}
5
  • 1
    I don't know the library, but it seems you are using pushTimer to get this long press behavior. Why just not using it by removing the inner if statement in loop()? have you tried that?
    – chrisl
    Apr 20 at 13:05
  • @chrisl im not that well versed to be honest, but i'll try to mix it up with removing that part, see what comes of it
    – Varonne
    Apr 20 at 13:22
  • 1
    it's afternoon hobby work, I am soldering and crimping and arduino'ing out of lockdown boredome, I just took up these hobbies and quite frankly the arduino stuff is fully out of my jurisdiction, i would pay someone to at least guide me on how to do it, and i have some more ideas but no coding knowledge so I think it will inevitably come to me paying someone to get ti done :D I don't have time, with my regular responsibilites and job, to tackle arduino programming, it's not as "piece of cake" as many people suggest.
    – Varonne
    Apr 20 at 14:20
  • 2
    again, take a coding course
    – Juraj
    Apr 20 at 19:55
  • 1
    @Varonne think of a pedestrian crosswalk ... the pedestrian does not directly ask the drivers to stop ... the pedestrian raises a flag in form of a red traffic light ... drivers watch for red light....... put a layer of separation between the button press and the LED blink ... pressing a button sets a flag, nothing else .... the LED blink code watches the flag and blinks when flag is raised .... the flag could have a value 5 ... when the blink code sees the flag being non-zero, then it blinks the LED once and decrements flag value .... on next iteration of loop() it does it again ... etc.
    – jsotola
    Apr 21 at 1:03
1

I managed to do this with another library with "doFlash(5)" but I have to work with LC basetools in this scenario and I can't figure out how to do it.

It looks like you are still allowed to write Arduino code in your sketch, so why not use the BlinkWithoutDelay "concept" and just write your own code.

I would favour an OOP solution for the LED flashing part of your requirement.

// 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(){

      // Check to see if it's time to change the state of the LED.
      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(){

  // Flash the LED 5 times.
  led1.Start(5);

}

void loop(){

  // Call the Update function as fast as possible.
  led1.Update();

}

1

First of all, considering your comment: "I don't have time [...] to tackle arduino programming" - If you don't learn how to code, then you can't work with code (and that includes putting together libraries you find on the internet). And learning takes time, it's that simple.

I recommend you forget about those libraries and implement that easy task from scratch, so you actually learn something. The below code has the logic you ask for, try to understand what it does.

#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;
  }
}

...pretty simple and it's only a few lines. You may want to debounce the button and use a non-blocking coding style, but that's a different chapter.

My advice is that you learn programming in a structured manner, e.g. by watching tutorials. A Q&A site is not the right place to do so, as we only answer questions.

3
  • Thanks @Sim Son for some reason your code gets an error when compiling, "if (digitalRead(BUTTON_PIN) { - error: expected primary-expression before '}' token"
    – Varonne
    Apr 20 at 23:25
  • 1
    @Varonne missing a closing parenthesis
    – jsotola
    Apr 20 at 23:29
  • @Varonne the answer provided by VE7JRO has a much better code. Mine was just intended to show you how such a thing can be implemented.
    – Sim Son
    Apr 25 at 2:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.