Hi there, I'm making a wire buzz game using a ATTiny 85 and I'm driving a Neopixel led strip and playing some songs on a passive piezzo buzzer.
The problem I have is that when playing a song or running a sequence on the leds, the loop won't check the flags until they are finished... So I'm thinking into using 3 interrupts (1 for the path beginning, another for the path end, and the third one for 'wire touched')
I attached the last one using this
attachInterrupt(0, blink, FALLING); //interrupt 0 == interruptPin == pin D 2
So I guess my questions are:
- how do to attach interrupts on pins 3 and 4
- is there any way to implement some sort of multitasking? (==> playing song while polling those 2 pins?)
Here is my code, note that beginning and end detection are not implemented yet and that I'm a newbie
//this is the code on a ATTiny85 8Mhz for a wire buzzer game...
#include <TimerFreeTone.h> //allows to use a 'tone' function equivalent on attiny (problems with timers....)
#include <Adafruit_NeoPixel.h> //this is for RGBW leds, single wire
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 0
#define NUM_LEDS 5
#define BRIGHTNESS 50
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
//const byte ledPin = 0;
const byte interruptPin = 2;
const byte TONE_PIN = 1; // Pin you have speaker/piezo connected to (be sure to include a 100 ohm resistor).
const byte startPin = 3;
const byte endPin = 4;
volatile bool touche = false;
uint32_t color;
bool neat=false; //to know if player arrived to victory without touching
int mode = 1; // for changing the NeoPixel modes
// byte neopix_gamma[] =....
// Les notes de musique
#define NOTE_B0 31
//****************************************************************************************
void allstrip (char colorordr, byte white=0); // defining a prototype cuz variable inputs)
void setup() {
//pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
pinMode(TONE_PIN, OUTPUT);
attachInterrupt(0, blink, FALLING); //interrupt 0 == interruptPin == pin D 2
pinMode(startPin, INPUT_PULLUP);
pinMode(endPin, INPUT_PULLUP);
// for NeoPixel
// This is for Attiny 5V 8MHz, you can remove these three lines if you are not using a Attiny/Trinket
#if defined (__AVR_ATtiny85__)
if (F_CPU == 8000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
strip.setBrightness(BRIGHTNESS);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
if (touche==true) //wire was touched
{
allstrip('r');
beep(150,500);
neat=false;
delay(500);
allstrip('x');
}
if (!digitalRead(startPin)) //handle is on the starting point
{
allstrip('g');
beep(400,1000);
neat=true;
allstrip('g',100); //greenish color
}
if (!digitalRead(endPin)) //victory
{
if neat
{
allstrip('b');
beep(450,200);
beep(800,200);
beep(1200,200);
delay(500);
}
else
{
allstrip('r',100);
beep(150,500);
}
}
else if (digitalRead(endPin)&&digitalRead(startPin)) //means player is playing
//Starwars();
//HarryPotter();
//mario(); //strident
//StarWars2(); //strident
switch (mode) {
case 1:
colorWipe(strip.Color(255, 0, 0), 500); // Red
delay(200);
colorWipe(strip.Color(0, 255, 0), 500); // Green
delay(200);
colorWipe(strip.Color(0, 0, 255), 500); // Blue
delay(200);
colorWipe(strip.Color(0, 0, 0, 255), 500); // White
delay(200);
break;
case 2:
whiteOverRainbow(200,40,5); //whiteOverRainbow(20,75,5);trop vite à changer //whiteOverRainbow(uint8_t wait, uint8_t whiteSpeed, uint8_t whiteLength )
delay(200);
break;
case 3:
rainbowFade2White(10,3,1); //très cool //rainbowFade2White(3,3,1);rainbowFade2White(uint8_t wait, int rainbowLoops, int whiteLoops)
delay(200);
break;
case 4:
allstrip('r');
delay(1000);
allstrip('g',100);
delay(1000);
break;
//default:
//break;
}
allstrip('x');
delay(500);
//digitalWrite(ledPin, LOW);
touche=false;
if (mode==4) mode=1;
else mode++;
}
}
//*****************************************************************************************
// interrupt function with debouncing
void blink() {
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
// If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 200)
{
touche=true;
}
last_interrupt_time = interrupt_time;
}