Maybe it is very simple but i cant figure it out sorry for it. i try to use basic button counter with interrupts but it didnt work correctly.when i pressed button 1 time, counter increases 2 times , even sometimes 5 times. why is that? is it because serial print?
You appear to have ignored the hint you were given in Post #7.
You didn't state what type of Arduino board you're using. But if it's an 8-bit AVR-based board (Uno, Mega, etc), then the access to your 16-bit variable 'counter' is non-atomic. You must disable interrupts in the non-ISR code, copy it to a local variable, then re-enable interrupts.
1- Now i am on that hint. İt could be the cause. now try to add some code to prevent it. do u have any idea?
2-i am using arduino uno. you mean place "noInterrups()" line in interrupt function?
Mostly that I can't think of a good reason to use interrupts for a push button application. They're not needed. There are lots of good libraries that do switch de-bouncing. Bounce2 is one of them.
No. In non-ISR code:
void loop() {
int localCounter;
noInterrupts();
localCounter = counter;
interrupts();
Also, why are you printing the value ever time loop executes? Why not just print it when it changes? Then you can also get rid of the delay(). See the State Change Detection example:
very good points. i want to use it any other program but first i want to get familiar with it. so give it some random delay representing my other functions.
1. Check that the interrupting device (K1) is a push-type button and is wired with internal pull-up resistor as per Fig-1.
Figure-1:
2. Upload the following sketch.
const byte interruptPin = 2;
volatile bool flag = false;
volatile int counter = 0;
void setup()
{
Serial.begin(9600);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), blink1, FALLING);
}
void loop()
{
if (flag == true) //Stops Serial Monitor to show 0 when there is no interrupt
{
noInterrupts(); //to ensure that counter's value is not changed while accessing here.
Serial.println(counter);
interrupts();
flag = false;
}
}
void blink1()
{
flag = true;
counter++;
}
3. Gently, press and then release K1. 4. Check that the display shows incremental values as per Step-5 and not the random values.
5.Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Notes: (1) When K1 is pressed, it makes hundreds of make-and-break before settling at the closed position (Fig-2). This is known as bouncing of the mechanical key. As a result, there occurs multiple interrupts which are randomly recorded and displayed.
Figure-2:
(2) Practically, an interrupt signal is generated as a single pulse by an electronic-type interrupting device (U1X) as depicted in Fig-3.
If you wish, you can interface your K1 through U1X one-shot to avoid multiple interrupts.
There is no way to implement "Software Based Debouncing using Debounce.h Library)" as the MCU goes to the ISR (Interrupt Service Routine) at the very first occurrence of the interrupting signal.
Yes.
Even a good switch (e.g. Omron microswitches) can be "very noisy" as the mechanical parts take a little bit of time to settle and is rated at about 1ms. Processor clocks have gone way up so they are detecting the (bouncing) state during when the switch is reacting. The way you want to debounce is, immediately after detecting a rising edge (or falling edge), ignore any pin changes for, say, 1ms.
Or simply poll the buttons at regular interval (e.g. 60Hz).
If interrupts are a requirement, then I would suggest adding a 0.22μF capacitor from the button input to GND. When using INPUT_PULLUP, this will:
provide adequate "wetting current" in order to exceed the button's minimum current rating and help prevent oxidation from accumulating on the contacts.
provide lower impedance and much increased immunity to noise.
provide hardware debounce having time constant of 7-11 ms.
prevent multiple consecutive interrupts from occurring when only one is required per button press.