timing between button presses - What am I doing wrong?

Hello

I only have basic knowledge of programming and I have hit roadblock, I have searched the internet for about 30 examples of similar ideas to what I want had have come up with a basic code but its not working right.

What I need the program to do is read the state of a micro-switch and flash a LED on and off according to a set of rules
ie button press = flash LED & add 1 to the counter eg:

When the micro-switch is pressed it sends a HIGH signal to pin 3 when it is unpressed it send a LOW signal

a) If the button is pressed and held or released - the Led flashes once only the counter set to 1

b) If the button is pressed and held or released a second time - the Led flashes once only the counter set to 2

c) If the button is pressed and released a third time - the Led flashes once only add to counter reset to 1

d) If the button is pressed and held on the 3rd time the Led flashes continuously until the button is released then
counter is reset, however only if the 3rd press is within 2 seconds of the 1st press
ie if the 3rd press is 2.5 seconds after the 1st press - the LED only blinks once and then the counter is set to 1 again

e) if rule (d) was active and Led blinked continuously then the button was released to stop the blinking and the button
is once again pressed and held or released within 2 seconds of the button being released in rule (d) then blinking
runs continuously while the button is pressed and rule (e) get repeated until such time as the button is released
and pressed again after 2 seconds of rule (d) then system resets back to rule (a)

here is my code

int switchinput = 3;  // the number of the input pin (for me a microswitch / push button)
int ledPin = 7;
int dwell = 50;

int current; //Current state of the button
int counter = 0; 
int continuous = false;
byte previous = LOW;
long firstTime; 
long secondTime;  

void setup()
{
  Serial.begin(9600);    // Use serial for debugging
  pinMode(ledPin, OUTPUT);
  pinMode(switchinput, INPUT);
  digitalWrite(switchinput, LOW);
}

void loop()
{
    current = digitalRead(switchinput);

    if (current == HIGH && previous == LOW && counter == 0) // 1st time button is pressed
    {
    firstTime = millis();
    Serial.println("start");
    Serial.println(counter);
    ledblink();
    counter++;
    delay(20);
    previous = current;
    }
   
    if (current == HIGH && previous == LOW && ((millis() - firstTime) < 2000)) //2nd time button is pressed still within 1 second
    {
    Serial.println("2nd press");
    Serial.println(counter);
    ledblink();
    counter++;
    delay(20);
    previous = current;
    }
    
    
    if (current == HIGH && previous == LOW  && ((millis() - firstTime) < 2000) && counter < 3) // if button is pressesed 3 or more times in 1 second continue blinking till button is released
    {
        while (switchinput == HIGH)
         {
         ledblink();
         Serial.println("continuous");
         }
         if (switchinput == LOW) //once switch is released start 2nd timer
           {
             secondTime = millis();
             continuous = true;
             previous = current;
           }
    }
    
   if (current == LOW && previous == HIGH && continuous == true && ((millis() - secondTime) < 2000)) //if button is not pressed again within 1 second then reset counter
            {
              Serial.println("reset counter!"); 
              counter = 0;
              delay(20);
              continuous == false;
            } 
    previous = current;
}



void ledblink()
{ 
    digitalWrite(ledPin, HIGH);  // turn relay on:    
    delay(dwell);
    digitalWrite(ledPin, LOW); // turn relay off:
    delay(dwell); 
}

Is this homework? Such a set of requirements often is.
You only need two Pins from the switch not three, if you use three pins then it will float when switched over. See:-
http://www.thebox.myzen.co.uk/Tutorial/Inputs.html

It is customary to say what your code does.

Ok I have worded it differently

The way I have connected the the micro-switch is that when it pressed it sends a HIGH signal to pin 3 when it is unpressed it send a LOW signal

Currently the code works as follows (displayed on serial monitor {SM})
I push the button the led blinks once & SM says “start” and “0”
I push the button again the led blinks & SM says “2nd press” and " 1 " each time I press button again the counter
goes up but it does not go to the “continuous” cycle and only accepts inputs for about 5 seconds then the program
stops responding (hit a dead loop)

So Im sure Im getting the coding wrong with timing / millis() function

on of the examples used % as a comparason function which I cant find out what it means

eg part of the code looked like this

&& ((millis() - firstTime) % 2000) && counter < 3)

I think you are trying to stuff too much logic into each if statement. Simpler code gives more clarity.

You need a variable that records whether this is the first, second or third press.
You need another variable that records whether the switch is pressed or not.

Then you can have a function that flashes the LED according to your rules using the values in those variables as inputs.

The code in loop() could be as simple as this

void loop() {
  readSwitch();
  flashLED();
}

Use the technique in the Blink Without Delay example sketch to use millis() to manage the timing.

...R

ok I have re-written the code based on feedback and example

problem is now it seems to work through the different steps however
it doesnt register “clicks” of the button. ie if I push the button the led blinks and the counter goes up
I need it to only blink once per press (and or hold) based on the rules with the exception of 3 presses and hold within 2 seconds
then it should continuously blink until button is released

int pushState = LOW;
const int ledPin = 7;
int buttonThen = LOW;
const int button = 3;
int flashState = 0;
int startTime = 0;
int interval = 2000;
int previousTime = 0;
int dwell = 300;
int prevState = 0;
int currState = LOW;

void setup()
{
  Serial.begin(9600);
pinMode(button,INPUT);
digitalWrite(button, LOW);  
pinMode(7,OUTPUT);
}

void loop()
{
 checkPush();
  if(pushState == HIGH && flashState == 0)
  {
    ledblink();
    flashState++;
    startTime = millis();
    Serial.print("start - "); Serial.println(flashState);
  }
  else       if(pushState == LOW && ((millis() - startTime) > 2000))
             {
              flashState = 0;
              Serial.print("idle reset - "); Serial.println(flashState);
             }
             if(pushState == HIGH && flashState >= 1 && ((millis() - startTime) > 2000))
             {
              ledblink();
              flashState = 1;
              startTime = millis();
              Serial.print("reset  - "); Serial.println(flashState);
             }
  
  if(pushState == HIGH && flashState < 3 && ((millis() - startTime) < interval)) 
          {
            ledblink();
            flashState++;  
           Serial.print("2nd - "); Serial.println(flashState) ;
          }
          else if(pushState == HIGH && flashState > 3 && ((millis() - startTime) < interval)) 
            {
              Serial.print("continous -"); Serial.println(flashState);
              continousGo();
              previousTime = millis();
            }
                else if(pushState == HIGH && flashState > 3 && ((millis() - previousTime) < 1500)) 
                  {
                    Serial.print("2nd continous - "); Serial.println(flashState);
                    continousGo();
                    previousTime = millis();
                  }
                            else if(pushState == HIGH && flashState > 3 && ((millis() - previousTime) < 1500)) 
                            {    
                              ledblink();
                              Serial.print("reset after continous - "); Serial.println(flashState);
                              flashState = 1;
                              startTime = millis();
                            }
}

void checkPush()
{
    int currState = digitalRead(button);
   
    if (currState != prevState)
    {
         if (currState == HIGH)
         {
           pushState = HIGH;  
         }
         else 
          {
           pushState = LOW;
          }
    }
    prevState = currState;
}




void ledblink()
{ 
    digitalWrite(ledPin, HIGH);     
    delay(dwell);
    digitalWrite(ledPin, LOW); 
    delay(dwell); 
}


void continousGo()
{
  do 
  {
  ledblink();
  }while (pushState == HIGH);
}

Any time you're in a delay, you're not looking at switches.
What do you think you should do about this?

ok so the main problem could be in the ledblink() loop?

clintk84:
ok so the main problem could be in the ledblink() loop?

Yes. Look at how the leds are programmed in the sketch attached to the first post of this Thread.

...R