Tearing into some code that debounces a switch with an interupt.

Once again.. These are more my research notes… There are no guarantees that this is going to make any kind of sense to anyone other than me. I found some code that debounces a switch with a an Arduino interrupt that I  like from here. (Just a side note here… I guess I never figured out how to use this plugin to display code.. how to use is here It appears that for all these years it was my theme that was hosing up the works. ) So here goes..

modeSelectorWorking

[code collapse=”true” title=”Buggy Interupt code for debouncing a button” highlight=”6,12,16,22″ language=”cpp”]
/*
* ISR Debounce
*/

// use 2ms debounce time
#define DEBOUNCE_TICKS (word)microsecondsToClockCycles(2000)

extern volatile unsigned long timer0_overflow_count;
word keytick; // record time of keypress

void setup() {
attachInterrupt(0,KeyPress,FALLING);
}

void KeyPress() {
keytick=(word)timer0_overflow_count;
}

// returns true if key pressed
boolean KeyCheck() {
if (keytick!=0) {
if (((word)timer0_overflow_count-keytick)>DEBOUNCE_TICKS) {
keytick=0;
return true;
}
}
return false;
}

void loop()
{
if (KeyCheck()) {
// do something useful
}
}
[/code]

I tried adapting this code to create a mode select option for my arduino and it seemed like it should work but it doesn’t… @#%! One of the things that’s interesting about these embedded systems is the layers of added complexity over straight coding.. So at this point, I’m not sure if why this isn’t working. It could be on the hardware or software side of things. I don’t fully understand this arudino code, so I wanted to dissect the things that are new for me. So starting out looking at the code there are a few things that I’m a bit fuzzy on and look a bit strange to me. First off there is this..

[code collapse=”false” title=”This looks fishy” firstine=”6″ language=”cpp”]
#define DEBOUNCE_TICKS (word)microsecondsToClockCycles(2000)
[/code]
[code collapse=”false” title=”when used with this” firstline=”19″ highlight=”22″ language=”cpp”]
// returns true if key pressed
boolean KeyCheck() {
if (keytick!=0) {
if (((word)timer0_overflow_count-keytick)>DEBOUNCE_TICKS) {
keytick=0;
return true;
}
}
return false;
}
[/code]

There’s all kinds of things that look strange to me here. Not getting into the logic of what’s going one here it looks like we’re comparing apples and pomegranates here: DEBOUNCE_TICKS is in clock cycles and timer0_overflow_count is an arduino variable that accumulates . I spent a few days trying figure out how all this stuff worked, grepp’ng and googling what all this stuff means, but I found this to be concise and useful.   http://ucexperiment.wordpress.com/2012/03/16/examination-of-the-arduino-millis-function Basically timer0_overflow_count will increment after 64*256 clock cycles.. With a 16 Mhz time timer0_overflow_count itself with overflow in about 50 days (assuming I did my math correctly) and: clockCyclesPerMicrosecond = 16000000/1000000 = 16 MICROSECONDS_PER_TIMER0_OVERFLOW = ((64*256)*1000)/(16000000/1000) = 1024

[code collapse=”false” title=”Something looking fishy here ” firstine=”6″ language=”cpp”]
#define DEBOUNCE_TICKS (word)microsecondsToClockCycles(2000)
[/code]

So this should have a physical value of 16*2000 = 32000 clock ticks.. If I’m understanding this correctly this is comparing clock ticks to timer0_overflow_count increment’s The time difference works out to 1024*32000 = 32,768,000 micro second = 32 seconds. I would say this is wrong. I ran across a nice little tutorial and I thought a nice delay time would be about 200 Milliseconds.. So the way this interupt routine works is that every time the signal rises the interupts is triggered and the time is stored (as measured by timer0_overflow_count) The time gap needs to be 200 milli-seconds and it returns true one time and zero’s out the counter. So… in terms of over flow ticks we’re looking at 200000/1024 = 195.3125. Lets just call it 200. Soo.. I think I’ve gotten the code tweaked… ans still not joy. I’m using a seeedstudio electronic Brick Kit I had some code that I wanted to adapt using the interrupt debounced switch and have it display on an LCD display. Basically what I want the switch to do is to switch from one of four modes. It’s become highly annoying that I can’t get this to work, so I’m starting to strip things down to basics.. I had some suspicions that I had a bad switch. Ok.. (I did see a bent pin on the shield (Rx) that wasn’t seated), (I don’t think that was messing things up.) So I ran this program and the light came on when the switch was pressed.

[code collapse=”true” title=”Basic Led Switch ” language=”cpp”]
int Button = 9;
int LED = 8;
//define the 9th digital pin for button brick
//define the 8th digital pin for LED brick
void setup()
{
pinMode(LED,OUTPUT); //set the LED pin for digital output
pinMode(Button,INPUT); //set the Button pin for digital input
}
void loop()
{
if (digitalRead(Button))
digitalWrite(LED,HIGH);
else
digitalWrite(LED,LOW);
}
[/code]
Soo I’m concluding the switch is functional.
Now the next think I need to do is to get the switch over to Pin2 which reacts to a hardware interrupt.

For my purposes I need to set 4 modes of operation.. At this point I don’t have the 4 modes implemented but they are defined.. The mode selection is working.

[code collapse=”true” title=”Interupt code for debouncing a button and Mode Selection” language=”cpp”]
#include <LiquidCrystal.h>

const int potentiometerPin = 4; // analog pin used to connect the potentiometer
const int interuptPin = 2;

int currentPotValue;
int tempValueHigh;
int tempValueLow;
int tempValueCurrent;

#define MODE_OFF 0
#define MODE_SET_LOW 1
#define MODE_SET_HIGH 2
#define MODE_ON 3

LiquidCrystal lcd(10,11,12,13,14,15,16);

#define OVERFLOW_INCREMENENTS 300
extern volatile unsigned long timer0_overflow_count;

#define DEBOUNCE_TICKS (word)microsecondsToClockCycles(2000)

extern volatile unsigned long timer0_overflow_count;
word btnDownTime;

int modeValueCurrent = MODE_OFF;
int modeValuePrevious = MODE_ON;

void setup() {
attachInterrupt(0,btnDown,FALLING);
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0,0);

}

void btnDown()
{
btnDownTime=(word)timer0_overflow_count;
}

boolean btnDownCheck() {
if (btnDownTime!=0) {
if (((word)timer0_overflow_count-btnDownTime)>OVERFLOW_INCREMENENTS) {
btnDownTime=0;
return true;
}
}
return false;
}

void loop()
{
if (btnDownCheck()) {

modeValueCurrent++;
if (modeValueCurrent>MODE_ON)
{
modeValueCurrent=MODE_OFF;
}

if (modeValueCurrent !=modeValuePrevious)
{
//lcd.clear();
lcd.setCursor(0,0);
switch (modeValueCurrent)
{
case MODE_ON:
lcd.print("MODE:ON ");
break;
case MODE_SET_LOW:
lcd.print("MODE:LOW ");
break;
case MODE_SET_HIGH:
lcd.print("MODE:HIGH");
break;
case MODE_OFF:
lcd.print("MODE:OFF");

break;
default:
lcd.print("ERR");

break;

}
}

modeValuePrevious= modeValueCurrent;

}
}
[/code]

This entry was posted in Uncategorized. Bookmark the permalink.