Back to Parent

// 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!

0