News

moodlite - Coming soon


HEXAGON TILES - RELEASE

hauschka · 365

hauschka

  • Newbie
  • *
    • Posts: 8
    • Likes: +0/-0
    • View Profile
on: April 06, 2019, 01:41:35 PM
Dear community,

I am releasing my design files for a hexagonal version of the Moodlite.









Each tile is composed of a bottom part that houses all the electronics and a top part that snaps on top to diffuse the light.
The degree of diffusion can be controlled by varying the lenght of the top part.

The tiles are interconnected with a servo cable + connnector.


In this build, I used ws2812b ledstrips.  They come in different densities (30-144 LEDs per meter!)

Since I wanted to achieve a strong glow (that can always be dimmed), I went with the highest density ;)

Any other LED-density can be chosen, as the height of the diffusor part can be adjusted to be closer to the LEDs.


In this build, I used a Particle Photon running AgileNebulas's code: https://moodlite.co.uk/index.php?topic=34
However, the controller can be interchanged with a NodeMCU & the Classic Moodlite software.

I have adapted the code to include some more effects. The code is available at the end of the post.

You can add your own color combinations  by adding a new block of colors as seen in:

Code: [Select]

void SetupPurplish()



The following components are needed:
-----------------------------------

WS2812b (I chose 4m @144 LEDs)
5V power supply (I chose 10 A)
Servo cables
Jumper wires + Breadboard
Particle photon dev board




Instructions:
--------------

The setup is heavily based on AgileNebulas' setup that I have previosly linked.

The main difference is the routing of the cables.

The servo cables are spliced to power the 5 tiles in parallel, as seen here:





The incoming power (yellow and brown) goes towards the LED strip.

The other end of the cable is then combined with the initial bit of the servo cable.

For this, I have exposed the incomming wire and resoldered the other end according to the image above.
Due to lack of shrinking wire, I have enclosed the solder with a drop of hot glue.

The data line runs from the tile's inlay straight to the LED strip. (image below)
At the end of the strip, the data line (red) is forwarded to the next tile.




This way, each tile receives power from the plug and data from the previous LED strip.

The top part is then snapped into 1 side and slowly worked around the whole bottom part:




Possible problems:
------------------

Diffusor may crack during mounting!


Soldered joint between cables might not be safe at certain Amps.


The diffusor is made of a single layer of white filament. You may run into errors when slicing it!
Use "detect thin features".

The design is rather new and will be adapted to house excatly half an LED strip.

When upscaling this setup, you will run into power delivery problems, especially when you choose 144 LEDs/meter.
The next version may feature a voltage regulator before each LED strip and a stronger power line interconnecting each tile (including stronger cables).

On/off doesn't work yet. For now, you can turn only turn it off by setting the brightness to 0. I am working on fixing this, it may just need a simple FastLed.clear() somewhere.




Code:

Code: [Select]


// This #include statement was automatically added by the Particle IDE.
#include <FastLED.h>
FASTLED_USING_NAMESPACE;

#define LED_PIN 6

#define NUM_LEDS 449

#define BRIGHTNESS 255
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define UPDATES_PER_SECOND 30

CRGB crgbLeds[NUM_LEDS];
TBlendType currentBlending;
CRGBPalette16 crgbCurrentPalette;



int iBrightness = 250;
int iSpeed = 10;

String sProgram = "Linear Rainbow";
bool bPower = true;

String sProgramNames = "Linear Rainbow,NB Rainbow Stripe,Linear Rainbow Stripe,Random,Purple and Green,Cloud,Party";

LEDSystemTheme ledTheme;



void setup() {
   
    Particle.variable("Brightness", iBrightness);
    Particle.variable("Speed", iSpeed);
    Particle.variable("Program", sProgram);
    Particle.variable("Programs", sProgramNames);
   
    Particle.function("AdjustBrightness", AdjustBrightness);
    Particle.function("AdjustSpeed", AdjustSpeed);
    Particle.function("ChangeProgram", ChangeProgram);
    Particle.function("Power", Power);
   
    delay(3000);
   
    FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(crgbLeds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness( BRIGHTNESS );
   
    crgbCurrentPalette = PartyColors_p;
    currentBlending = LINEARBLEND;
   
    ledTheme.setColor(LED_SIGNAL_CLOUD_CONNECTED, 0x00000000); // Set LED_SIGNAL_NETWORK_ON to no color
ledTheme.apply(); // Apply theme settings
}

void loop() {

    static uint8_t ui8StartIndex = 0;
    ui8StartIndex = ui8StartIndex + 1;
    fillLedsFromPaletteColors(ui8StartIndex);
    if (bPower) {
        FastLED.show();
        FastLED.delay(1000 / iSpeed);
    }
   
 
   
}

void fillLedsFromPaletteColors(uint8_t ui8ColorIndex) {
   
    uint8_t ui8Brightness = 255;
 
    for (int i = 0; i < NUM_LEDS; i++)
    {
        crgbLeds[i] = ColorFromPalette(crgbCurrentPalette, ui8ColorIndex, ui8Brightness, currentBlending);
        ui8ColorIndex += 3;
    }
}



void setupTotallyRandomPalette()
{
  for ( int i = 0; i < 16; i++) {
    crgbCurrentPalette[i] = CHSV( random8(), 255, random8());
  }
}

// This function sets up a palette of crgbPurple and green stripes.
void SetupPurpleAndGreenPalette()
{
  CRGB crgbPurple = CHSV( HUE_PURPLE, 255, 255);
  CRGB crgbGreen  = CHSV( HUE_GREEN, 255, 255);
  CRGB crgbBlack  = CRGB::Black;

  crgbCurrentPalette = CRGBPalette16(
                     crgbGreen,  crgbGreen,  crgbBlack,  crgbBlack,
                     crgbPurple, crgbPurple , crgbBlack,  crgbBlack,
                     crgbGreen,  crgbGreen,  crgbBlack,  crgbBlack,
                     crgbPurple, crgbPurple, crgbBlack,  crgbBlack );
}

void SetupPurplish()
{
  CRGB crgb1 = CHSV(255, 255, 255);
  CRGB crgb2 = CHSV(250, 255, 255);
  CRGB crgb3 = CHSV(245, 255, 255);
  CRGB crgb4 = CHSV(240, 255, 255);
  CRGB crgb5 = CHSV(235, 255, 255);
  CRGB crgb6 = CHSV(230, 255, 255);
  CRGB crgb7 = CHSV(225, 255, 255);
  CRGB crgb8 = CHSV(220, 255, 255);
  CRGB crgb9 = CHSV(215, 255, 255);
  CRGB crgb10 = CHSV(210, 255, 255);
  CRGB crgb11 = CHSV(205, 255, 255);
  CRGB crgb12 = CHSV(200, 255, 255);
  CRGB crgb13 = CHSV(195, 255, 255);
  CRGB crgb14 = CHSV(190, 255, 255);
  CRGB crgb15 = CHSV(185, 255, 255);
  CRGB crgb16 = CHSV(180, 255, 255);
 

  crgbCurrentPalette = CRGBPalette16(
                     crgb1,  crgb2,  crgb3,  crgb4,
                     crgb5, crgb6 , crgb7,  crgb8,
                     crgb9,  crgb10,  crgb11,  crgb12,
                     crgb13, crgb14, crgb15,  crgb16 );
}

void SetupGreenish()
{
  CRGB crgb1 = CHSV(120, 255, 255);
  CRGB crgb2 = CHSV(117, 255, 255);
  CRGB crgb3 = CHSV(114, 255, 255);
  CRGB crgb4 = CHSV(111, 255, 255);
  CRGB crgb5 = CHSV(108, 255, 255);
  CRGB crgb6 = CHSV(105, 255, 255);
  CRGB crgb7 = CHSV(103, 255, 255);
  CRGB crgb8 = CHSV(100, 255, 255);
  CRGB crgb9 = CHSV(97, 255, 255);
  CRGB crgb10 = CHSV(94, 255, 255);
  CRGB crgb11 = CHSV(91, 255, 255);
  CRGB crgb12 = CHSV(88, 255, 255);
  CRGB crgb13 = CHSV(85, 255, 255);
  CRGB crgb14 = CHSV(82, 255, 255);
  CRGB crgb15 = CHSV(79, 255, 255);
  CRGB crgb16 = CHSV(76, 255, 255);
 

  crgbCurrentPalette = CRGBPalette16(
                     crgb1,  crgb2,  crgb3,  crgb4,
                     crgb5, crgb6 , crgb7,  crgb8,
                     crgb9,  crgb10,  crgb11,  crgb12,
                     crgb13, crgb14, crgb15,  crgb16 );
}



int AdjustBrightness(String sBrightness) {
   
    int newBrightness = sBrightness.toInt();
    if (newBrightness >= 0  && newBrightness <= 255)
    {
        iBrightness = newBrightness;
        FastLED.setBrightness(iBrightness);
        return 0;
    }
    return -1;
}

int AdjustSpeed(String sSpeed) {
   
    iSpeed = sSpeed.toInt();
    //iSpeed = digitalRead(V5);
    return 0;
}


int ChangeProgram(String sNewProgram) {

    if (sNewProgram.equalsIgnoreCase("Linear Rainbow")) {
        sProgram = sNewProgram;
        crgbCurrentPalette = RainbowColors_p;
        currentBlending = LINEARBLEND;
        return 1;
    }
    else if (sNewProgram.equalsIgnoreCase("NB Rainbow Stripe")) {
        sProgram = sNewProgram;
        crgbCurrentPalette = RainbowStripeColors_p;
        currentBlending = NOBLEND;
        return 2;
    }
    else if (sNewProgram.equalsIgnoreCase("Linear Rainbow Stripe")) {
        sProgram = sNewProgram;
        crgbCurrentPalette = RainbowStripeColors_p;
        currentBlending = LINEARBLEND;
        return 3;
    }
    else if (sNewProgram.equalsIgnoreCase("Random")) {
        sProgram = sNewProgram;
        setupTotallyRandomPalette();
        currentBlending = LINEARBLEND;
        return 4;
    }
    else if (sNewProgram.equalsIgnoreCase("Purple and Green")) {
        sProgram = sNewProgram;
        SetupPurpleAndGreenPalette();
        currentBlending = LINEARBLEND;
        return 5;
    }
    else if (sNewProgram.equalsIgnoreCase("Cloud")) {
        sProgram = sNewProgram;
        crgbCurrentPalette = CloudColors_p;
        currentBlending = LINEARBLEND;
        return 6;
    }
    else if (sNewProgram.equalsIgnoreCase("Party")) {
        sProgram = sNewProgram;
        crgbCurrentPalette = PartyColors_p;
        currentBlending = LINEARBLEND;
        return 7;
    }
        else if (sNewProgram.equalsIgnoreCase("Lava")) {
        sProgram = sNewProgram;
        crgbCurrentPalette = LavaColors_p;
        currentBlending = LINEARBLEND;
        return 8;
    }
    else if (sNewProgram.equalsIgnoreCase("Ocean")) {
        sProgram = sNewProgram;
        crgbCurrentPalette = OceanColors_p;
        currentBlending = LINEARBLEND;
        return 9;
    }
    else if (sNewProgram.equalsIgnoreCase("Forest")) {
        sProgram = sNewProgram;
        crgbCurrentPalette = ForestColors_p;
        currentBlending = LINEARBLEND;
        return 10;
    }
    else if (sNewProgram.equalsIgnoreCase("Heat")) {
        sProgram = sNewProgram;
        crgbCurrentPalette = HeatColors_p;
        currentBlending = LINEARBLEND;
        return 11;
    }
    else if (sNewProgram.equalsIgnoreCase("Purplish")) {
        sProgram = sNewProgram;
        SetupPurplish();
        currentBlending = LINEARBLEND;
        return 12;
    }
    else if (sNewProgram.equalsIgnoreCase("Greenish")) {
        sProgram = sNewProgram;
        SetupGreenish();
        currentBlending = NOBLEND;
        return 12;
    }
    else {
        sProgram = "Linear Rainbow";
        crgbCurrentPalette = RainbowColors_p;
        currentBlending = LINEARBLEND;
        return 0;
    }
    return -1;
}

int Power(String sPower)
{
    if (sPower.equalsIgnoreCase("On")) {
        bPower = true;
        return 1;
    } else if (sPower.equalsIgnoreCase("Off")) {
        bPower = false;
        return 0;
    }
    return -1;
}




MrLaFave

  • Newbie
  • *
    • Posts: 13
    • Likes: +0/-0
    • View Profile
Reply #1 on: April 11, 2019, 12:31:34 AM
This is great. I was working on a hexagon tile, but since you were able to finish a design already, I don't need to keep hacking away at it lol!
Though I don't see any stl or f3d files?



hauschka

  • Newbie
  • *
    • Posts: 8
    • Likes: +0/-0
    • View Profile
Reply #2 on: April 11, 2019, 07:01:35 AM
I have attached them to the first post. You can find them at the bottom.



MrLaFave

  • Newbie
  • *
    • Posts: 13
    • Likes: +0/-0
    • View Profile
Reply #3 on: April 11, 2019, 07:06:34 PM
Ah, I missed them, I looked all over lol.
Thanks



 


SMF spam blocked by CleanTalk