Light up 2 times, 1 time too many

I wanted to make a flash light in which I could activate an LED for 0.08 seconds with a switch. I have a nano, I have the switch between pin D5 and the mosfet that controls the LED on D3, the LED has a separate power source. Now when I press the switch, the LED lights up once and when I release it, it lights up again. I want it to only light up once. what's wrong with my code?

Code:
const int tasterPin = 5; // Button connected to Pin D5
const int mosfetPin = 3; // MOSFET connected to Pin D3
bool tasterPrevious = false; // Variable to store the previous button state

void setup() {
pinMode(tasterPin, INPUT_PULLUP); // Configure button as input with internal pull-up resistor
pinMode(mosfetPin, OUTPUT); // Configure MOSFET pin as output
}

void loop() {
bool tasterCurrent = digitalRead(tasterPin); // Read current button state

if (tasterCurrent == LOW && tasterPrevious == HIGH) { // If the button is pressed and was not pressed before
digitalWrite(mosfetPin, HIGH); // Turn on the MOSFET (full brightness)
delay(80); // Keep the LED on for 0.08 seconds
digitalWrite(mosfetPin, LOW); // Turn off the LED
}

tasterPrevious = tasterCurrent; // Save current button state for the next iteration
}

The issue is that you're detecting the button press on both the press and release actions because you're checking if the current state is LOW and the previous was HIGH. The LED lights up once when you press (state changes from HIGH to LOW) and again when you release (state changes back from LOW to HIGH).

To fix it, update your code to only trigger the LED on one edge of the button press (e.g., only on the press down or only on the release). Here's an example to trigger only on the press:

bool tasterPressed = false; 

void loop() {
  bool tasterCurrent = digitalRead(tasterPin); 

  if (tasterCurrent == LOW && !tasterPressed) { 
    digitalWrite(mosfetPin, HIGH); 
    delay(80); 
    digitalWrite(mosfetPin, LOW); 
    tasterPressed = true;
  }
  
  if (tasterCurrent == HIGH) {
    tasterPressed = false;
  }
}

This way, the LED will only light up once per button press, and not again on the release.

not solved by the code you posted.

When you placed this on an Arduino with an LED and pushbutton attached, did the LED blink once when you pressed the switch down, and not at all when you released the button?

When I did, the LED flashed on both edges.

a7

button handling is a bit rough..
maybe like this..

const int tasterPin = 5; // Button connected to Pin D5
const int mosfetPin = 3; // MOSFET connected to Pin D3
//input pullup starts high..
byte tasterPrevious = 1; // Variable to store the previous button state

unsigned long lastPush;
int intervalDebounce = 50;
bool press = false;


void setup() {
  pinMode(tasterPin, INPUT_PULLUP); // Configure button as input with internal pull-up resistor
  pinMode(mosfetPin, OUTPUT); // Configure MOSFET pin as output
}

void loop() {

  if (millis() - lastPush >= intervalDebounce) {
    byte b = digitalRead(tasterPin);
    if ( b != tasterPrevious) {
      tasterPrevious = b;
      lastPush = millis();//start debounce
      if (b == LOW) {
        //raise the press
        press = true;
      }
    }
  }

  if (press) { // If the button is pressed
    digitalWrite(mosfetPin, HIGH); // Turn on the MOSFET (full brightness)
    delay(80); // Keep the LED on for 0.08 seconds
    digitalWrite(mosfetPin, LOW); // Turn off the LED
    press = false; //drop the press
  }
}

Happy New Year!!

good luck.. ~q

No debounce? How is the button wired?

@faebeli06 the bouncing push button is the problem.

You can see this by using a loop like

void loop() {
  bool tasterCurrent = digitalRead(tasterPin); 

  if (tasterCurrent == LOW) {
    digitalWrite(mosfetPin, HIGH); 
    delay(80); 
    digitalWrite(mosfetPin, LOW);
    delay(500);
  }
}

You will see one stab of the LED each time you hit the button.

Unfortunately, you will not be able to get more than two stabs of LED per second.

Unfortunately, maybe, you will get stabs repeating every 1/2 second (500 milliseconds) if you hold the button down.

If either or both those are a problem, you need to learn about

 arduino switch debouncing

and maybe

arduino state change detection

If neither "feature" of the poor man's solution to the bouncing problem (ignore the button for 500 milliseconds) matters, you done.

Here please be sure to wire your switch in the most common way: place it between the input pin and ground, use INPUT_PULLUP in the pinMode() call and then expect the switch to digitalRead() LOW when pressed.

HTH

a7

Try this here right here: :grin:

const int tasterPin = 5; // Button connected to Pin D5
const int mosfetPin = 3; // MOSFET connected to Pin D3
bool tasterPrevious = false; // Variable to store the previous button state

void setup() {
  pinMode(tasterPin, INPUT_PULLUP); // Configure button as input with internal pull-up resistor
  pinMode(mosfetPin, OUTPUT); // Configure MOSFET pin as output
}

void loop() {
  bool tasterCurrent = digitalRead(tasterPin); // Read current button state
  if (tasterCurrent != tasterPrevious)
  {
    delay(50); // simple debounce
    if(! tasterCurrent)
    {
      digitalWrite(mosfetPin,HIGH);
      delay(80);
      digitalWrite(mosfetPin,LOW);
    }
  tasterPrevious = tasterCurrent;
  }
}

Seems to work. As does moving the simple debouncing to the end of the function, where it would serve to debounce all the buttons you might ever pile on this.

const int tasterPin = 5; // Button connected to Pin D2
const int mosfetPin = 3; // MOSFET connected to Pin D3
bool tasterPrevious = false; // Variable to store the previous button state

void setup() {
  pinMode(tasterPin, INPUT_PULLUP); // Configure button as input with internal pull-up resistor
  pinMode(mosfetPin, OUTPUT); // Configure MOSFET pin as output
}

void loop() {
  bool tasterCurrent = digitalRead(tasterPin); // Read current button state
  if (tasterCurrent != tasterPrevious)
  {
    if (!tasterCurrent)
    {
      digitalWrite(mosfetPin, HIGH);
      delay(80);
      digitalWrite(mosfetPin, LOW);
    }
  tasterPrevious = tasterCurrent;
  }

  delay(50); // simple debounce (poor man's)
}

You can use either pattern for toggling, in which case we get back to one delay() call, viz:

void loop() {
  bool tasterCurrent = digitalRead(tasterPin); // Read current button state
  if (tasterCurrent != tasterPrevious)
  {
    if(! tasterCurrent)
    {
      digitalWrite(mosfetPin, !digitalRead(mosfetPin));
    }
  tasterPrevious = tasterCurrent;
  }

  delay(50); // simple debounce (poor man's)
}

It is the ignoring of the switch that saves you.

Now it is simple to add a proper debounce: just don't look at the switch if you've let it trigger either a stab or a toggle:


void loop() {
  static unsigned long lastTime;    // when did we do IT, whatever IT is?

  unsigned long now = millis();
  unsigned long elaspsedTime = now - lastTime;

  if (elaspsedTime > 50) {
    bool tasterCurrent = digitalRead(tasterPin); // Read current button state
    if (tasterCurrent != tasterPrevious)
    {
      if (!tasterCurrent)
      {
        digitalWrite(mosfetPin, !digitalRead(mosfetPin));
      }
      tasterPrevious = tasterCurrent;

      lastTime = now;  // so we ignore the button for awhile
    }
  }
}

We can even invert the time test:

void loop() {
  static unsigned long lastTime;    // when did we do IT, whatever IT is?

  unsigned long now = millis();
  unsigned long elaspsedTime = now - lastTime;

  if (elaspsedTime < 50) return;    // it is too soon to even look at the switch, we done.


 
  bool tasterCurrent = digitalRead(tasterPin); // Read current button state
  if (tasterCurrent != tasterPrevious)
  {
    if (!tasterCurrent)
    {
      digitalWrite(mosfetPin, !digitalRead(mosfetPin));
    }

    tasterPrevious = tasterCurrent;
    lastTime = now;  // so we ignore the button for awhile
  }
}

which you might do in the case of a function that had a time test controlling the entirety of its purpose.

a7

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