Unexpected behaviour of the program

i just gave that sketch a go and for the microswitch i am using in my project im getting on average 5 on press and 1to3 on release . but ive seen as high as 12 on press and 5 on release

when i use the pcb button switch that was in the arduino starter kit im getting no or only 1 bounce

so i hooked up the micro switch again to confirm the bouncing behaviour , and then i implemented the global delay what u suggested earlier and it eliminated the detection of the bounces

Thanks for running the switch diagnostic code. I am quite surprised by your results, maybe the humidity has some effect. :expressionless:

I get larger numbers for regular pushbuttons, and even larger numbers for my crappy arcade switches.

Is your sketch operating to your satisfaction?

I ask because I built your project and TBH the buttons and navigating through the options they provide are yet very finicky and do not work very well for me.

Reading the code I think I can see why, but I will not spend time chasing the problems I think are still in the code, between you being happy and the hole thing mostly coming from the AI.

As I say often, I do not argue with success, even though in this case I question it, and always if you happy, I'm happy.

a7

to be completely honest , it does miss a keypress every now and again , but i can live with it .
i dunno if its a saying or not , but the chase of perfection is the birth of insanity ? XD

however im am interested in learning what u deem problematic in the program.

If it's only that bad, perhaps it is you who are being trained about exactly how to press the buttons… I try to make things break by pressing like a five year old and an eighty year old user.

The button handling works to the extent it does because of exactly how it finds itself in the entire loop. The timing and tracking of state and so forth.

The sketch should, as has been suggested, be set aside and a different approach taken.

The very first part that should be settled is the button handling. Until you have a siml,e sketch that can reliably report of any button

  • I am pressed at the moment

  • I am not pressed at the moment

  • I just got pressed

  • I just got released

  • I've been down for two seconds

  • I got released after a short press

  • I got released after a long press

You can learn how to code this starting from scratch and building from a basic ability to see the button get pressed, or as we say here "become" pressed, all the way to long presses and short presses.

I can't recommend a good library for buttons that does the several things you need to do. I don't use button libraries much, and if I do they would be from the simpler of the many available and only allow seeing button get pressed.

Here's a post on a thread about the basic idea of seeing a button getting pressed:

Yo'll see I used the same global simple debouncing. The post shows the idea of "state change detection", recognizing when a button "becomes pressed".

You might lose the two seconds thing, an annoying and fiddly UI for many of us, and just add a few buttons so you don't need to overload the two with multiple purposes.

Another enhancement for V2 would be a set of LEDs, or if you ambitious a small display showing the user where in the flowchart of control and adjustments the process is currently.

HTH

a7

ok so here is a sketch that will show every state of the button/switch

const int buttonPin = 2;
bool buttonState = HIGH;  
bool lastButtonState = HIGH;
unsigned long pressTime = 0;
unsigned long releaseTime = 0;
bool longPressDetected = false;

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

void loop() {
  buttonState = digitalRead(buttonPin);
  unsigned long currentTime = millis();

  if (buttonState == LOW && lastButtonState == HIGH) {
    Serial.println("I just got pressed");
    pressTime = currentTime;
    longPressDetected = false;
  }

  if (buttonState == HIGH && lastButtonState == LOW) {
    Serial.println("I just got released");
    releaseTime = currentTime;
    if (releaseTime - pressTime > 2000) {
      Serial.println("I got released after a long press");
    } else {
      Serial.println("I got released after a short press");
    }
  }

  if (buttonState == LOW && currentTime - pressTime > 2000 && !longPressDetected) {
    Serial.println("I've been down for two seconds");
    longPressDetected = true;  
  }

  if (buttonState == LOW) {
    Serial.println("I am pressed at the moment");
  } else {
    Serial.println("I am not pressed at the moment");
  }

  lastButtonState = buttonState;
  delay(30);  
}

this is as simple as i could get it

Nice. I have tested your sketch.

To reduce spam and since it is clearly going to do the state report, I removed

  if (buttonState == LOW) {
    Serial.println("I am pressed at the moment");
  } else {
    Serial.println("I am not pressed at the moment");
  }

There are a few things I would change, but I suggest to you that we can leave those what are somewhat subtleties to a later time and possibly never.

But some low fruit. I've copied three lines and recommend you leave LOW and HIGH behind and embrace the bool variables for what they are. So here

bool buttonState = HIGH;  

buttonState = digitalRead(buttonPin);

if (buttonState == LOW && lastButtonState == HIGH) {

instead

// start with 
bool buttonState = false;    // true is switch is pressed

// add a manifest constant
# define PRESSED LOW    // switches are pulled up normally

// get the true/false condition of the button
buttonState = digitalRead(buttonPin) == PRESSED;

// use boolean values directly
if (buttonState && !lastButtonState) { // ...  see the 

Here's where a weakness of mine enters, I'm not so good at naming variables. buttonIsPressed and buttonWasPressed read better in this casting, but I really don't care for them. So you do you, I'll leave it as it is and just "know" buttonState true means it read as down when you did.

Good move reading the button once!

Now I will say you have a grip on the first step of any loop(), which is to gather all inputs. Nothing but reading the button(s), and where you now print, setting flags. A flag is simple a variable that takes on tow (usually) meanings, so

bool inProgrammingMode = false;  // Dedicated flag

never mind! You already know this.

The next section of code should bifurcate on inProgrammingMode, and within each section the flags set for the buttons will be useful for doing one thing or another.

And here's where some flags should be cleared (reset to false). So if a button reading set the saw-short-press release flag, and you were in programming mode, you would, e.g., increment the index of the current parameter and then... clear the flag to keep say you've handled it.

I could go on; my sense of it is that you are catching my hang of it and can probably make some kinds of progress. I hate to say it, but if this makes insufficient sense, I have found feeding entire posts (and threads!) to chatGPT with a request for it to make a different kind of sense, you will get a better written version of what I am saying.

I'm not in the lab, but I will pay attention and if you wanna be sure, feel free to @alto777 when you post and I will get a notification when I tune in.

Meanwhile, take a short press victory lap.

Oh, speaking of long and short, now that you have reliable reporting, I suggest to you to tune down the excruciating 2000 millseconds hold time to qualify as long. A number, oh say 777 will be crisper yet long enough so getting off the button to mean short won't be hard at all. Ppl naturally stay on a button a hundred milliseconds or so, long only has to be a healthy bit longer than the fattest fingered button presser.

For what passes as fun in my empty life I worked a bit with this thread using chatGPT. A single sentence only of which I share here, I thought it was put very well:

Before you decide what a button should do, you need to be sure you know exactly what the button did.

HTH

a7

1 Like