-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNeoPixel_Interrupt_Sleep_ATTiny85.ino
151 lines (119 loc) · 4.46 KB
/
NeoPixel_Interrupt_Sleep_ATTiny85.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/// Interrupt-triggered "Motion Activated" NeoPixel Light for ATTiny85
// Created by: David R Ratliff
// October, 2013
// In the public domain
// Created, written, and tested on Digispark ATTiny85 based Arduino compatible platform
// This sketch simply sets an interrupt on pin, puts ATTiny to sleep...
// waits for interrrupt, and runs 'light show'
// Interupt was designed for an active HIGH PIR sensor, but can use anything which outputs
// a digital high signal to trigger the interrupt and activate the NeoPixel program
//
#include <Adafruit_NeoPixel.h> // Library for Adafruit NeoPixels
#include <avr/sleep.h> // Library for ATTiny 'sleep' functionality
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#define PIN 0 // Pin on which NeoPixels are attached
byte PIR = 5; // Interrupt pin
byte LED = 1; // Status/debugging LED pin (turns on when sleep mode entered)
// This should probably be disabled for energy efficiency!
// Parameter 1 = number of pixels in strip
// 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
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800);
void setup()
{
pinMode(PIR, INPUT);
digitalWrite(PIR, LOW);
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
sbi(GIMSK, PCIE); // Turn on Pin Change Interrupt on port
sbi(PCMSK, PCINT5); // Which particular pin affected by interrupt
strip.begin();
strip.show(); // Initialize all pixels to 'off'
delay(1000); // Small pause on startup
colorWipe(55, 10); // Simple color display to signal that everything is working! YAY!
strip.show();
delay(20000); // give PIR time to "settle" before initiating sleep & interrupt
}
void loop()
{
// What do you want to happen while 'awake'
if(digitalRead(PIR)) // IF motion activity - (PIR pin HIGH)
{
rainbowCycle(10); // show rainbow cycle on NeoPixels (All colors at same time)
rainbowCycle(5); // show rainbow cycle on NeoPixels
rainbowCycle(0); // show rainbow cycle on NeoPixels
return;
}
else // If no motion - after motion stops
{
rainbow(15); // signals about to shut off (one color at a time)
colorWipe((0),0); // turn them off
system_sleep(); // do nothing...prepare for sleep
}
}
// 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);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; 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);
}
}
// 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) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
void system_sleep() // Goin' to bed!
{
digitalWrite(LED, HIGH); // Turn onboard LED ON to indicate sleep mode (Debug feedback)
delay(20);
cbi(ADCSRA,ADEN); // Switch analog to digital converter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // set sleep mode
sleep_mode(); // system sleeps here
sbi(ADCSRA,ADEN); // switch ADC ON - after interrupt wakes up ATTiny
digitalWrite(LED, LOW); // Turns onbaord LED OFF at wake-up (more debug feedback)
}
ISR(PCINT0_vect)
{
}