I’ve made a cloud connected cloud with 2 Wemos D1 minis, 70 neopixels, the FastLED library, and most importantly: Blynk!
There are several modes right now including lightning, solid color, mood lamp, rainbow with glitter, chase, and off. I got the idea from here, borrowed some code from here, and got advice/help from Jamin and Costas! It can be controlled via the Blynk App (my layout isn’t shown yet, I’ll try to upload it later) or a physical controller utilizing the Blynk Bridge.
Its not quite finished yet as I have to make a more permanent remote that is child proof, and I also have to wire the cloud portion more permanently so I can hang it in my daughters room.
This has been a great learning experience for me in Arduino, Blynk, wiring in general, soldering (never soldered until now), coding, and electronics in general! I hope you all like it!
Cloud code: (sorry for the lack of commenting, I’ll try to add some later…)
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <FastLED.h>
#include <SimpleTimer.h>
// How many leds in your strip?
#define NUM_LEDS 70
#define DATA_PIN 12
CRGB leds[NUM_LEDS];
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "CODE";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "NETGEAR67";
char pass[] = "PW";
int varonoff;
int qq = 0;
int varHue = 50;
int varSat = 255;
int varVal = 150;
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
WidgetTerminal terminal(V9);
SimpleTimer timer;
int chasetimer = 0;
int rainbowtimer = 0;
int solidtimer = 0;
int moodlamptimer = 0;
int LIGHTNINGtimer = 0;
int t1 = 0;
int t2 = 0;
int t3 = 0;
int L1 = 0;
int loop1 = 0;
int looplength = 0;
BLYNK_WRITE(V0) {
switch (param.asInt())
{
case 1: { // Item 1
timer.enable(chasetimer);
timer.disable(rainbowtimer);
timer.disable(solidtimer);
timer.disable(LIGHTNINGtimer);
timer.disable(moodlamptimer);
break;
}
case 2: { // Item 2
timer.enable(rainbowtimer);
timer.disable(chasetimer);
timer.disable(solidtimer);
timer.disable(LIGHTNINGtimer);
timer.disable(moodlamptimer);
break;
}
case 3: { // Item 3
timer.enable(solidtimer);
timer.disable(rainbowtimer);
timer.disable(chasetimer);
timer.disable(LIGHTNINGtimer);
timer.disable(moodlamptimer);
break;
}
case 4: { // Item 4
timer.enable(moodlamptimer);
timer.disable(rainbowtimer);
timer.disable(chasetimer);
timer.disable(LIGHTNINGtimer);
timer.disable(solidtimer);
break;
}
case 5: { // Item 5
timer.enable(LIGHTNINGtimer);
timer.disable(chasetimer);
timer.disable(rainbowtimer);
timer.disable(solidtimer);
timer.disable(moodlamptimer);
varHue = 190;
varSat = 20;
varVal = 255;
Serial.println("lightning enabled");
break;
}
case 6: { // Item 6
timer.disable(chasetimer);
timer.disable(rainbowtimer);
timer.disable(solidtimer);
timer.disable(LIGHTNINGtimer);
ledoff();
break;
}
default: {
Serial.println("Unknown item selected");
}
}
}
BLYNK_WRITE(V1)
{
varHue = param.asInt();
terminal.print("Hue: ");
terminal.println(varHue);
terminal.flush();
}
BLYNK_WRITE(V2)
{
varSat = param.asInt();
terminal.print("Saturation: ");
terminal.println(varSat);
terminal.flush();
}
BLYNK_WRITE(V3)
{
varVal = param.asInt();
terminal.print("Value: ");
terminal.println(varVal);
terminal.flush();
}
void setup()
{
Serial.begin(9600);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
Blynk.begin(auth, ssid, pass);
chasetimer = timer.setInterval(75L, chase);
rainbowtimer = timer.setInterval(20L, rainbowWithGlitter);
solidtimer = timer.setInterval(100L, solid);
moodlamptimer = timer.setInterval(100L, moodlamp);
LIGHTNINGtimer = timer.setInterval(300L, LIGHTNING);
timer.disable(chasetimer);
timer.disable(rainbowtimer);
timer.disable(solidtimer);
timer.disable(moodlamptimer);
timer.disable(LIGHTNINGtimer);
timer.setInterval(1000L,senduptime);
t1 = timer.setInterval(2L, v1);
t2 = timer.setInterval(100L, v2);
t3 = timer.setInterval(3L, v3);
timer.disable(t1);
timer.disable(t2);
timer.disable(t3);
}
void loop()
{
Blynk.run();
timer.run(); // Initiates SimpleTimer
FastLED.show();
}
void senduptime(){
Blynk.virtualWrite(V20, millis() / 1000);
}
void chase() {
fadeToBlackBy( leds, NUM_LEDS, 20);
leds[qq] = CHSV( varHue, varSat, varVal);
qq++;
if (qq >= 69){
qq = 0;
}
}
void rainbow()
{
// FastLED's built-in rainbow generator
fill_rainbow( leds, NUM_LEDS, gHue, 7);
gHue++;
}
void rainbowWithGlitter()
{
// built-in FastLED rainbow, plus some random sparkly glitter
rainbow();
addGlitter(80);
}
void addGlitter( fract8 chanceOfGlitter)
{
if ( random8() < chanceOfGlitter) {
leds[ random16(NUM_LEDS) ] += CRGB::White;
}
}
void ledoff(){
fill_solid(leds, NUM_LEDS, CRGB::Black);
}
void solid(){
fill_solid(leds, NUM_LEDS, CHSV(varHue,varSat,varVal));
}
void moodlamp(){
fill_solid(leds, NUM_LEDS, CHSV(varHue,varSat,varVal));
varHue++;
}
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//Lightning related functions start here
void LIGHTNING()
{
int randlightning = random8(100);
if (randlightning < 10){
switch (random(1,4)){
case 1:{
timer.enable(t1);
timer.disable(t2);
timer.disable(t3);
Serial.println("lightning case 1");
break;
}
case 2:{
timer.enable(t2);
timer.disable(t1);
timer.disable(t3);
Serial.println("lightning case 2");
break;
}
case 3:{
timer.enable(t3);
timer.disable(t2);
timer.disable(t1);
Serial.println("lightning case 3");
break;
}
}
}
}
void v1(){
//Serial.println(loop1);
if (loop1 == 0){
//FastLED.delay(random8(1000,2000));
looplength = random8(15,30);
L1 = random8(NUM_LEDS-looplength);
}
if (loop1 < looplength){
loop1++;
leds[L1] = CHSV( varHue, varSat, varVal);
L1++;
}
if (loop1 == looplength){
loop1 = 0;
ledoff();
FastLED.show();
FastLED.delay(random8(15,50));
for (int i = L1 - looplength; i <=L1; i++){
leds[i] = CHSV( varHue, varSat, varVal);
}
FastLED.show();
FastLED.delay(random8(15,50));
ledoff();
FastLED.delay(random8(50,100));
for (int i = L1 - looplength; i <=L1; i++){
leds[i] = CHSV( varHue, varSat, varVal);
}
FastLED.show();
FastLED.delay(random8(50,100));
ledoff();
timer.disable(t1);
}
FastLED.show();
}
void v2(){
solid();
FastLED.show();
FastLED.delay(random8(25,100));
ledoff();
FastLED.show();
FastLED.delay(random8(25,50));
solid();
FastLED.show();
FastLED.delay(random8(25,100));
ledoff();
FastLED.show();
FastLED.delay(random8(25,50));
solid();
FastLED.show();
FastLED.delay(random8(25,100));
ledoff();
FastLED.show();
FastLED.delay(random8(25,50));
timer.disable(t2);
}
void v3(){
if (loop1 == 0){
//FastLED.delay(random8(1000,2000));
looplength = random8(25,40);
L1 = random8(NUM_LEDS);
}
if (loop1 < looplength){
loop1++;
leds[L1] = CHSV( varHue, varSat, varVal);
L1 = random8(NUM_LEDS);;
}
if (loop1 == looplength){
loop1 = 0;
ledoff();
FastLED.delay(random8(25,50));
FastLED.show();
timer.disable(t3);
}
FastLED.show();
}
Remote Code:
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
char auth[] = "AUTHCODE";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "NETGEAR67";
char pass[] = "PW";
uint8_t varHueB = 0;
uint8_t varSatB = 0;
uint8_t varValB = 0;
int varModeB = 0;
// Bridge widget on virtual pin 1
WidgetBridge bridge1(V1);
// Timer for blynking
SimpleTimer timer;
void hueplus(){
varHueB = varHueB +10 ;
bridge1.virtualWrite(V1, varHueB);
}
void satplus(){
varSatB = varSatB +20 ;
bridge1.virtualWrite(V2, varSatB);
}
void valplus(){
varValB = varValB +20 ;
bridge1.virtualWrite(V3, varValB);
}
void modeplus(){
varModeB++;
if (varModeB > 5){
varModeB = 0;
}
bridge1.virtualWrite(V0, varModeB);
}
void setup()
{
//Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
while (Blynk.connect() == false) {
// Wait until connected
}
// Make pin 2 default HIGH, and attach INT to our handler
pinMode(2, INPUT_PULLUP); //wemos pin D4
pinMode(0, INPUT_PULLUP); //wemos pin D3
pinMode(4, INPUT_PULLUP); //wemos pin D2
pinMode(5, INPUT_PULLUP); //wemos pin D1
}
BLYNK_CONNECTED() {
bridge1.setAuthToken("otherAUTHCODE"); // Place the AuthToken of the second hardware here
}
int prevState4 = -1;
int currState4 = -1;
long lastChangeTime4 = 0;
int prevState3 = -1;
int currState3 = -1;
long lastChangeTime3 = 0;
int prevState2 = -1;
int currState2 = -1;
long lastChangeTime2 = 0;
int prevState1 = -1;
int currState1 = -1;
long lastChangeTime1 = 0;
void checkPin4()
{
// Invert state, since button is "Active LOW"
int state4 = !digitalRead(2);
// Debounce mechanism
long t4 = millis();
if (state4 != prevState4) {
lastChangeTime4 = t4;
}
if (t4 - lastChangeTime4 > 50) {
if (state4 != currState4) {
currState4 = state4;
if (state4 == 1){
valplus();
//Serial.println("button 4 pushed");
}
}
}
prevState4 = state4;
}
void checkPin3()
{
// Invert state, since button is "Active LOW"
int state3 = !digitalRead(0);
// Debounce mechanism
long t3 = millis();
if (state3 != prevState3) {
lastChangeTime3 = t3;
}
if (t3 - lastChangeTime3 > 50) {
if (state3 != currState3) {
currState3 = state3;
if (state3 == 1){
satplus();
//Serial.println("button 3 pushed");
}
}
}
prevState3 = state3;
}
void checkPin2()
{
// Invert state, since button is "Active LOW"
int state2 = !digitalRead(4);
// Debounce mechanism
long t2 = millis();
if (state2 != prevState2) {
lastChangeTime2 = t2;
}
if (t2 - lastChangeTime2 > 50) {
if (state2 != currState2) {
currState2= state2;
if (state2 == 1){
hueplus();
//Serial.println("button 2 pushed");
}
}
}
prevState2 = state2;
}
void checkPin1()
{
// Invert state, since button is "Active LOW"
int state1 = !digitalRead(5);
// Debounce mechanism
long t1 = millis();
if (state1 != prevState1) {
lastChangeTime1 = t1;
}
if (t1 - lastChangeTime1 > 50) {
if (state1 != currState1) {
currState1 = state1;
if (state1 == 1){
modeplus();
//Serial.println("button 1 pushed");
}
}
}
prevState1 = state1;
}
void loop()
{
Blynk.run();
timer.run();
checkPin4();
checkPin3();
checkPin2();
checkPin1();
}