I have a project that is limited on size and overall price. I am using an attiny85 to run 6 addressable rgbw leds. I need it to cycle through two different patterns of led flashing on a button press, then go to sleep on button press.
So it would look like this: all leds off, attiny in sleep mode (for battery life). press a button leds flash white, they continue to flash until the button gets pressed again then they change to a rainbow effect which continues until the button is pressed again, then led a turned off and attiny goes back to sleep.
The code I have is mostly cut up from other examples I could find of doing similar things, as I'm not proficient enough to write my own from scratch. I can get it to change between modes if i hold the button down for a second, which is fine with me, however it never enters sleep mode and battery life is very poor.
I've read everything I can find on attiny interrupts, I really just don't know where to go from here. is this even possible? what am I missing to get this thing to sleep. I sure would appreciate a shove in the right direction
#include <Adafruit_NeoPixel.h>
#include<avr/sleep.h>
#include<avr/interrupt.h>
#define BUTTON_PIN 2 // Digital IO pin connected to the button. This will be
// driven with a pull-up resistor so the switch should
// pull the pin to ground momentarily. On a high -> low
// transition the button press logic will execute.
#define PIXEL_PIN 4 // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT 6
// Parameter 1 = number of pixels in strip, neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_RGB Pixels are wired for RGB bitstream
// NEO_GRB Pixels are wired for GRB bitstream, correct for neopixel stick
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_RGBW + NEO_KHZ800);
bool oldState = HIGH;
int mode = 0;
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void sleep(){
GIMSK = 0b01000000; // turns on pin change interrupts
PCMSK = 0b00001000; // turn on interrupts on pins PB0, PB1, &amp; PB4
sei();
ADCSRA&=~_BV(ADEN);//ADC off
set_sleep_mode(SLEEP_MODE_PWR_DOWN);//replaces above statment
sleep_enable();//sets the sleep enable bit in the MCUCR Register (SE BIT)
sei();//enable interrupts
sleep_cpu();//sleep
cli();//disable interrupts
PCMSK&=~_BV(PCINT2);//turn off PB2? as interrupt pin
sleep_disable();//Clear SE bit
ADCSRA|=_BV(ADEN);//ADC on
sei();//enable interrupts
}//sleep
ISR(PCINT0_vect){
//This is called when the interrupt occurs, but it is not mandatory to do anything with it
buttonState++;
if (buttonState > 2)
buttonState=0;
}
void loop() {
// Get current button state.
bool newState = digitalRead(BUTTON_PIN);
// Check if state changed from high to low (button press).
if (newState == LOW && oldState == HIGH) {
// Short delay to debounce button.
delay(20);
// Check if button is still low after debounce.
newState = digitalRead(BUTTON_PIN);
if (newState == LOW) {
buttonState++;
if (buttonState > 2)
buttonState=0;
// startShow(buttonState);
}
}
// buttonState = digitalRead(BUTTON_PIN);{
if (buttonState == 0){
colorWipe(strip.Color(0, 0, 0,0), 50); // Black/off
delay(1000);
sleep;
}
else if (buttonState == 1){
theaterChase(strip.Color(0, 0, 0, 255), 50); // White
}
else if (buttonState == 2){
rainbowCycle(5);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}