I am new to Arduino. I am modifying the Crystal Ball project from the Arduino Beginner's Kit and am adding a pushbutton to change the brightness of the LCD. My problem is that the button is not interrupting.
I am using an Arduino Uno.
Here is my sketch:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,7);
long bounce_duration = 20;
volatile unsigned long bounceTime = 0;
enum displayBrightness{
off = 0,
low = 64,
medium = 128,
high = 255
};
volatile displayBrightness brightness = low;
const int brightnessTogglePin = 2;
const int brightnessPin = 9;
const int switchPin = 6;
int switchState = 0;
int prevSwitchState = 0;
int reply;
void setup(){
Serial.begin(9600);
lcd.begin(16,2);
pinMode(switchPin,INPUT);
pinMode(brightnessPin,OUTPUT);
lcd.print("Ask the");
lcd.setCursor(0,1);
lcd.print("Crystal ball");
attachInterrupt(brightnessTogglePin,toggleBrightness,LOW );
analogWrite(brightnessPin,brightness);
}
void loop(){
Serial.println(brightness);
switchState = digitalRead(switchPin);
analogWrite(brightnessPin,brightness);
if(switchState != prevSwitchState){
if(switchState == LOW){
reply = random(8);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("The ball says:");
lcd.setCursor(0,1);
switch(reply){
case 0:
lcd.print("Yes");
break;
case 1:
lcd.print("Most Likely");
break;
case 2:
lcd.print("Certainly");
break;
case 3:
lcd.print("Outlook Good");
break;
case 4:
lcd.print("Unsure");
break;
case 5:
lcd.print("Ask Again");
break;
case 6:
lcd.print("Doubtful");
break;
case 7:
lcd.print("No");
break;
}
}
}
prevSwitchState = switchState;
}
void toggleBrightness(){
if(millis() > bounceTime){
if(brightness == off){
brightness = low;
}
else if(brightness == low){
brightness = medium;
}
else if(brightness == medium){
brightness = high;
}
else{
brightness = off;
}
bounceTime = millis() + bounce_duration;
}
}
const int brightnessTogglePin = 2; // Using digital input pin 2 for INT0 function
attachInterrupt((brightnessTogglePin -2),toggleBrightness,RISING );
You are in fact wiring something to and using arduino digital pin 2, which the constant name implies so just handle the fact that pin 2 is interrupt 0 and pin 3 is interrupt 1 as a calculation adjustment inside the attachInterrupt argument list. No?
Not a great suggestion, this would not work on 32u4 based devices where the interrupt/pin mappings are different. Users have a better change of figuring out why these things do not work across boards when the pin and interrupt numbers are represented rather than calculated on an assumed offset which does not hold across boards.
Speaking from experience of porting some interrupt code form 328s to 32u4's this week.
You might consider using pull-up resistors instead of pull-down. The way you have it wired, if you accidentally had the internal pull-up resistors on, they would be wasting power in the pull-down resistor. Also, they would over-ride the large 1M resistor you have, making it so that the pin is never LOW. I would use a smaller resistor at least, maybe 10k - 47k to make sure that the pin is really pulled LOW when the button is up.
afremont:
You might consider using pull-up resistors instead of pull-down. The way you have it wired, if you accidentally had the internal pull-up resistors on, they would be wasting power in the pull-down resistor. Also, they would over-ride the large 1M resistor you have, making it so that the pin is never LOW. I would use a smaller resistor at least, maybe 10k - 47k to make sure that the pin is really pulled LOW when the button is up.
Can you elaborate?
What is an internal pull-up resistor?
How would I accidentally have the internal pull up resistor on?
Should I wire it in a pull-up fashion from now on?
The ports have internal pull-up resistors that can be enabled when a pin is in INPUT mode. You can find them described in the datasheet. There are very weak and can supply only a limited amount of current. They are enabled on an INPUT pin by writing a logic HIGH to the input pin. You can go either way, but pull-up is more common today I think.
The biggest issue with using simple passive switch buttons as interrupt sources isn't with how the pull-up or pull-down is accomplished (although that issue must be satisfied) but rather how one is going to deal with switch contact bounce which is not a simple matter then the switch is generating interrupt requests.
retrolefty:
The biggest issue with using simple passive switch buttons as interrupt sources isn't with how the pull-up or pull-down is accomplished (although that issue must be satisfied) but rather how one is going to deal with switch contact bounce which is not a simple matter then the switch is generating interrupt requests.
Lefty
Sure it is, you just use a couple of resistors and a cap externally, bounce-be-gone.
retrolefty:
The biggest issue with using simple passive switch buttons as interrupt sources isn't with how the pull-up or pull-down is accomplished (although that issue must be satisfied) but rather how one is going to deal with switch contact bounce which is not a simple matter then the switch is generating interrupt requests.
Lefty
I did read something about debouncing including how to deal with it with hardware and software. The software version involved using delay() to wait for it to debounce. The hardware version is similar to what was mentioned in this thread, but the person added an extra piece of hardware. Since I didn't have it, I didn't bother with it. I also haven't seen any issues with the switch bouncing and I don't know why.
afremont:
retrolefty:
The biggest issue with using simple passive switch buttons as interrupt sources isn't with how the pull-up or pull-down is accomplished (although that issue must be satisfied) but rather how one is going to deal with switch contact bounce which is not a simple matter then the switch is generating interrupt requests.
Lefty
Sure it is, you just use a couple of resistors and a cap externally, bounce-be-gone.
Is it that simple? The videos I have been watching described something with one more componenet, although it did use a capacitor. Here is the video for reference.
He is using a Schmitt trigger (inverting) to help clean up the pulse. Schmitt triggers have built in hysteresis to help prevent multiple back and forth flipping at the threshold voltage and they also don't care how slow the signal changes. It would be ideal to have one, but I'm thinking that if you tinker with the resistor(s) a little, you'll get it to work reliably straight into the CMOS input pin of your Uno. Try a 10k resistor and 1uF cap to start (or 100k and .1uF).
The software version involved using delay() to wait for it to debounce.
Yes, delay() can be used as an effective software debounce method for simple polled switches, but the delay() command does not work inside interrupt ISR functions so a more elaborate method must be used. Hardware debouncing once optimized (or tuned) for the switch being used, will work equally well as a simple polled input or as a interrupt source.
Hi,
Been searching for a hardware debounce solution to my project and happened upon this. I have a motor start/stop switch on interrupt pin 2 set up as an input with pullups turned on. Using a software solution is not going to work as I am using a timer to send a high frequency signal to a stepper driver and polling isn't an option. Everything works great but the stepper will not turn on/of reliably due to the switch bounce. I have seen hardware solutions on the internet and a few involve schmitt trigger devices others don't, and the cap/res one seems to fit. I have a good selection of resistors and capacitors but not a lot of time to play around with finding the right combination. Can anyone elaborate on a suitable schematic and cap/res values that will help cure a switch with around a 10 millisecond debounce time...?