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:
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?
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
}
}
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.
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:
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.