Mark Daniel Belarmino
Published © CC BY-NC-SA

3D Printed Thomas Helmet of Daftpunk

Yet another Thomas Helmet made from a 3d printer with Attiny85 to control the RGB LED lights.

IntermediateWork in progress2 days43
3D Printed Thomas Helmet of Daftpunk

Things used in this project

Hardware components

ATtiny85
Microchip ATtiny85
×1
WS2812 Addressable LED Strip
Digilent WS2812 Addressable LED Strip
×1
PTS 645 Series Switch
C&K Switches PTS 645 Series Switch
×1
Custom PCB
Custom PCB
×1
Toggle Switch, (On)-Off-(On)
Toggle Switch, (On)-Off-(On)
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Helping Hand Tool, with Magnifying Glass
Helping Hand Tool, with Magnifying Glass
Mini Side Cutter, 120mm Length with 25mm Jaw Capacity
Mini Side Cutter, 120mm Length with 25mm Jaw Capacity
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires

Story

Read more

Custom parts and enclosures

WS2812 LED Strip Visor for Thomas Helmet of Daft Punk

A 3D model to hold the LED strips before attaching inside the Helmet

Schematics

uLed Controller Circuit

Code

Arduino Program for Daft Punk Visor Effects

C/C++
Please choose your specific Arduino Boards. Then, edit the pinout for the addressable LED and input switch.
The input switch will change the state of current effects.
#include <Adafruit_NeoPixel.h>
#include <EEPROM.h>

#define PIN  0
#define BTN  3

uint8_t state = 1;
uint16_t NUM_LEDS = 51;
uint16_t NUM_LEDS_ROW = 17;

#define MAX_EFFECTS 10

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products Uw/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(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
byte colors[3][3] = { {0xff, 0, 0},
  {0xff, 0xff, 0xff},
  {0   , 0   , 0xff}
};

void setup()
{
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  pinMode(BTN, INPUT_PULLUP);
  state = EEPROM.read(100);
  if (state == 0)
    state = 1;

  //  Serial.begin(9600);
}

uint8_t ctr = 0;
void loop()
{
  effects();

}

void effects()
{
  if (digitalRead(BTN) == LOW)
  {
    delay(50);
    while (digitalRead(BTN) == LOW) {
      setAll(0, 0, 0);
    }
    state++;
    if (state > MAX_EFFECTS)
      state = 1;
    EEPROM.write(100, state);
  }

  switch (state)
  {
    case 1:
      Sparkle(0xff, 0xff, 0xff, 1); break; //good
    case 2:
      Fire(55, 120, 15); break; //good
    case 3:
      TwinkleRandom(50, 50, false); break; //good
    case 4:
      RunningLights(0xff, 0xff, 0xff, 10); break; //good
    case 5:
      SnowSparkle(0x10, 0x10, 0x10, 10, random(100, 1000)); break;
    case 6:
      rainbowCycle(20); break; //good
    case 7:
      theaterChase(0xff, 0, 0, 50); break; //good
    case 8:
      CyclonPass(random(0, 200), random(0, 200), random(0, 200), 2, 50); break;
    case 9:
      pink_black(1); break;
    case 10:
      blue_black(1); break;

  }
}

//vu
void vu(uint8_t num, uint16_t d)
{
  uint8_t r = random(0, 255);
  uint8_t g = random(0, 255);
  uint8_t b = random(0, 255);
  d = d / num / 2;
  for (int i = 0; i < num; i++)
  {
    setPixel(i, r, g, b);
    showStrip();
    delay(d);
  }

  for (int i = num; i > -1; i--)
  {
    setPixel(i, 0, 0, 0);
    showStrip();
    delay(d);
  }

}
//on off
void on_off(uint8_t r, uint8_t g, uint8_t b, uint8_t num, uint16_t d)
{
  for (int i = 0; i < num; i++)
  {
    setPixel(i, r, g, b);
    showStrip();
  }
  delay(d);
  for (int i = num; i > -1; i--)
  {
    setPixel(i, 0, 0, 0);
    showStrip();
  }
}
//strand
void strand(uint8_t l, int d)
{
  uint8_t r = random(0, 180);
  uint8_t g = random(0, 180);
  uint8_t b = random(0, 180);
  int a = random(0, NUM_LEDS - l);
  for (int i = 0; i < NUM_LEDS; i++)
  {
    setPixel(i, 0, 0, 0);
    showStrip();
  }
  for (int i = a; i < a + l; i++)
  {
    setPixel(i, r, g, b);
    showStrip();
  }
  delay(d);

}
//2 vu
void dual_vu(uint8_t num, uint16_t d)
{
  int r = random(0, 180);
  int g = random(0, 180);
  int b = random(0, 10);
  int r2 = random(0, 180);
  int g2 = random(0, 10);
  int b2 = random(0, 180);


  int t = d / num;
  int h = num / 2;
  for (int i = 0; i < num / 2; i++)
  {
    for (int j = h; j < h + i; j++)
      setPixel(j, r, g, b );
    for (int j = h; j > h - i; j--)
      setPixel(j, r2, g2, b2);
    showStrip();
    delay(t);
  }
  for (int i = num; i > num / 2; i--)
  {
    setPixel(i, 0, 0, 0);
    setPixel(num - i + 1, 0, 0, 0);
    showStrip();
    delay(t);
  }
}


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 theaterChase(byte red, byte green, byte blue, uint8_t SpeedDelay) {
  for (int q = 0; q < 3; q++) {
    for (int i = 0; i < NUM_LEDS; i = i + 3) {
      setPixel(i + q, red, green, blue);  //turn every third pixel on
    }
    showStrip();

    delay(SpeedDelay);

    for (int i = 0; i < NUM_LEDS; i = i + 3) {
      setPixel(i + q, 0, 0, 0);    //turn every third pixel off
    }
  }
}


void theaterChaseRainbow(uint8_t SpeedDelay) {
  byte *c;

  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 < NUM_LEDS_ROW; i = i + 3) {
        c = Wheel( (i + j) % 255);
        setPixel(i + q, *c, *(c + 1), *(c + 2)); //turn every third pixel on
        setPixel(i + q + NUM_LEDS_ROW - 1, *c, *(c + 1), *(c + 2)); //turn every third pixel on
        setPixel(i + q + NUM_LEDS_ROW * 2 - 3, *c, *(c + 1), *(c + 2)); //turn every third pixel on
      }
      showStrip();

      delay(SpeedDelay);

      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        setPixel(i + q, 0, 0, 0);    //turn every third pixel off
        setPixel(i + q + NUM_LEDS_ROW - 1, 0, 0, 0);   //turn every third pixel off
        setPixel(i + q + NUM_LEDS_ROW * 2 - 3, 0, 0, 0);  //turn every third pixel off
      }
    }
  }
}


void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause)
{
  for (int j = 0; j < StrobeCount; j++) {
    setAll(red, green, blue);
    showStrip();
    delay(FlashDelay);
    setAll(0, 0, 0);
    showStrip();
    delay(FlashDelay);
  }

  delay(EndPause);
}

void SnowSparkle(byte red, byte green, byte blue, int SparkleDelay, int SpeedDelay) {
  setAll(red, green, blue);
  delay(SpeedDelay);
  int Pixel = random(0, NUM_LEDS);
  setPixel(Pixel, 255, 255, 255);
  showStrip();
  delay(SparkleDelay);
  setPixel(Pixel, red, green, blue);
  showStrip();
}

void RunningLights(byte red, byte green, byte blue, int WaveDelay)
{
  int Position = 0;

  for (uint8_t i = 0; i < 10; i++)
  {
    Position++; // = 0; //Position + Rate;
    for (uint8_t i = 0; i < NUM_LEDS_ROW; 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);
      setPixel(i + NUM_LEDS_ROW - 1, ((sin(i + Position) * 127 + 128) / 255)*red,
               ((sin(i + Position) * 127 + 128) / 255)*green,
               ((sin(i + Position) * 127 + 128) / 255)*blue);
      setPixel(i + NUM_LEDS_ROW * 2 - 3, ((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 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 rainbowCycle(uint8_t SpeedDelay) {
  byte *c;
  uint16_t i, j;

  for (j = 0; j < 256; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < NUM_LEDS_ROW; i++) {
      c = Wheel(((i * 256 / NUM_LEDS_ROW) + j) & 255);
      setPixel(i, *c, *(c + 1), *(c + 2));
      setPixel(i + NUM_LEDS_ROW - 1, *c, *(c + 1), *(c + 2));
      setPixel(i + NUM_LEDS_ROW * 2 - 3, *c, *(c + 1), *(c + 2));
    }
    showStrip();
    delay(SpeedDelay);
  }
}

/*

  void rainbowCycle(uint8_t SpeedDelay) {
  byte *c;
  uint16_t i, j;

  for (j = 0; j < 256; 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);
  }
  }

*/

void Fire(int Cooling, int Sparking, uint8_t SpeedDelay) {
  byte heat[NUM_LEDS];
  int cooldown;

  // Step 1.  Cool down every cell a little
  for ( uint8_t 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 CylonBounce(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);

  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 CyclonPass(byte red, byte green, byte blue, int EyeSize, int SpeedDelay ) {

  for (int i = 0; i < NUM_LEDS_ROW + EyeSize; i++)
  {
    for (int j = i; j < i + EyeSize; j++)
    {
      setPixel(j, red, green, blue);
      setPixel(j + NUM_LEDS_ROW - 1, red, green, blue);
      setPixel(j + NUM_LEDS_ROW * 2 - 3, red, green, blue);
      showStrip();
    }
    setPixel(i, 0, 0, 0);
    setPixel(i + NUM_LEDS_ROW - 1, 0, 0, 0);
    setPixel(i + NUM_LEDS_ROW * 2 - 3, 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 thunder()
{
  int len = random(10, 25);
  int Pixel = random(1, NUM_LEDS);
  for (int j = 0; j < random(2, 7); j++)
  {
    for (int i = Pixel; i < (Pixel + len); i++)
    {
      setPixel(i, 255, 255, 255);
      showStrip();
    }
    delay(20);
    for (int i = Pixel; i < (Pixel + len); i++)
    {
      setPixel(i, 0, 0, 0);
      showStrip();
    }
    delay(20);
  }
  for (int i = Pixel; i < NUM_LEDS; i++)
  {
    setPixel(i, 0, 0, 0);
    showStrip();
  }
  delay(random(2000));
}


int ctr_pink = 80;
bool pink_state = 0;
void pink_black(int d)
{
  if (pink_state == 0)
    ctr_pink--;
  else
    ctr_pink++;
  setAll(ctr_pink, 0, ctr_pink);
  delay(d);
  if (ctr_pink >= 180)
    pink_state = 0;
  if (ctr_pink <= 0)
  {
    pink_state = 1;
    delay(1000);
  }
}


int ctr_blue = 80;
bool blue_state = 0;
void blue_black(int d)
{
  if (blue_state == 0)
    ctr_blue--;
  else
    ctr_blue++;
  setAll(0, 0, ctr_blue);
  delay(d);
  if (ctr_blue >= 180)
    blue_state = 0;
  if (ctr_blue <= 0)
  {
    blue_state = 1;
    delay(1000);
  }
}

int ctr_red = 80;
bool red_state = 0;
void red_black(int d)
{
  if (red_state == 0)
    ctr_red--;
  else
    ctr_red++;
  setAll(ctr_red, 0, 0);
  delay(d);
  if (ctr_red >= 180)
    red_state = 0;
  if (ctr_red <= 0)
  {
    red_state = 1;
    delay(1000);
  }
}

int ctr_green = 80;
bool green_state = 0;
void green_black(int d)
{
  if (green_state == 0)
    ctr_green--;
  else
    ctr_green++;
  setAll(0, ctr_green, 0);
  delay(d);
  if (ctr_green >= 180)
    green_state = 0;
  if (ctr_green <= 0)
  {
    green_state = 1;
    delay(1000);
  }
}




// *** REPLACE TO HERE ***

void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  FastLED.show();
#endif
}

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
}

void setAll(byte red, byte green, byte blue) {
  for (int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
    delay(1);
  }
  showStrip();
}

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

Credits

Mark Daniel Belarmino

Mark Daniel Belarmino

0 projects • 0 followers
R&D Engineer
Thanks to DimitriK42.

Comments

Add projectSign up / Login