Wednesday, June 5, 2013

Adding a #hardware #interrupt to my #arduino project

Moving toward my goal of making a "catch the light" game, I needed to master hardware interrupts. To that end, I added a single blue led and a button. The button was connected to interrupt 0 which is pin 2 on the Arduino board and ground. The LED was wired to pin 12 and ground. I used the scanning code that basically started lighting LEDs, one at a time, from both ends moving to the center and back out. The goal being to light the blue LED when I push the button without interrupting the scanning. I took the basic code, and added an attachInterrupt() function on interrupt 0, setting it to trip when the value was LOW. When this pin is pulled LOW by grounding it, the "pushit" handler is called:
    attachInterrupt(0,pushit,LOW);
I also added variables to hold the time in milliseconds and the lasttime in milliseconds.  These are needed to "debounce" the button. 
unsigned long time;
unsigned long lasttime;

Debounce, what am I talking about?
The problem is, when you push a button, as the contacts come together, the Arduino moving so fast, may think the button was pushed multiple times which would turn off the LED possibly before you even noticed it was on. To debounce it, you keep track of when the last time the button was pressed, so that when the interrupt is tripped, it compares the current time against the previous time and if it has been longer than 50 milliseconds, it will consider it to be a new button press:
  if (time-lasttime>50){

Putting it all together
Now when the sketch runs, the LED is set to LOW with a digitalWrite(), the interrupt is set, and the main loop begins the scanning sequence. I press the button, the LED turns on instantly and the scanning continues. When I press the button again, the LED turns off and the scanning continues.
You may notice from the picture that I have also added a battery. The positive (red) lead goes to VIN (Voltage Input) and the black goes to ground.  Here's the code:

int dataPin = 10;        //Define which pins will be used for the Shift Register control
int latchPin = 9;
int clockPin = 8;

int seq1[14] = {1,2,4,8,16,32,64,128,64,32,16,8,4,2};  //The array for storing the 
      // byte #1 value
int seq2[14] = {128,64,32,16,8,4,2,1,2,4,8,16,32,64};  //The array for storing the 
      // byte #2 value
volatile int state=LOW;
unsigned long time;
unsigned long lasttime;
void setup()
{
    attachInterrupt(0,pushit,LOW);
    pinMode(dataPin, OUTPUT);       //Configure each IO Pin
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(12,OUTPUT);
    digitalWrite(12,state);
    lasttime==millis();
}
void loop()
{
    for (int x = 0; x < 14; x++)         //Array Index
    {
        digitalWrite(latchPin, LOW);            //Pull latch LOW to start sending data
        shiftOut(dataPin, clockPin, MSBFIRST, seq1[x]);         //Send the data byte 1
        shiftOut(dataPin, clockPin, MSBFIRST, seq2[x]);         //Send the data byte 2
        digitalWrite(latchPin, HIGH);           //Pull latch HIGH to stop sending data
        delay(75);
    }
}
void pushit()
{
  time=millis();
  if (time-lasttime>50){
    digitalWrite(12,!state);
    state=!state;
    lasttime = time;
  }
}



The next step, I'm going to try using the the 2 line LCD.

No comments:

Post a Comment