Skip to content

Instantly share code, notes, and snippets.

@kav2k
Last active Dec 31, 2015
Embed
What would you like to do?
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