It shouldn't light up as I push the button down

So I thought I had the code working but Ive got a huge problem.
If I hold the button down the led still turns on and I really dont know what to do anymore.
The led should only turn on AFTER I release the button, and 3 seconds have passed, and everytime I oush the button within the span of less than 3 seconds continously, then release for 3 seconds the led should light up as many times as I clicked the button.

This is the wowki: State_Change_Detection Copy - Wokwi ESP32, STM32, Arduino Simulator

And this is what Ive got in proteus:
imagen_2024-04-22_153704937

Also when I start the simulation in proteus the led lights up one time before any input, like it just does it one time without any action from the nutton

The wiring diagram in the simulator does not agree with the wiring diagram in your post.

The 330 Ohm resistor must be in series with the LED, and need not be connected to the button.

1 Like

It is best if you wire up buttons between the input pin and ground. Then enable the internal pull up resistor in the pin mode statement in the setup function.

Your code should look for a LOW being returned from a digitalRead of the pin number when it is pressed.

1 Like

imagen_2024-04-22_163159112
I just changed it, but what about the code?

How can I do that?

const int LED_PIN = 2;
const int BTN_PIN = 3;
const unsigned long blinkDuration = 3000; // Duración de parpadeo predeterminada en milisegundos (5 segundos)

int oldState = HIGH; // El estado inicial del botón es alto (debido a INPUT_PULLUP)
int counter = 0;

unsigned long lastButtonPressTime = 0; // Variable para almacenar el tiempo del último botón presionado
bool counting = false; // Variable para indicar si se está contando clics

void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(BTN_PIN, INPUT_PULLUP);
}

void checkButton() {
  int state = digitalRead(BTN_PIN);
  if (state != oldState) { // Si el estado cambió
    oldState = state; // Recordar el estado anterior
    if (state == LOW) { // Si el botón está presionado
      counter++;
      lastButtonPressTime = millis(); // Guardar el tiempo del último botón presionado
      counting = true; // Empezar a contar
    }
    delay(20); // Debounce
  }
}

void loop() {
  checkButton();

  // Si estamos contando y ha pasado el tiempo de duración del parpadeo
  if (counting && millis() - lastButtonPressTime >= blinkDuration) {
    counting = false; // Detener la cuenta
    for (int i = 0; i < counter; i++) {
      digitalWrite(LED_PIN, HIGH);
      delay(200); // Encender el LED durante 200ms
      digitalWrite(LED_PIN, LOW);
      delay(200); // Apagar el LED durante 200ms
    }
    counter = 0; // Reiniciar el contador después de parpadear el LED
  }
}

the button pulls the pin LOW, so check for it to become HIGH when it is released

1 Like

But it sends the signal without it being released

Not too sure what you are doing here. The && operation is a logical and function.
I think you might have a problem with the order the C/C++ language does it operations. This is known as operator precedence.
http://naipc.uchicago.edu/2014/ref/cppreference/en/cpp/language/operator_precedence.html

Maybe try

if (counting  && ((millis() - lastButtonPressTime) >= blinkDuration)) {

To ensure the code does what it looks like you want to do.

is the LED on and winks off?
does a LOW/HIGH turn LED on?

checkButton() also captures a timestamp, lastButtonPressTime, which is used to delay toggling the LED in loop()

@monloca
I modified your code, added a button test. (lines 20 to 22).
If the button is kept pressed, the blinking time is always updated.

const int LED_PIN = 2;
const int BTN_PIN = 3;
const unsigned long blinkDuration = 5000; // Duración de parpadeo predeterminada en milisegundos (5 segundos)

int oldState = HIGH; // El estado inicial del botón es alto (debido a INPUT_PULLUP)
int counter = 0;

unsigned long lastButtonPressTime = 0; // Variable para almacenar el tiempo del último botón presionado
bool counting = false; // Variable para indicar si se está contando clics

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BTN_PIN, INPUT_PULLUP);
  Serial.println("Button hasn't been pressed yet.");
}

void checkButton() {
  int state = digitalRead(BTN_PIN);
  while (!digitalRead(BTN_PIN)) {
    lastButtonPressTime = millis();
  }
  if (state != oldState) { // Si el estado cambió
    oldState = state; // Recordar el estado anterior
    if (state == LOW) { // Si el botón está presionado
      counter++;
      lastButtonPressTime = millis(); // Guardar el tiempo del último botón presionado

      counting = true; // Empezar a contar
      Serial.print("Button has been pressed ");
      Serial.print(counter);
      Serial.println(" times.");
    }
    delay(20); // Debounce
  }
}

void loop() {
  checkButton();

  // Si estamos contando y ha pasado el tiempo de duración del parpadeo
  if (counting && millis() - lastButtonPressTime >= blinkDuration) {
    counting = false; // Detener la cuenta
    for (int i = 0; i < counter; i++) {
      digitalWrite(LED_PIN, HIGH);
      delay(200); // Encender el LED durante 200ms
      digitalWrite(LED_PIN, LOW);
      delay(200); // Apagar el LED durante 200ms
    }
    counter = 0; // Reiniciar el contador después de parpadear el LED
  }
}

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