My program can't always make the switch responsive

char state = LOW;
void setup() {
  // put your setup code here, to run once:
pinMode(2,INPUT_PULLUP);
pinMode(6,OUTPUT);
attachInterrupt(0,blink,LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
digitalWrite(6,state);
}
blink(){
state = !state;
}

I am a beginner.Now I have some questions about this program.
If I keep pressing the switch and not releasing it, will attachInterrupt continue to read the interrupt signal, repeatedly executing the blink function, causing the loop function to fail? Because when I run the program, I press the button and sometimes it works, sometimes it doesn't. So, is a continuous interrupt signal treated as an interrupt signal?
I would be grateful if you could give me an answer.

Welcome to the forum

Why are you using an interrupt to read the input when you could just poll its state in loop() ?

How many times will state change when the input is LOW ?

this calls the interrupt when the signal is LOW

if you want to catch a transition (state change) use FALLING or RISING.

Mind bouncing with buttons though

Oh yes, I see what you mean. This is a program I found on the Internet for learning "interrupt".The program is not perfect,then I have the question .I wonder how this program works if I keep pressing the switch and not releasing it.

Thank you for your reply.But I'm not sure what" Mind bouncing with buttons though "means.

You should be careful (ie mind) about buttons which can be bouncing

See for example https://arduinogetstarted.com/tutorials/arduino-button-debounce

You took care of my immediate needs.I have looked carefully at the link you provided.That's great!Thank you very much for enabling me to continue my study.

Welcome to the forum
How many times will state change when the input is LOW ?

Oh yes, I see what you mean ! I changed the program. I added a delay function to make the error more obvious.When I pressed the button and did not release, the LED kept flashing ! I think I understand.

int state = LOW;
void setup() {
  // put your setup code here, to run once:
pinMode(2,INPUT_PULLUP);
pinMode(6,OUTPUT);
attachInterrupt(0,blink,LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
digitalWrite(6,state);
delay(1000);
}
void blink(){
state = !state;
}

Do you find your Solution with this Topic?

I haven't.I replaced "LOW" in attachInterrupt with "RISING".Sometimes it still doesn't work, but the frequency is lower than before. Maybe I should give up using interrupt.

It's OK to experiment.

Did you forget about the switch bouncing issue? :expressionless:

a7

I'm trying to solve this problem with a millis(). Press and release the switch once, the LED changes once (from on to off or off to on).
But now I can only achieve the following :Press or release the switch once, the LED changes once (from on to off or off to on).

What's millis() got to do with that?

Check the state change detect example in the IDE. Better to modify it to use input pullups compared to the hard-wired pulldowns it expects. Then look for the button to be released (low to high) and toggle the led.

It works but not in the way that I think you want it to

Note all variables that are used both inside and outside of an interrupt must be declared volatile, and you should not use an int type variable unless you surround the access to it with a noInterrupts at the start and interrupts when you have finished.

volatile bool state = false;

Anything else with the rest of that code shows you what a crap tutorial you were following.

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

The reason why I use this variable type is the above program(I found an example in the IDE) also uses an int.

int buttonState = 0; 

Why not indeed, that’s what digitalRead returns, but you don’t need it as a global variable (could be local to the loop() function) and really you don’t need it at all (the compiler/optimizer likely gets rid of it) as you could write


void loop() {
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (digitalRead(buttonPin) == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

And you could go one step further if you notice that the led takes the state of the button and so the loop could just be

void loop() {
  digitalWrite(ledPin,  digitalRead(buttonPin));
}

(Your code is assuming you have a pull down on your button)

Is that the right way to define butttonstate if you leave the procedure out?Can we define it as an int?Is it a must to use Boolean?

If you want to stay true to the programming interface, digitalRead() returns an int, so as the spec does not say the range taken by HIGH and LOW (you have to look at the source code to know it’s an int defined as 1 and 0) then using an int is the right way.

If you want a bool you would write

bool buttonIsPressed = (digitalRead(butyonPin) == HIGH);
if (buttonIsPressed) {
  ….
} else {
  …
}

This way what you store is really a truth value, the result of a comparison making no assumption whatsoever about the type ot values of HIGH and LOW.

You can go one step further to accommodate a pull-up or pulldown situation by defining at the start of the code what pressed means this way you have only one place to change the code if you change the hardware setup

#define PRESSED HIGH  // using an external pulldown resistor for the button
….

  bool buttonIsPressed = (digitalRead(butyonPin) == PRESSED);
  if (buttonIsPressed) {
    ….
  } else {
    ….
  }
….
1 Like