Latching momentary switch to flash LED using millis()

I'm learning to use an Arduino to create a lighting controller for my kit car. The first step is to latch momentary switches to create a flasher function to control the indicators.
I've managed to latch a momnetary switch, and I've managed to code a flash function using millis(), but when I put the two functions together I cannot get the outcome I want. With the code below I get the latching function but no flashing.
Thanks for your help - there will be more questions to follow once I've resolved this one!

int LEDState = 0;
int LEDPin = 13;
int buttonPin = 3;
int buttonNew;
int buttonOld = 1;
int dt = 50;
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // put your setup code here, to run once:
  // Serial.begin(9600);
  pinMode (LEDPin, OUTPUT);
  pinMode (buttonPin, INPUT_PULLUP);

}

void loop() {
  // put your main code here, to run repeatedly:
  unsigned long currentMillis = millis();

  buttonNew = digitalRead(buttonPin);
  if (buttonOld == 1 && buttonNew == 0) {
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis; // save the last time you blinked the LED
      if (LEDState == LOW) { // if the LED is off turn it on and vice-versa:
        LEDState = HIGH;
      } else {
        LEDState = LOW;
      }
      digitalWrite(LEDPin, LEDState); // set the LED with the ledState of the variable:

    }
   else {
      digitalWrite(LEDPin, LOW);
      LEDState = 0;
    }
  }
  buttonOld = buttonNew;
  delay(dt);

}

Your flashing code only gets run when you detect a transition to LOW on your button.

I suggest that you use the button to toggle a boolean, perhaps called IndicatorOn. Make the flashing stuff dependent on that instead.

I did a project like that a coupe of years ago with rings of WS2812B LEDs.

I rewrote your code as belows:

int LEDState = 0;
int LEDPin = 13;
int buttonPin = 3;
int buttonNew;
int buttonOld = 1;
int dt = 50;
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 1000;           // interval at which to blink (milliseconds)

bool isFlashed = false;

void setup() {
  // put your setup code here, to run once:
  // Serial.begin(9600);
  pinMode (LEDPin, OUTPUT);
  pinMode (buttonPin, INPUT_PULLUP);

}

void loop() {
  // put your main code here, to run repeatedly:
  unsigned long currentMillis = millis();

  buttonNew = digitalRead(buttonPin);
  if (buttonOld == 1 && buttonNew == 0) {
    isFlashed = true;
    delay(dt);
  }

  buttonOld = buttonNew;

  if (isFlashed == true) {
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis; // save the last time you blinked the LED
      if (LEDState == LOW) { // if the LED is off turn it on and vice-versa:
        LEDState = HIGH;
      } else {
        LEDState = LOW;
      }
      digitalWrite(LEDPin, LEDState); // set the LED with the ledState of the variable:
    }
  }
}

I hope this help

Sigh… I think the OP has left us.

Since its done, here’s my approach…

#include <mechButton.h>
#include <blinker.h>

#define BUTTON_PIN   2     // Pin we'll hook the button to. The other side hooks to ground.
#define LED_PIN      13    // Usual pin number for built in LED.


mechButton  aButton(BUTTON_PIN); // Set button one to pin 2.
blinker     aBLinker(LED_PIN);   // Allocate a global blinker object.

// Your standard sketch setup()
void setup() {
   
   aButton.setCallback(myCallback);    // Set up our callback.
   aBLinker.setOnOff(false);           // Make sire it's off.
}


// This is the guy that's called when the button changes state.
void myCallback(void) {

   if (!aButton.trueFalse()) {                  // If false, meaning connected to ground. (Pushed)..
      aBLinker.setOnOff(!aBLinker.blinking());  // We just toggle the on state of the blinker. on/off   
   }
}


// Your standard sketch loop()
void loop() { idle(); } // Idle runs the background suff.

-jim lee

Hi, sorry, I am still here! Thanks for the help so far guys.

@ IoT_hobbyist - I've looked at your code and it will latch on, then flash, but it will not unlatch on a second button press. I've been playing around all day with it and I cannot for the life of me work out how to get it to unlatch???!

@ jimLee - I think what you're suggesting is a bit beyond my basic knowledge of Arduino programming - ie. I don't really inderstand what you've said! Thanks for your help though....

Ray

@ jimLee - I think what you're suggesting is a bit beyond my basic knowledge of Arduino programming - ie. I don't really inderstand what you've said! Thanks for your help though....

No worries, I"m used to people thinking I'n nuts.

Well.. c++ is object oriented. This program is basically two objects. A button object and a blinker object. The button turns the blinker on and off.

For a car's blinkers I'd think you'd need two blinkers (Left/Right) and three buttons. (Left/off/Right)

IF you'd like to see if/how it works, you just need to instal the LC_baseTools library from the Library manger on the IDE.

Good luck!

-jim lee

but it will not unlatch on a second button press. I've been playing around all day with it and I cannot for the life of me work out how to get it to unlatch???!

if (buttonOld == 1 && buttonNew == 0) {
    isFlashed = true;
    delay(dt);
  }

To toggle the flashing state with each button push you can use this syntax

if (buttonOld == 1 && buttonNew == 0) {
    isFlashed = !isFlashed;
    delay(dt);
  }

or, if its easier to understand

if (buttonOld == 1 && buttonNew == 0) {
    if(isFlashed ==  true) isFlashed = false;
    else isFlashed = true;
    delay(dt);
  }

So @cattledog is your first name Hank?

-jim lee

So @cattledog is your first name Hank?

Nope. It's Richard. I'm sure Hank is a fine fellow, be he ain't me. :slight_smile:

Not Hank The Cowdog then.

-jim lee

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.