Transformers: Modding a LED-Lamp

Once upon a time there was a gift: A white glowing lamp shaped as an Autobotsign. My girlfriend gave me this lamp at the end of 2015. I really liked it, but it was a kind of boring. It just glowed white and I was not able, to mount the lamp directly onto a wall.

So i decided to mod this lamp:
It should glow in all colors and should be mountable onto walls, too.

The idea was simple:
The originale LEDS should be replaced with new RGB-LEDs, additionally the powerjack should be replaced to the bottom, so I'm able to mount it onto a wall.
After loosening the screws, drilling and using the Dremel, the case was empty, a new hole for the new jack was drilled and all mountingpoints on the inside were removed.

A list of all needed things:


UPDATE: Meanwhile i build two lamps:
A few weeks ago, my godson visited me: Jasper is nearly three years old and really, really liked the lamp, which is placed in our livingroom. He just pointed to the lamp and yelled "Have too!". So i promised him, that I will build him one. This is why this entry will sometimes uses the terms "first lamp" respectively "second lamp". I hope, this i okay for you.

On it's back, the lamp is screwed with six screws: When you loose them, you are able to just drag the backplate from the front. The originale LEDs were hold by some kind of plasticpins, which i removed by using a Dremel. I placed the new RGB-LEDs directly onto this spots. The new LEDs get connected in a row with it's 3 connectors:

  • 5V
  • Data
  • GND

The first lamp whith breakoutboards on each LED. I just used some hotglue to mount the LEDs in the second lamp. Works too. Close LED-shot.

You should take the needed 5V directly from the powerjack and not from the 5V-Pin at the Arduino. These 8 LEDs needs some "juice" and I'm not sure, if they are not able to burn the microcontroller. To connect the datapin you can choose whatever you want. I took D6. To use the button, you should build a Pull-Up-Resistor (~4,7 kOhm) on one of the inputs (D4 maybe?).
It could look like this:

Schematic

I place the switch and button on the side of the case. Just a hint: If you don't want to file yourself nearly to death, to get a square shaped hole into the plastic: you can also just add a powerswitch directly into the cable. I did this on the first lamp, but I'm not sure, where Jasper will place the lamp and if it's possible to reach the cable easily.

The new jack is on the case's bottom. I replaced the old jack, placed on the back, with a identically jack from the bottom, to make it possible using the lamp on a desk or onto a wall. You should not use both jacks at the same time. This could produce some "funny" effects. REALLY! YOU. SHOULD. NOT. DO. THIS!!!!1

While I was writing the code, i found out, that i like a lot of colors and maybe it would look awesome, if the colors would fade slowly from one to another. I really do!
For that I'm using a Library called FastLED. Inside there is a function called "rainbow", which is nearly the functionality i was looking for.
So the lamp works in four different modes:

  1. Rainbow (fades the colors slowly)
  2. Glowing white
  3. Glowing blue
  4. FIRE!!!! (Ok. It was a test, but it looks a kind of interesting. Maybe while listing to techno?!)

Ah. The code. Right. Here it is:

/*
Hacky hacky code for Transformer-RGB Lamp
with some colors and animations:
Colors:
 - White
 - Blue
Animations:
 - Rainbow
 - Fire
*/

#include "FastLED.h"
#define NUM_LEDS 8 //Count of LEDs
#define CHIPSET WS2812B
#define FRAMES_PER_SECOND  120

#define DATA_PIN 6 //Data pin
#define BTN_PIN 4 // Button to change color

int colors[] = {10000, CRGB::White, CRGB::MediumBlue, 10001}; //Color patterns
int brightness[] = {0, 150, 250}; //Brightness patterns

//Used for fire-animation
#define COOLING  50
#define SPARKING 120
#define ANTIBEAT 100

CRGB leds[NUM_LEDS];
uint8_t gHue = 0;
bool gReverseDirection = false;

int current = 0; // Current pattern to start with
int state = 0; //Startvalue of button
int antibeatCnt = 0;

void setup() {
  delay(1000); // sanity check delay - allows reprogramming if accidently blowing power w/leds
  pinMode(BTN_PIN, INPUT); //set buttonmode
  FastLED.addLeds<CHIPSET,DATA_PIN,RGB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  setColor();
}

void loop() {
  animate();
  if(button()) {
    handleCurrent();
    setColor();
  } 
}

void handleCurrent() {
  current++;
    if(current > sizeof(colors) / sizeof(int)-1){
      current = 0;
    }
}

void setColor() {
  int color = colors[current];
  FastLED.setBrightness(brightness[current]);
  for(int led = 0; led < NUM_LEDS; led = led + 1) {
      leds[led] = colors[current];
  }
  FastLED.show();
}

boolean button() {
    if(antibeatCnt > 0) {
      delay(1);
      antibeatCnt--;
      return false;
    }
    if(digitalRead(BTN_PIN) == state) return false;
    state = digitalRead(BTN_PIN);
    if(state == LOW) {
      antibeatCnt = ANTIBEAT;
      return true;
    }
    return false;
}


boolean animate() {
  if(millis() % 2) {
    return false;
  }
  int color = colors[current];
  if(color > 9999 && color < 10003) {
    FastLED.delay(1000/FRAMES_PER_SECOND); 
    switch(color) {
      case 10000:
        EVERY_N_MILLISECONDS( 130 ) { gHue++; }
        FastLED.setBrightness(250);
        fill_rainbow( leds, NUM_LEDS, gHue, 7);
      break;
      
      case 10001:
        EVERY_N_MILLISECONDS( 20 ) { gHue++; }
        random16_add_entropy( random());
        FastLED.setBrightness(110);
        fire2012();
      break;
      
      default: 
      break;
    }
    FastLED.show(); 
    return true;
  }
  return false;
}

void fire2012()
{
  static byte heat[NUM_LEDS];

  for( int i = 0; i < NUM_LEDS; i++) {
    heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
  }

  for( int k= NUM_LEDS - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
  }

  if( random8() < SPARKING ) {
    int y = random8(7);
    heat[y] = qadd8( heat[y], random8(160,255) );
  }

  for( int j = 0; j < NUM_LEDS; j++) {
    CRGB color = HeatColor( heat[j]);
    // guck mal mami, ohne temp-variable! (mrks sagt das)
    color.g = color.r ^ color.g;
    color.r = color.r ^ color.g;
    color.g = color.r ^ color.g;
    int pixelnumber;
    if( gReverseDirection ) {
      pixelnumber = (NUM_LEDS-1) - j;
    } else {
      pixelnumber = j;
    }
    leds[pixelnumber] = color;
  }
}

The insided of the first lamp. The board of the second lamp is glued onto the side. Green. White. Kind of blue with purple. Pink.

The following video shows how i build the second lamp (in german only):