Smart LED Strips: Revisited

As a present for my 1-year anniversary with my girlfriend, I decided to create an RGB mushroom with the same functionality as my smart LED strips, but with the additional option of being able to move it between wifi hotspots without having to reflash the firmware.
The hardware was fairly straightforward. I took one of the cheap RGB we had from aliexpress, and gutted it of the meager electronics it had used previously. I interfaced it to an ESP-12 breakout with a 1k resistor and 3D printed an enclosure for the ESP and a stand for the mushroom to hold the wires. I used a 1-amp usb power supply because I had one lying around and I might want to add more mushrooms later.

I did some preliminary research, and found a neat library for ESP chips called wifimanager that provides a function that will try to connect to an access point that you specify or has been connected to previously. If it can't, it'll start its own access point that you can connect to, with a configuration page that lets you configure the security for your access point. Simple!

...Except it wasn't. Not entirely. When I tried to install it using the library manager in the Arduino IDE it wouldn't work. Took me a few hours to figure out it wasn't my code that was wrong, and it wasn't the board that was wrong, but the library itself. Downloading the latest version from GitHub solved the problem though, and by modifying the Blynk.begin() function to Blynk.config(), I had a glowing mushroom with configurable wifi credentials!

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>         //https://github.com/tzapu/WiFiManager

#define PIN D7

char auth[] = "Auth Key";

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(3, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  /*#if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif*/
  // End of trinket special code
  Serial.begin(115200);
  WiFiManager wifiManager;
  wifiManager.autoConnect("MechaShroomie");
  Blynk.config(auth);
  strip.begin();
  strip.show(); // Initialize all pixels to '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);
  }
}

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);
}

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);
  }
}

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

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //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
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.

int rv = 0;
int gv = 0;
int bv = 0;

int red = 0;
int green = 0;
int blue = 0;

int on = 0;
double brightness = 1;

BLYNK_WRITE(1)
{
  if (param.asInt())
  {
      //HIGH
      on = 1;
  }
  else
  {
     //LOW
     on = 0;
  }
}

BLYNK_WRITE(2)
{
  rv = param.asInt();
  red = rv*brightness;
}

BLYNK_WRITE(3)
{
  gv = param.asInt();
  green = gv*brightness;
}

BLYNK_WRITE(4)
{
  bv = param.asInt();
  blue = bv*brightness;
}

BLYNK_WRITE(5)
{
  brightness = (param.asInt()+0.0)/255.0;
  red = brightness*rv;
  green = brightness*gv;
  blue = brightness*bv;
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  //colorWipe(strip.Color(255, 0, 0), 10); // Red
  //colorWipe(strip.Color(0, 255, 0), 10); // Green
  //colorWipe(strip.Color(0, 0, 255), 10); // Blue
  Blynk.run();
  if(on == 1)
    colorWipe(strip.Color(red, green, blue), 10); // Red
  else
    colorWipe(strip.Color(0,0,0), 10); // Red
  delay(100);
}

Comments

Popular posts from this blog

UMPC Adventures: the Mix Yoga

The Wearable Computer--A Synopsis