// This #include statement was automatically added by the Particle IDE.
#include <libfixmath.h>
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>
// This #include statement was automatically added by the Particle IDE.
#include <math.h>
#include <neopixel.h>
#include <Particle.h>
//Set the neopixel to pin 5
#define PIXEL_PIN D5
//Set the pixel count
#define PIXEL_COUNT 32
//Set the neopixel type
#define PIXEL_TYPE WS2812
//Set the rotary encoder pins
#define encoder0PinA D2 // CLK
#define encoder0PinB D3 // DT
#define encoderPushPin D4 // SW
// Rotary Encoder Setup
int encoder0Pos = 0;
int encoder0PinALast = LOW;
int n = LOW;
int modeChange = 0;
// Neopixel Setup
int num_options = 4;
int steps = 5;
int indices = 0;
int prev_idx = 0;
//Create the neopixel strip function
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
unsigned long lastButtonPress = 0;
long last_on = 0;
long last_low = 0;
//This determines the minimum brightness
int pwr_min = 10;
//This determines the starting brightness but will change
int pwr = 20;
//This determines highest brightness
int pwr_max = 50;
//Neopixel color set up
uint32_t off = strip.Color(0,0,0);
uint32_t color = strip.Color(pwr*r,pwr*g,pwr*b);
uint32_t test = strip.Color(pwr*r,0,0);
uint32_t low_light = strip.Color(pwr_min*r,pwr_min*g,pwr_min*b);
void setup() {
Serial.begin(9600);
pinMode (encoder0PinA, INPUT);
pinMode (encoder0PinB, INPUT);
pinMode (encoderPushPin, INPUT_PULLUP);
//This determines the color, using the brightness indicator
uint32_t color = strip.Color(pwr, pwr, pwr);
strip.begin();
strip.show();
//Neopixel lights up when connected
for(int j=0; j < strip.numPixels(); j++)
{
strip.setPixelColor(j,color);
strip.show();
}
delay(1000);
for(int j=0; j< strip.numPixels(); j++)
{
strip.setPixelColor(j, off );
strip.show();
}
// subscribe to Donner
Particle.subscribe( "D2F_CW", handleCW );
Particle.subscribe( "D2F_CCW", handleCCW );
Particle.subscribe( "D2F_BTN", handleBTN );
}
void loop() {
// Get index of lighting mode
rotary();
// add mode change (1 or -1 or 0) to current indices
indices = indices + modeChange;
// make sure indices can only be 0,1,2,3
if (indices > 3) {
indices = 0;
}
if (indices < 0) {
indices = 3;
}
// Read Rotary Button
int btnState = digitalRead(encoderPushPin);
if (btnState == LOW) {
// reset when button is pushed
indices = 0;
encoder0Pos = 0;
Particle.publish( "F2D_BTN" ); // sync the other lamp
}
// Light up Neopixel
if (prev_idx != indices) {
Serial.printf("indices: %d\n", indices);
Serial.printf("prev_idx: %d\n", prev_idx);
// 0 - off
if( indices == 0 ){
for(int j=0; j< strip.numPixels(); j++){
strip.setPixelColor(j, off );
strip.show();
}
}
// 1 - on
else if( indices == 1 ){
for(int j=0; j< strip.numPixels(); j++) {
strip.setPixelColor(j, color );
strip.show();
}
}
}
// 2 - breath
if( indices == 2 ) {
breathe( 1 );
}
// 3 - flutter
else if( indices == 3 ) {
flutter(1);
}
prev_idx = indices;
}
// Calc the sin wave for the breathing white led
void breathe( uint8_t wait ){
// CITATION: reference code from Daragh
float val = (exp(sin(millis()/2000.0*M_PI)) - 0.36787944)*108.0;
Serial.println( val );
uint16_t i;
uint32_t c = strip.Color(val/2, val/2, val/2);
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
strip.show();
delay(wait);
}
void flutter( uint8_t wait ){
long now = millis();
if(now - last_on > 1000) // low light for 1s
{
for(int j=0; j < strip.numPixels(); j++)
{
strip.setPixelColor(j,low_light);
strip.show();
}
last_on = now;
}
delay(wait);
if(last_on - last_low >500) // on for 0.5s
{
for(int j=0; j < strip.numPixels(); j++)
{
strip.setPixelColor(j,color);
strip.show();
}
last_low = millis();
}
delay(wait);
}
// check mode index change
// output 1 (rotate CW) or -1 (rotate CCW) or 0 (no change)
void rotary() {
// read encoder pin A and pin B change to determine if encoder position has changed,
// and count the change as encoder0Pos
n = digitalRead(encoder0PinA);
if ((encoder0PinALast == LOW) && (n == HIGH))
{
if (digitalRead(encoder0PinB) == LOW) {
encoder0Pos++;
}
else {
encoder0Pos--;
}
}
encoder0PinALast = n;
// mode change to next or previous every 5 steps
if (encoder0Pos > 4) {
modeChange = 1; // mode change to next
Particle.publish( "F2D_CW" ); // sync the other lamp if mode change
encoder0Pos = 0; // reset encoder step count
}
else if (encoder0Pos < -4) {
modeChange = -1; // mode change to previous
Particle.publish( "F2D_CCW" ); // sync the other lamp if mode change
encoder0Pos = 0; // reset encoder step count
}
else {
modeChange = 0; // no mode change
}
}
// handle event from Donner
// rotate clockwise
void handleCW (const char *event, const char *data) {
indices = indices + 1;
}
// rotate counter-clockwise
void handleCCW (const char *event, const char *data) {
indices = indices - 1;
}
// button pushed - reset
void handleBTN (const char *event, const char *data){
indices = 0;
encoder0Pos = 0;
}
Click to Expand
Content Rating
Is this a good/useful/informative piece of content to include in the project? Have your say!
You must login before you can post a comment. .