Skip to content

Instantly share code, notes, and snippets.

@kav2k
Last active December 31, 2015 20:19
Show Gist options
  • Save kav2k/8039241 to your computer and use it in GitHub Desktop.
Save kav2k/8039241 to your computer and use it in GitHub Desktop.
This sketch demonstrates how to set up and use Pin Change Interrupt to catch button presses on BlinkyTape.
// Example sketch for using interrupt-based button press detection
// It will check button state every 500ms and display it along with the push count
// It also sends this information over serial
#include <FastSPI_LED2.h>
#define LED_COUNT 60
struct CRGB leds[LED_COUNT];
#define LED_OUT 13
#define BUTTON_IN 10
#define ANALOG_INPUT A9
#define IO_A 7
#define IO_B 11
// Button interrupt variables and Interrupt Service Routine
volatile uint8_t button_state = 0;
volatile int button_push_count = 0;
ISR(PCINT0_vect){ // Will be called on both pressing and releasing
button_state = !(PINB & (1 << PINB6)); // Reading state of the PB6 (remember that HIGH == released)
button_push_count += button_state; // If pressed, increment push count
}
// Function to check whether the button was pressed since its last call
// If you just need to know whether the button was pressed,
// check for button_push_count and clear it if non-zero
void check_button(){
static int last_count = 0;
static uint8_t last_state = 0;
int new_count = button_push_count;
uint8_t new_state = button_state;
if((new_count != last_count) || (new_state != last_state)){
Serial.print("Interrupt triggered, count: ");
Serial.print(new_count);
Serial.print(", state: ");
Serial.println((new_state)?"pressed":"released");
last_count = new_count;
last_state = new_state;
}
for (int i = 0; i < 5; i++) {
if(new_state){
leds[i] = CRGB(0, 50, 0);
} else {
leds[i] = CRGB(50, 0, 0);
}
}
for (int i = 5; i < LED_COUNT; i++) {
int j = 5 + new_count%(LED_COUNT-5);
if(i==j){
leds[i] = CRGB(50, 50, 50);
} else {
leds[i] = CRGB(0, 0, 0);
}
}
LEDS.show();
}
void setup()
{
Serial.begin(57600);
LEDS.addLeds<WS2811, LED_OUT, GRB>(leds, LED_COUNT);
LEDS.showColor(CRGB(0, 0, 0));
LEDS.setBrightness(93); // Limit max current draw to 1A
LEDS.show();
pinMode(BUTTON_IN, INPUT_PULLUP);
pinMode(ANALOG_INPUT, INPUT_PULLUP);
pinMode(IO_A, INPUT_PULLUP);
pinMode(IO_B, INPUT_PULLUP);
// Interrupt set-up; see Atmega32u4 datasheet section 11
PCIFR |= (1 << PCIF0); // Just in case, clear interrupt flag
PCMSK0 |= (1 << PCINT6); // Set interrupt mask to the button pin (PCINT6)
PCICR |= (1 << PCIE0); // Enable interrupt
}
void loop()
{
check_button();
delay(500);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment