Stopper l'incrémentation quand mon btn est appuyé

Bonjour,
Je créer un clicker physique et j'aimerais que quand j'appuie sur mon btn qu'il face qu'une incrémentation de 1 à mon counter, quand je reste appuyé il s'incrémente en continue.

#include <Arduino.h>
#include "NimBLEDevice.h"

#define     BUTTON_PIN          32

#define     BLE_SERVER_NAME     "Clicker"
#define     SERVICE_UUID        "*******************************"
#define     CHARAC_UUID         "*******************************"

uint32_t counter = 0;
uint32_t lastButtonState = HIGH;
uint32_t currentButtonState;

NimBLEServer* pServer = nullptr;
NimBLECharacteristic* pCharacteristic = nullptr;

void setup()
{
    Serial.begin(115200);
    pinMode(BUTTON_PIN, INPUT_PULLUP);

    NimBLEDevice::init(BLE_SERVER_NAME);
    NimBLEDevice::setSecurityAuth(true,true,true);
    NimBLEDevice::setSecurityPasskey(123456);

    pServer = BLEDevice::createServer();
    NimBLEService* pService = pServer->createService(SERVICE_UUID);

    pCharacteristic = pService->createCharacteristic(
        CHARAC_UUID,
        READ | READ_ENC | NOTIFY
    );
    pCharacteristic->setValue(String(counter));
    pService->start();

    NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising();
    pAdvertising->addServiceUUID(SERVICE_UUID);
    pAdvertising->setScanResponse(true);
    pAdvertising->setMinPreferred(0x06); //pour les iphones qui peuvent avoir des problèmes de connexions
    pAdvertising->setMinPreferred(0x12);
    NimBLEDevice::startAdvertising();
}

void loop()
{
    currentButtonState = digitalRead(BUTTON_PIN);

    if (currentButtonState == LOW && lastButtonState == HIGH)
    {
        counter++;
        pCharacteristic->setValue(String(counter));
        pCharacteristic->notify();
    }

    lastButtonState = currentButtonState;
}

Merci d'avance pour l'aide

Bonjour,

Tant que tu maintient ton bouton appuyé, tu retourne dans le

et tu incrémente.

Le probléme Numéro 1:
C'est que entre chaque passage dans le "if", lastButtonState n'est pas changé alors qu à un moment le bouton est bien passé de HIGH à LOW
Il faudrait je pense, mettre

lastButtonState == LOW;

entre les { } du if

Comme cela

Heu, je ne sais pas s'il y a d'autres problémes!

Hello,
C'est une piste que j'avais déjà exploré et que je vient de réessayé.
Malheureusement ce n'est pas ça.

void loop() {
    currentButtonState = digitalRead(BUTTON_PIN); // Lire l'état du bouton

    if (currentButtonState == LOW && lastButtonState == HIGH && buttonPressed == true) {
        counter++;
        buttonPressed = false;
        currentButtonState = HIGH;
        lastButtonState = LOW;

        Serial.print("count : ");
        Serial.println(counter);
        pCharacteristic->setValue(String(counter));
        pCharacteristic->notify();
        delay(20);
    }

    while (buttonPressed == false){
        
        Serial.print("wait");
        delay(1000);
    }

    lastButtonState = currentButtonState; // Mettre à jour l'état du bouton
}

J'avais aussi fait ça. La je reste bloqué sur le wait ca incrémente de 1 Mais je ne sort plus de ma while

Il y a encore à voir le probléme des rebonds sur appui des BP.

Genre (comme dirait les jeunes) tu appuie est maintiens appuyé 1 fois, et la lamelle du BP rebondit un certains nombre de fois avant de rester fermée, c'est purement mécanique.

Une astuce, pour confirmer cela, c'est de mettre un petit "delay" entre 2 lectures du "if", histoire de calmer le jeu.

20 ms c'est assez en general pour que le contact inter, bp ou relais se stabilise.

J'en ai déjà mis j'ai fais le code hier et j'ai eu l'esp-32 et les breadbord aujourd'hui je suis sur le problème depuis 9h du matin haha J'ai vraiment essayé plein de truc.
J'ai même teste chatGPT mais lui c'est pire mdr

En vrai je sais vraiment pas quoi faire pour le coup

En fait, j'ai essayé cela sur mon UNO (c'est ton code initial allégé)



#define BUTTON_PIN 2


uint32_t counter = 0;
uint32_t lastButtonState = HIGH;
uint32_t currentButtonState;

void setup()
{
    Serial.begin(115200);
    pinMode(BUTTON_PIN, INPUT_PULLUP);

}

void loop()
{
    currentButtonState = digitalRead(BUTTON_PIN);

    if (currentButtonState == LOW && lastButtonState == HIGH)
    {
        counter++;
    }

    delay(20);

    lastButtonState = currentButtonState;
    Serial.println(counter);
}

Avec et sans delay.

Sans delay, une fois sur 20 il compte un "top" en plus quand je relache le BP (alors qu'il ne devrait pas incrémenter au relachement).

Il faudrait que je teste sur un ESP32, je ne l'ais pas sous la main...

EDIT:

Bien entendu, puisque j'ai l'entrée 2 en INPUT_PULLUP, j'ai branché un BP entre 2 et GND.

Le soucis principal, c'est ce que l'on appel un appuis.
Un appuis très nerveux et t'il traité de la même façon qu'un appuis sous substance ?

Pour moi il faut définir en terme de temps ce que l'on appel un appuis et donc incrémenter le compteur uniquement après ce temps.
Après bien sure avoir réglé les problèmes de rebonds de façon logiciel ou matérielle.
avec ce genre de code

#define BUTTON_PIN 2


uint32_t counter = 0;
uint32_t lastButtonState = HIGH;
uint32_t currentButtonState;

long timePush = 300;
long nextPush = 0;

void setup()
{
    Serial.begin(115200);
    pinMode(BUTTON_PIN, INPUT_PULLUP);

}

void loop()
{
    currentButtonState = digitalRead(BUTTON_PIN);
    if (currentButtonState == LOW) {
      nextPush = millis() + timePush;
    }

    if (currentButtonState == LOW && lastButtonState == HIGH || nextPush > millis())
    {
        counter++;
    }

    delay(20);

    lastButtonState = currentButtonState;
    Serial.println(counter);
}

par contre je ne vois pas ce que ton clicker doit compter ou ce que tu t'attends à compter en continue avec un appuis prolongé ?

Bonjour nervirekea

Tu tirerai avantage à utiliser une bibliothèque comme JC_Button, ça te simplifierai la tâche, veux tu un exemple?

A quel rythme veux-tu incrémenter quand il y a une longue pression?

A+
Cordialement
jpbbricole

:innocent: quelle substances?

Le café?

Hello, je crois que le pb est plutôt

Merci pour ta réponse enfaite je suis hyper actif et je suis en formation DotNet Angular et la je créer un clicker pour un cours de prototypage et je vais en faire mon projet de fin de formation avec une application mobile qui comptera les cliques que je fais. donc enfaite je ne compte rien juste le nombre de pressions sur le bouton quand il y à une pression prolongé je veux que ca n'incrémente rien de plus. Juste un push = +1 a mon counter je ne veux pas que quand on reste appuyé qu'il y à 100 cliques qui s'incrémente :).

Bonjour, merci pour ta réponse effectivement je veux bien en exemple et une petit explication j'ai jamais fais de C++ J'apprend depuis hier haha donc ça m'aidera fortement merci BCP :smiley:

Je crois que le problème est plutôt dans ta compréhension de ma réponse :woozy_face:

Bonjour nervirekea

OK
A+

Bonjour nervirekea

Voilà un exemple, tout est là, expliqué, grâce à l'IA, si tu veux des explications supplémentaires, n'hésites pas :wink:

J'ai testé le programme, il fonctionne sans retouches.

Cordialement
jpbbricole

non plutôt l'effet inverse

Cool, moi j'ai fait un projet en Avalonia, ca doit ce ressembler.

Dans ce cas le code de @jef59 est fonctionnel si tu n'a pas de rebond de plus de 20 ms.

Tu peux aussi utiliser une librairie de gestion des boutons comme le propose @jpbbricole , mais bon pour un cas aussi simple, je ne sais pas si cela est vraiment bénéfique.

Bonjour nervirekea

En fait j'avais mal "tourné" le

En effet, une bibliothèque n'est pas nécessaire, mais pourquoi pas, ça fait découvrir le sujet?

Oublies mon post#15

Cordialement
jpbbricole

Bonjour nervirekea

Par curiosité, quelle application mobile?

Je t'ai fait un exemple avec la bibliothèque JC_Button, avec en plus de ta question, un reset du compteur, si tu presses plus de 2 secondes sur le bouton. C'est ce genre de "trucs" qui rend l'usage d'une bibliothèque attractif.

Le programme:

#include <JC_Button.h>          // https://github.com/JChristensen/JC_Button

const int btnPin = 3;
int clickCounter = 0;

const boolean btnPullup = true; // PULLUP internes
const boolean btnInvert = true; // Actif à LOW
const int btnDebounce = 20; // Temps anti rebonds

Button btn(btnPin, btnPullup, btnInvert, btnDebounce);     // Création du bouton

void setup()
{
	Serial.begin(115200);
	btn.begin(); // Démarrage du bouton
}

void loop()
{
	// read the buttons
	btn.read(); // Lecture du bouton

	if (btn.pressedFor(2000) && clickCounter != 0)     // Si BP presse 2 secondes, reset du compteur
	{
		clickCounter = 0;
		Serial.println(clickCounter);
	}
	else if (btn.wasPressed())
	{
		clickCounter ++;
		Serial.println(clickCounter);
	}
}

A+
Cordialement
jpbbricole

Ce qui est interessant, c'est que le code que j'ai testé et qui marche sur mon UNO est celui de @nervirekea qui ne marche pas sur son ESP32, c'est une piste non?

Ce n'est pas ce bout de code qui est en défaut...

C'est peut-être ce qu'il y a autour il me semble.

Je compléter mon message:

Avec un esp32
et ce code, counter s'incrémente de 1 à chaque appuie sur un BP (10 appuis ==> counter = 10)
C'est toujours le code de @nervirekea + 20ms de "delay", mais même sans ça à l'air de marcher

#define BUTTON_PIN 32


uint32_t counter = 0;
uint32_t lastButtonState = HIGH;
uint32_t currentButtonState;

void setup()
{
    Serial.begin(115200);
    pinMode(BUTTON_PIN, INPUT_PULLUP);

}

void loop()
{
    currentButtonState = digitalRead(BUTTON_PIN);

    if (currentButtonState == LOW && lastButtonState == HIGH)
    {
        counter++;
    }

    delay(20);

    lastButtonState = currentButtonState;
    Serial.println(counter);
}

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