The orginal Design is from Thingyverse. I made some modifications. The top lid can be twisted on with a big thread. I also made a switch on the side to change modes, also added a 10k Potmeter to change the brightness of the light. I did not like the existing patterns so I made some myself (see code). See the thinyverse link for the stl files.
Fusion 360 Design
I used Fusion 360 to modify the other designs to my need. In my design I actualy used the twisted core. Right picture, because is was just easier, and I didn’t have to cut and solder the ledstrip. I modified the original core from 8 rows of 10 LEDS to 6 rows of ten LEDS, so I could use a one meter LED strip.
Original Designs
- https://www.myminifactory.com/object/3d-print-led-mood-lamp-87393
- https://www.thingiverse.com/thing:3676533
- https://www.thingiverse.com/thing:4790221
Thingyverse
https://www.thingiverse.com/thing:5147558
Switch and Potmeter I used for this project
Electrical design
The code
#include "FastLED.h"
#include <EEPROM.h>
#define NUM_LEDS 60
CRGB leds[NUM_LEDS];
#define PIN 5
const int sensorValue = analogRead(A1);
#define BUTTON 2
#define MAX_BRIGHTNESS 150 // Don't set it too high
#define MIN_BRIGHTNESS 7 // set to a minimum of 7%
byte selectedEffect=0;
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled- gemaakt om geen programma's over te slaan
unsigned long debounceDelay = 300 ; // the debounce time; increase if the output flickers gemaakt om geen programma's cases over te slaan
void setup()
{
//delay(3000); // in case we do something stupid. We dont want to get locked out.
//Serial.begin(9600);
FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
int mappedValue = map(sensorValue, 0, 1023, 7, 150); //hier worden de sensorwaarden omgezet naar Brightness waarden
FastLED.setBrightness(constrain(mappedValue, MIN_BRIGHTNESS, MAX_BRIGHTNESS)); //hier zetten we de Brightness afhankelijk van de stand van de POTmeter werk alleen bij overschakelen case
//Serial.println(mappedValue);
//Serial.println("end");
pinMode(2,INPUT_PULLUP); // internal pull-up resistor
attachInterrupt (digitalPinToInterrupt (BUTTON), changeEffect, CHANGE); // pressed
}
// *** REPLACE FROM HERE ***
void loop() {
EEPROM.get(0,selectedEffect);
if(selectedEffect>17) {
selectedEffect=0;
EEPROM.put(0,0);
}
switch(selectedEffect) {
case 0 : {
// RGBLoop - no parameters
RGBLoop();
break;
}
case 1 : {
// colorWipe0 - Color , speed delay kleur draait van beneden naar boven
colorWipe(0xcc,0x00,0xcc, 50); //paars
colorWipe(0xff,0xff,0x66, 50); //licht geel
colorWipe(0x00,0xff,0xff, 50); //lichtblauw
colorWipe(0xff,0xff,0x66, 50); //licht geel
break;
}
case 2 : {
// meteorRain - Color (red, green, blue), meteor size, trail decay, random trail decay (true/false), speed delay wit achtig van beneden naar boven.
meteorRain(0xff,0xff,0xff,10, 64, true, 30);
break;
}
case 3 : {
// tequillasunrise - Color , speed delay kleur draait van beneden naar boven
colorWipe(0xff,0x00,0x00, 50); //rood
colorWipe(0xff,0xff,0x00, 50); //geel
break;
}
case 4 : {
// NewKITT - Color (red, pink, blue), eye size, speed delay, end pause
NewKITT(0xff, 0x00, 0x00, 8, 10, 50);
NewKITT(0xff, 0x00, 0xff, 8, 10, 50);
NewKITT(0x00, 0x00, 0xff, 8, 10, 50);
break;
}
case 5 : {
// Twinkle - Color (red, geel, blue), count, speed delay, only one twinkle (true/false) willekeurige leds gaan aan voorlopig alleen rood
Twinkle(0xff, 0x00, 0x00, 10, 100, false);
Twinkle(0xff, 0xff, 0x00, 10, 100, false);
Twinkle(0x00, 0xff, 0x00, 10, 100, false);
break;
}
case 6 : {
// TwinkleRandom - twinkle count, speed delay, only one (true/false) twinkle van verschillende kleuren
TwinkleRandom(20, 100, false);
break;
}
case 7 : {
// Sparkle - Color (red, green, blue), speed delay
Sparkle(0xff, 0xff, 0xff, 0);
break;
}
case 8 : {
// colorWipe3 - Color , speed delay kleur draait van beneden naar boven
colorWipe(0xff,0x00,0x00, 50); //rood
colorWipe(0xff,0x80,0x00, 50); //oranje
colorWipe(0xff,0xff,0x00, 50); //geel
colorWipe(0x80,0xff,0x00, 50); //groen
colorWipe(0x00,0xff,0xff, 50); //lichtblauw
colorWipe(0x7f,0x00,0xff, 50); //paars
colorWipe(0xff,0x00,0xff, 50); //roze
colorWipe(0xff,0x00,0x7f, 50); //lila
break;
}
case 9 : {
// Running Lights - Color (red, green, blue), wave dealy
RunningLights(0xff,0x00,0x00, 50); // red
RunningLights(0xff,0xff,0xff, 50); // white
RunningLights(0x00,0x00,0xff, 50); // blue
break;
}
case 10 : {
// colorWipe - Color , speed delay kleur draait van beneden naar boven
colorWipe(0x00,0xff,0x00, 50); //groen
colorWipe(0xff,0xff,0x66, 50); //licht geel
colorWipe(0xff,0x80,0x00, 50); //oranje
colorWipe(0xff,0xff,0x66, 50); //licht geel
break;
}
case 11 : {
// rainbowCycle - speed delay regenboog
rainbowCycle(20);
break;
}
case 12 : {
// virgincocktail - Color , speed delay kleur draait van beneden naar boven
colorWipe(0x33,0x33,0xff, 50); //blauw
colorWipe(0x00,0xff,0x00, 50); //groen
colorWipe(0xff,0xff,0x00, 50); //geel
colorWipe(0xff,0x00,0x00, 50); //rood
break;
}
case 13 : {
// Fire - Cooling rate, Sparking rate, speed delay vuur
Fire(55,120,15);
break;
}
case 14 : {
// lamp wordt groen
Naargroen();
break;
}
case 15 : {
// lamp wordt paars
Naarpaars();
break;
}
case 16 : {
// lamp wordt rood
Naarrood();
break;
}
case 17 : {
// lamp wordt geel
Naargeel();
break;
}
}
}
void changeEffect() {
if ((millis() - lastDebounceTime) > debounceDelay)
{
if (digitalRead (BUTTON) == HIGH) {
selectedEffect++;
EEPROM.put(0, selectedEffect);
asm volatile (" jmp 0");
}
}
}
// *************************
// ** LEDEffect Functions **
// *************************
void RGBLoop(){
for(int j = 0; j < 3; j++ ) {
// Fade IN
for(int k = 0; k < 256; k++) {
switch(j) {
case 0: setAll(k,0,0); break;
case 1: setAll(0,k,0); break;
case 2: setAll(0,0,k); break;
}
showStrip();
delay(3);
}
// Fade OUT
for(int k = 255; k >= 0; k--) {
switch(j) {
case 0: setAll(k,0,0); break;
case 1: setAll(0,k,0); break;
case 2: setAll(0,0,k); break;
}
showStrip();
delay(3);
}
}
}
void colorWipe0(byte red, byte green, byte blue, int SpeedDelay) {
for(uint16_t i=0; i<NUM_LEDS; i++) {
setPixel(i, red, green, blue);
showStrip();
delay(SpeedDelay);
}
}
void Naargroen() {
for (int i=1; i<NUM_LEDS; i++) {
leds[i] = CRGB::Green;
FastLED.show();
delay(10);
}
}
void Naarpaars() {
for (int i=1; i<NUM_LEDS; i++) {
leds[i] = CRGB::Purple;
FastLED.show();
delay(10);
}
}
void Naarrood() {
for (int i=1; i<NUM_LEDS; i++) {
leds[i] = CRGB::Red;
FastLED.show();
delay(10);
}
}
void Naargeel() {
for (int i=1; i<NUM_LEDS; i++) {
leds[i] = CRGB::Yellow;
FastLED.show();
delay(10);
}
}
void colorWipe1(byte red, byte green, byte blue, int SpeedDelay) {
for(uint16_t i=0; i<NUM_LEDS; i++) {
setPixel(i, red, green, blue);
showStrip();
delay(SpeedDelay);
}
}
void NewKITT(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay){
RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay);
}
// used by NewKITT
void CenterToOutside(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
for(int i =((NUM_LEDS-EyeSize)/2); i>=0; i--) {
setAll(0,0,0);
setPixel(i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(i+j, red, green, blue);
}
setPixel(i+EyeSize+1, red/10, green/10, blue/10);
setPixel(NUM_LEDS-i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(NUM_LEDS-i-j, red, green, blue);
}
setPixel(NUM_LEDS-i-EyeSize-1, red/10, green/10, blue/10);
showStrip();
delay(SpeedDelay);
}
delay(ReturnDelay);
}
// used by NewKITT
void OutsideToCenter(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
for(int i = 0; i<=((NUM_LEDS-EyeSize)/2); i++) {
setAll(0,0,0);
setPixel(i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(i+j, red, green, blue);
}
setPixel(i+EyeSize+1, red/10, green/10, blue/10);
setPixel(NUM_LEDS-i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(NUM_LEDS-i-j, red, green, blue);
}
setPixel(NUM_LEDS-i-EyeSize-1, red/10, green/10, blue/10);
showStrip();
delay(SpeedDelay);
}
delay(ReturnDelay);
}
// used by NewKITT
void LeftToRight(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
for(int i = 0; i < NUM_LEDS-EyeSize-2; i++) {
setAll(0,0,0);
setPixel(i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(i+j, red, green, blue);
}
setPixel(i+EyeSize+1, red/10, green/10, blue/10);
showStrip();
delay(SpeedDelay);
}
delay(ReturnDelay);
}
// used by NewKITT
void RightToLeft(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) {
for(int i = NUM_LEDS-EyeSize-2; i > 0; i--) {
setAll(0,0,0);
setPixel(i, red/10, green/10, blue/10);
for(int j = 1; j <= EyeSize; j++) {
setPixel(i+j, red, green, blue);
}
setPixel(i+EyeSize+1, red/10, green/10, blue/10);
showStrip();
delay(SpeedDelay);
}
delay(ReturnDelay);
}
void Twinkle(byte red, byte green, byte blue, int Count, int SpeedDelay, boolean OnlyOne) {
setAll(0,0,0);
for (int i=0; i<Count; i++) {
setPixel(random(NUM_LEDS),red,green,blue);
showStrip();
delay(SpeedDelay);
if(OnlyOne) {
setAll(0,0,0);
}
}
delay(SpeedDelay);
}
void TwinkleRandom(int Count, int SpeedDelay, boolean OnlyOne) {
setAll(0,0,0);
for (int i=0; i<Count; i++) {
setPixel(random(NUM_LEDS),random(0,255),random(0,255),random(0,255));
showStrip();
delay(SpeedDelay);
if(OnlyOne) {
setAll(0,0,0);
}
}
delay(SpeedDelay);
}
void Sparkle(byte red, byte green, byte blue, int SpeedDelay) {
int Pixel = random(NUM_LEDS);
setPixel(Pixel,red,green,blue);
showStrip();
delay(SpeedDelay);
setPixel(Pixel,0,0,0);
}
void colorWipe3(byte red, byte green, byte blue, int SpeedDelay) {
for(uint16_t i=0; i<NUM_LEDS; i++) {
setPixel(i, red, green, blue);
showStrip();
delay(SpeedDelay);
}
}
void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
int Position=0;
for(int i=0; i<NUM_LEDS*2; i++)
{
Position++; // = 0; //Position + Rate;
for(int i=0; i<NUM_LEDS; i++) {
// sine wave, 3 offset waves make a rainbow!
//float level = sin(i+Position) * 127 + 128;
//setPixel(i,level,0,0);
//float level = sin(i+Position) * 127 + 128;
setPixel(i,((sin(i+Position) * 127 + 128)/255)*red,
((sin(i+Position) * 127 + 128)/255)*green,
((sin(i+Position) * 127 + 128)/255)*blue);
}
showStrip();
delay(WaveDelay);
}
}
void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
for(uint16_t i=0; i<NUM_LEDS; i++) {
setPixel(i, red, green, blue);
showStrip();
delay(SpeedDelay);
}
}
void rainbowCycle(int SpeedDelay) {
byte *c;
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< NUM_LEDS; i++) {
c=Wheel(((i * 256 / NUM_LEDS) + j) & 255);
setPixel(i, *c, *(c+1), *(c+2));
}
showStrip();
delay(SpeedDelay);
}
}
// used by rainbowCycle and theaterChaseRainbow
byte * Wheel(byte WheelPos) {
static byte c[3];
if(WheelPos < 85) {
c[0]=WheelPos * 3;
c[1]=255 - WheelPos * 3;
c[2]=0;
} else if(WheelPos < 170) {
WheelPos -= 85;
c[0]=255 - WheelPos * 3;
c[1]=0;
c[2]=WheelPos * 3;
} else {
WheelPos -= 170;
c[0]=0;
c[1]=WheelPos * 3;
c[2]=255 - WheelPos * 3;
}
return c;
}
void virgincocktail(byte red, byte green, byte blue, int SpeedDelay) {
for(uint16_t i=0; i<NUM_LEDS; i++) {
setPixel(i, red, green, blue);
showStrip();
delay(SpeedDelay);
}
}
void Fire(int Cooling, int Sparking, int SpeedDelay) {
static byte heat[NUM_LEDS];
int cooldown;
// Step 1. Cool down every cell a little
for( int i = 0; i < NUM_LEDS; i++) {
cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2);
if(cooldown>heat[i]) {
heat[i]=0;
} else {
heat[i]=heat[i]-cooldown;
}
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for( int k= NUM_LEDS - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
}
// Step 3. Randomly ignite new 'sparks' near the bottom
if( random(255) < Sparking ) {
int y = random(7);
heat[y] = heat[y] + random(160,255);
//heat[y] = random(160,255);
}
// Step 4. Convert heat to LED colors
for( int j = 0; j < NUM_LEDS; j++) {
setPixelHeatColor(j, heat[j] );
}
showStrip();
delay(SpeedDelay);
}
void setPixelHeatColor (int Pixel, byte temperature) {
// Scale 'heat' down from 0-255 to 0-191
byte t192 = round((temperature/255.0)*191);
// calculate ramp up from
byte heatramp = t192 & 0x3F; // 0..63
heatramp <<= 2; // scale up to 0..252
// figure out which third of the spectrum we're in:
if( t192 > 0x80) { // hottest
setPixel(Pixel, 255, 255, heatramp);
} else if( t192 > 0x40 ) { // middle
setPixel(Pixel, 255, heatramp, 0);
} else { // coolest
setPixel(Pixel, heatramp, 0, 0);
}
}
void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {
setAll(0,0,0);
for(int i = 0; i < NUM_LEDS+NUM_LEDS; i++) {
// fade brightness all LEDs one step
for(int j=0; j<NUM_LEDS; j++) {
if( (!meteorRandomDecay) || (random(10)>5) ) {
fadeToBlack(j, meteorTrailDecay );
}
}
// draw meteor
for(int j = 0; j < meteorSize; j++) {
if( ( i-j <NUM_LEDS) && (i-j>=0) ) {
setPixel(i-j, red, green, blue);
}
}
showStrip();
delay(SpeedDelay);
}
}
// used by meteorrain
void fadeToBlack(int ledNo, byte fadeValue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
uint32_t oldColor;
uint8_t r, g, b;
int value;
oldColor = strip.getPixelColor(ledNo);
r = (oldColor & 0x00ff0000UL) >> 16;
g = (oldColor & 0x0000ff00UL) >> 8;
b = (oldColor & 0x000000ffUL);
r=(r<=10)? 0 : (int) r-(r*fadeValue/256);
g=(g<=10)? 0 : (int) g-(g*fadeValue/256);
b=(b<=10)? 0 : (int) b-(b*fadeValue/256);
strip.setPixelColor(ledNo, r,g,b);
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[ledNo].fadeToBlackBy( fadeValue );
#endif
}
// *** REPLACE TO HERE ***
// ***************************************
// ** FastLed/NeoPixel Common Functions **
// ***************************************
// Apply LED color changes
void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
FastLED.show();
#endif
}
// Set a LED color (not yet visible)
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
#endif
}
// Set all LEDs to a given color and apply it (visible)
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < NUM_LEDS; i++ ) {
setPixel(i, red, green, blue);
}
showStrip();
}