Skill Dev III - Wei Liang

Made by Wei Liang

Created: November 30th, 2020

0

Intention

In this lab we will learn to use neopixels to achieve ambient design and IFTTT to trigger the design by certain information.

0

Neopixel Exercise 1

Modify the code to light up pixel by pixel then reverse the sequence turning each pixel off one by one.

0

Approach

The tricky part of this exercise is to build a reverse for loop to turn off each pixel one by one.

The initial condition of the reverse loop should be uint16_t i=strip.numPixels()-1, since the maximum number of the pixel should be 15 given the fact that the numbers list from 0 to 15 in the neopixel library.

I only use one function to achieve both loops by adding an indicator showing if the loop inside the function is in ascending or descending order.

Actually, I left one pixel out since if I terminate the reverse loop at i>=o instead of i>0, all the pixels turn off but the loop also terminates. Thus I have to leave one pixel out and directly start the next loop.

The video is attached.

0
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_PIN D4
#define PIXEL_COUNT 16
#define PIXEL_TYPE WS2812

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

void setup() {

    strip.begin();
    strip.setBrightness(50);
    strip.show(); // Initialize all pixels to 'off'
}

void loop() {
    uint8_t wait = 500;
    uint32_t c = strip.Color(255, 255, 255);
    uint32_t off = strip.Color(0, 0, 0);

    colorWipe(c, wait, 0);
    colorWipe(off, wait, 1);

}

// Fill the dots one after the other with a color, wait (ms) after each one
void colorWipe(uint32_t c, uint8_t wait, uint8_t reverse) {
    if (reverse == 0) {
        for(uint16_t i=0; i<strip.numPixels(); i++) {
            strip.setPixelColor(i, c);
            strip.show();
            delay(wait);
        }
    } else if (reverse == 1) {
        for(uint16_t i=strip.numPixels()-1; i>0; i--) {
            strip.setPixelColor(i, c);
            strip.show();
            delay(wait);
        }
    } else {
        return;
    }
    return;
}
Click to Expand
0
Neopixel Ex1
Wei Liang - https://youtu.be/iOQtAoFxZCE
0

Neopixel Exercise 2

Modify the code to light up blue, then red, then green then white in sequence.

0

Approach

I use colorAll function to turn on all the pixels at a certain color simultaneously. The key difference between colorAll and colorWipe is the positioning of strip.show() function - if it is inside the loop, it is lighting up the neopixel one by one; if it is outside the loop, it is turning all the neopixel on/off simualtaneously.

The video is attached.

0
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>


// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_PIN D4
#define PIXEL_COUNT 16
#define PIXEL_TYPE WS2812

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

void setup() {

    strip.begin();
    strip.setBrightness(50);
    strip.show(); // Initialize all pixels to 'off'
}

void loop() {

    uint8_t wait = 200;
    uint32_t red = strip.Color(255, 0, 0);
    uint32_t blue = strip.Color(0, 0, 255);
    uint32_t green = strip.Color(255, 255, 0);
    uint32_t white = strip.Color(255, 255, 255);

    colorAll(blue, wait);
    colorAll(red, wait);
    colorAll(green, wait);
    colorAll(white, wait);
}

// Set all pixels in the strip to a solid color, then wait (ms)
void colorAll(uint32_t c, uint8_t wait) {
    uint16_t i;

    for(i=0; i<strip.numPixels(); i++) {
        strip.setPixelColor(i, c);
    }
    strip.show();
    delay(wait);
}
Click to Expand
0
Neopixel Ex2
Wei Liang - https://youtu.be/aD2xviJTXSA
0

Neopixel Exercise 3

Change the code to only light up only one pixel at a time. With each loop move that pixel one position higher. When it reaches the final pixel, restart the sequence at zero i.e. build a single pixel that will continually cycle.

0

Approach

I wrote a function call colorSingle to achieve this feature. Note that I change the data type wait to achieve larger wait time as the original wait time is only 8 digits (256 millis). In the for loop we only need to add an extra line to turn off the same pixel.

The video is attached.

0
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_PIN D4
#define PIXEL_COUNT 16
#define PIXEL_TYPE WS2812

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

void setup() {

    strip.begin();
    strip.setBrightness(50);
    strip.show(); // Initialize all pixels to 'off'
}

void loop() {
    uint64_t wait = 500;
    uint32_t c = strip.Color(255, 255, 255);
    uint32_t off = strip.Color(0, 0, 0);

    colorSingle(c, wait);

}

// Fill the dots one after the other with a color, wait (ms) after each one
void colorSingle(uint32_t c, uint64_t wait) {
    for(uint16_t i=0; i<strip.numPixels(); i++) {
        strip.setPixelColor(i, c);
        strip.show();
        delay(wait);
        strip.setPixelColor(i, 0);
    }
}
Click to Expand
0
Neopixel Ex3
Wei Liang - https://youtu.be/4JpCbNkDMm8
0

Neopixel Exercise 4

Add three Particle.function to set the Red, Green and Blue components. Allow these values to be set from 0-255 and as they are set to change all of the pixels on the LED strip to that color.

0

Approach

I wrote only one Particle.function instead of three by parsing the command input. The format of input should be r,g,b that each of the letters represents the Red, Green, and Blue components. The remaining of the Particle.function calls colorAll function to light the pixels.

The video is attached.

0
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_PIN D4
#define PIXEL_COUNT 16
#define PIXEL_TYPE WS2812

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
int redValue = 255; // Full brightness for an Cathode RGB LED is 0, and off 255
int greenValue = 255; // Full brightness for an Cathode RGB LED is 0, and off 255
int blueValue = 255; // Full brightness for an Cathode RGB LED is 0, and off 255

void setup() {
    strip.begin();
    strip.setBrightness(50);
    strip.show(); // Initialize all pixels to 'off'
    Particle.function("set_color", colorSingle);

    Particle.variable("Red", redValue);
    Particle.variable("Green", greenValue);
    Particle.variable("Blue", blueValue);
}

void loop() {

}

int colorSingle(String command) {
    String colors[3];
    char charBuf[20];
    char *token;
    uint32_t c;
    uint8_t wait = 200;
    const char *s = ",";
    int i = 1;
    command.toCharArray(charBuf, 20);
    /* get the first token */
    token = strtok(charBuf, s);
    colors[0] = token;
    /* walk through other tokens */
    while( token != NULL ) {
        token = strtok(NULL, s);
        colors[i] = token;
        i++;
    }
    
    redValue = colors[0].toInt();
    greenValue = colors[1].toInt();
    blueValue = colors[2].toInt();
    Particle.publish("status","changing color");
    c = strip.Color(redValue, greenValue, blueValue);
    colorAll(c, wait);
    return 1;
}

// Set all pixels in the strip to a solid color, then wait (ms)
void colorAll(uint32_t c, uint8_t wait) {
    uint16_t i;

    for(i=0; i<strip.numPixels(); i++) {
        strip.setPixelColor(i, c);
    }
    strip.show();
    delay(wait);
}
Click to Expand
0
Neopixel Ex4
Wei Liang - https://youtu.be/dFk9kg0wnno
0

Practice Exercise: Ambient Calendar Alert

The final practice exercise needs to combine neopixel with IFTTT. My IFTTT set up is as follows:

When any google calendar is 15 minutes away, call the Particle.function with the input of time duration of the alert. For simplicity of the demonstration, the time duration of each phase is set as only 1 minute.

The three phases of the alerts are inline with the advanced requirement on the course website:

  1. 15 minutes before the calendar event starts, the ambient alert will begin displaying.
  2. It will fade up slowly for 10 minutes to solid white
  3. 5 minutes before the meeting, the color will begin to slowly change from white to red over those 5 minutes.
  4. At the time when the meeting takes place, the ambient display will present as red
  5. Then it will slowly fade out over 5 more minutes.

0
// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

// IMPORTANT: Set pixel COUNT, PIN and TYPE
#define PIXEL_PIN D4
#define PIXEL_COUNT 16
#define PIXEL_TYPE WS2812

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

int redValue = 0; // Full brightness for an Cathode RGB LED is 0, and off 255
int greenValue = 0; // Full brightness for an Cathode RGB LED is 0, and off 255
int blueValue = 0; // Full brightness for an Cathode RGB LED is 0, and off 255

unsigned long lastFade = 0;


void setup() {
    
    strip.begin();
    strip.setBrightness(50);
    strip.show(); // Initialize all pixels to 'off'
    
    // Particle.function("fade_up", colorFadeUp);
    // Particle.function("to_red", colorFadeRed);
    // Particle.function("fade_out", colorFadeOut);
    
    Particle.function("time input", colorSeq);
    
    Particle.variable("Red", redValue);
    Particle.variable("Green", greenValue);
    Particle.variable("Blue", blueValue);
}

void loop() {

}

int colorSeq(String command) {
    unsigned long t = command.toInt();
    uint64_t wait = t * 1000;
    uint32_t c;
    
    
    c = strip.Color(redValue, greenValue, blueValue);
    colorAll(c, wait);
    
    lastFade = millis();
    while(millis() - lastFade <= t * 60 * 1000) {
        redValue += 4;
        greenValue += 4;
        blueValue += 4;
        c = strip.Color(redValue, greenValue, blueValue);
        colorAll(c, wait);
    }
    
    lastFade = millis();
    while(millis() - lastFade <= t * 60 * 1000) {
        greenValue -= 4;
        blueValue -= 4;
        c = strip.Color(redValue, greenValue, blueValue);
        colorAll(c, wait);
    }
    
    lastFade = millis();
    while(millis() - lastFade <= t * 60 * 1000) {
        redValue -= 4;
        c = strip.Color(redValue, greenValue, blueValue);
        colorAll(c, wait);
    }
    colorAll(0, wait);
    return 1;
}

int colorFadeUp(String command) {
    int t = command.toInt();
    uint64_t wait = t * 1000;
    uint32_t c;
    
    
    c = strip.Color(redValue, greenValue, blueValue);
    colorAll(c, wait);
    
    unsigned long now = millis();
    while(now - lastFade <= t * 60 * 1000) {
        redValue += 4;
        greenValue += 4;
        blueValue += 4;
        c = strip.Color(redValue, greenValue, blueValue);
        colorAll(c, wait);
        now = millis();
    }
}

int colorFadeRed(String command) {
    int t = command.toInt();
    uint64_t wait = t * 1000;
    uint32_t c;
    
    redValue = 255;
    greenValue = 255;
    blueValue = 255;
    
    unsigned long lastFade = 0;
    
    c = strip.Color(redValue, greenValue, blueValue);
    colorAll(c, wait);
    unsigned long now = millis();
    
    while(now - lastFade <= t * 60 * 1000) {
        greenValue -= 4;
        blueValue -= 4;
        c = strip.Color(redValue, greenValue, blueValue);
        colorAll(c, wait);
        now = millis();
    }
    return 1;
}

int colorFadeOut(String command) {
    int t = command.toInt();
    uint64_t wait = t * 1000;
    uint32_t c;
    
    redValue = 255;
    greenValue = 0;
    blueValue = 0;
    
    unsigned long lastFade = 0;
    
    c = strip.Color(redValue, greenValue, blueValue);
    colorAll(c, wait);
    unsigned long now = millis();
    
    while(now - lastFade <= t * 60 * 1000) {
        redValue -= 4;
        c = strip.Color(redValue, greenValue, blueValue);
        colorAll(c, wait);
        now = millis();
    }
    colorAll(0, wait);
    return 1;
}

// Set all pixels in the strip to a solid color, then wait (ms)
void colorAll(uint32_t c, uint64_t wait) {
    uint16_t i;

    for(i=0; i<strip.numPixels(); i++) {
        strip.setPixelColor(i, c);
    }
    strip.show();
    delay(wait);
}

// Button press interrupt service routine
void buttonPressInterrupt(){
    buttonPressFlag = true;
}
Click to Expand
0

The video below shows the process of the alert: how the alert is triggered by a google calendar event; the pixels fade up from dim white to solid white (increasing RGB values simultaneously in 1 minute); then fade the pixels from solid white to solid red (decreasing green and blue values from 255 to 0 in 1 minute); then fade out the pixels to dark (decreasing red value from 255 to 0 in 1 minute)

0
Neopixel IFTTT
Wei Liang - https://youtu.be/nSF8hd9q6Oo
0

Reflection

In this lab, I had a lot of fun playing with neopixels, and also got a chance to know IFTTT as a powerful IoT tool.

x