Close
0%
0%

ESP-01 CONTROL RGB LED CUBE 4x4x4

ESP-01 ESP8266 can be used as a stand-alone device to control a RGB led cube 4x4x4.

Similar projects worth following
Today, I'd like to share how ESP-01 ESP8266 can be used as a stand-alone device to control a RGB led cube 4x4x4 via SPI protocol & B.A.M process.

Before getting started, please watch the video below:

Project schematic is as follows:

My RGB led cube 4x4x4 includes 64pcs x 10mm RGB LEDs arranged in 04 x LAYERS and each LAYER arranged in 04 x ROWS and 04 x COLUMNS.

  • 04 x LAYERS are controlled by 01pcs x 74HC595 + 04pcs x NPN Transistor 2N3904 + 04pcs x PNP Transistor TIP42C. Outputs of TIP42C are connected to LED ANODES, so the layer needs to be HIGH for an individual LED to turn on. The TIP42C can carry maximum current about 6A.
  • Each LAYER has 16 x RGB LED arranged in 04 x ROWS and 04 x COLUMNS, which are controlled by 06pcs x TPIC6B595N. Outputs of TPIC6B595N are connected to RED-GREEN-BLUE CATHODES PIN through current limiting resistors R100, so each color pin needs to be LOW to turn on. The TPIC6B595N is high power drains, able to sink 150mA per pin and it cannot source current so they should be connected to LED CATHODES. Each RGB LED has 3 colors and each color of 16pcs x RGB LEDs on a layer is controlled by 2pcs x TPIC6B595N. 
    • RED COLOR: 02pcs x TPIC6B595N.
    • GREEN COLOR: 02pcs x TPIC6B595N.
    • BLUE COLOR: 02pcs x TPIC6B595N.
  • ESP-01 ESP8266 is including modes slide switch, reset button, programming header, SPI header and AMS1117 power module for converting from 5V to 3.3V.

The schematic below is shown how the ESP-01S can boot up in program mode and normal operation mode:

  • The button - S1 - is used to reset ESP-01.
  • The slide switch - S2 - allows switching between program and normal operation modes.
  • In normal operation mode, ESP-01S control 4x4x4 RGB led cube by 4 GPIO pins as follows:
    • BLANK PIN connecting to GPIO3 - RX
    • LATCH PIN connecting to GPIO0
    • CLOCK PIN connecting to GPIO2
    • DATA PIN connecting to GPIO1 – TX

NOTES:

  • AMS1117 power module is used for supplying 3.3V to ESP-01.
  • All pull-up resistors are 10Kohm.
  • The 6 PIN FEMALE PROGRAMMING HEADER was soldered on control board. In order for uploading the program from Arduino IDE, I can easily plug FTDI programmer into this header, remove SPI header, switch S2 to GND position and ensure the external power is supplied to ESP-01S.

ESP-01-RGB-LED-CUBE-4x4x4-master.ino

Project code for RGB LED CUBE 4x4x4

ino - 66.05 kB - 06/17/2020 at 07:26

Download

ESP-01S-LED-CUBE-4x4x4_schem.pdf

Schematic in high resolution *PDF format.

Adobe Portable Document Format - 4.60 MB - 06/17/2020 at 02:11

Preview
Download

ESP-01S-LED-CUBE-4x4x4_schem.jpg

Schematic in *JPG format

JPEG Image - 2.93 MB - 06/17/2020 at 02:10

Preview
Download

  • 1 × ESP-01S ESP8266
  • 64 × RGB LED, 10MM, COMMON ANODE
  • 10 × RESISTOR R10K
  • 1 × PUSH BUTTON
  • 1 × SLIDE SWITCH

View all 19 components

  • 1
    SOLDERING LED CUBE MODULE

    We can refer to lots of projects related on how to build a led cube.

    You should make a wooden cube template with 16 holes, diameter 10mm and led tester with battery to check before and after soldering your LED.

    After soldering 04 planes of led cube, I arranged and assembled them into the Prototype PCB 8X12CM.

    I aligned them neatly and symmetrically then soldered them to the Prototype PCB.

    On top of led cube, I soldered 16pcs x RGB LED ANODE PINS in same layer together by copper wires. We have totally 4 layers and they are connected to a 4 pin female header at bottom. Later they will be plugged on control board at this header.

    At bottom of led cube, I soldered LED CATHODES PIN to 6pcs x 8P-female headers in color groups: RED, GREEN & BLUE. As explained in previous step, because each layer has 16 RGB LEDs, so we need to use 2pcs x TPIC6B595N to control each color.

    RGB Led cube 4x4x4 module is DONE!!!

  • 2
    SOLDERING CONTROL MODULE

    I used a remaining prototype PCB 8X12CM to solder the control circuit following the schematic on previous step. Note that in order for led cube module and control module to be matched together perfectly, firstly we have to align & solder all male headers on control module following female headers of led cube.

    Picture below is bottom side of control module. I soldered all de-coupling capacitors and high power transistors TIP42C at bottom.

    Finally I plugged led cube module on top of control module.

    All soldering works were done and we go to next step for programming!!!

  • 3
    PROGRAMMING

    In my program, ESP-01S ESP8266 is used as a stand-alone device to control a RGB led cube 4x4x4. The project code is available at my GitHub.

    CONNECTION
    The ESP-01S ESP8266, 74HC595 & TPIC6B595N are connected together as follows:

    LED CUBE CONTROL
    For layer scanning (anodes), because my led cube module has 4 layers, so we need to shift out 1 byte to 74HC595 with order from 0 ~ 3, as following anode array below.

    byte anode[4]= {B00001000, B00000100, B00000010, B00000001};

     I referenced to original shiftOut() function in file "core_esp8266_wiring_shift.cpp" to create for my own SPI function. You can search this file on your computer or check at this LINK.

    void __attribute__((optimize("O0"))) DIY_SPI(uint8_t DATA)
    {
        uint8_t i;
        uint8_t val;
        for (i = 0; i<8; i++)  
        {
          digitalWrite(DATA_Pin, !!(DATA & (1 << (7 - i))));
          digitalWrite(CLOCK_Pin,HIGH);
          digitalWrite(CLOCK_Pin,LOW);                
        }
    }

    In this project, I used Timer 1 in ESP-01S ESP8266 and a callback routine to implement B.A.M process.

    timer1_isr_init();
    timer1_attachInterrupt(timer1_ISR);
    timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
    timer1_write(60);

    The table below describes the Timer 1 and B.A.M settings as well as their relationship. With this setup, our timer clock runs at 5MHz (80MHz/16=5MHz) or 1/5MHz = 0.2us. When we set timer1_write (60), this means the interrupt will be called every Tick = 60 x 0.2us = 12us and 4 bit B.A.M process need 6 Ticks x 12us = 72us to set the "Least Significant Bit of BAM_Bit" to "ON" or "OFF", which gives a multiplex frequency of about 13.9kHz.

    Main attach interrupt service routine code:

    void ICACHE_RAM_ATTR timer1_ISR(void)
    {   
    digitalWrite(BLANK_Pin, HIGH);
    
    if(BAM_Counter==6)
    BAM_Bit++;
    else
    if(BAM_Counter==18)
    BAM_Bit++;
    else
    if(BAM_Counter==42)
    BAM_Bit++;
    BAM_Counter++;
    switch (BAM_Bit)
    {
    case 0:
           //Blue       
            DIY_SPI(blue[0][level + 1]);
            DIY_SPI(blue[0][level]);
          //Green
            DIY_SPI(green[0][level + 1]);
            DIY_SPI(green[0][level]);      
          //Red
            DIY_SPI(red[0][level + 1]);
            DIY_SPI(red[0][level]);
          break;
        case 1:
          //Blue
            DIY_SPI(blue[1][level + 1]);
            DIY_SPI(blue[1][level]);       
          //Green
            DIY_SPI(green[1][level + 1]);
            DIY_SPI(green[1][level]);
          //Red
            DIY_SPI(red[1][level + 1]);
            DIY_SPI(red[1][level]);
          break;
        case 2:
          //Blue
            DIY_SPI(blue[2][level + 1]);
            DIY_SPI(blue[2][level]);
           //Green
            DIY_SPI(green[2][level + 1]);
            DIY_SPI(green[2][level]);              
          //Red
            DIY_SPI(red[2][level + 1]);
            DIY_SPI(red[2][level]);              
    
          break;
        case 3:
          //Blue
            DIY_SPI(blue[3][level + 1]);
            DIY_SPI(blue[3][level]);
          //Green
            DIY_SPI(green[3][level + 1]);
            DIY_SPI(green[3][level]);
          //Red
            DIY_SPI(red[3][level + 1]);
            DIY_SPI(red[3][level]);
      if(BAM_Counter==90)
        {
          BAM_Counter=0;
          BAM_Bit=0;
        }
      break;
    }
    
    DIY_SPI(anode[anodeLevel]);
    
    digitalWrite(LATCH_Pin, HIGH);
    digitalWrite(LATCH_Pin, LOW);
    digitalWrite(BLANK_Pin, LOW);
    
    anodeLevel++;
    level = anodeLevel<<1;
    if(anodeLevel == 4) anodeLevel=0;
    if(level==8) level=0;
    
    //pinMode(BLANK_Pin, OUTPUT);
    timer1_write(60);
    }

    Below code is used to set a LED based on its coordinates and color.

    void LED(int CZ, int CY, int CX, int CR, int CG, int CB) 
    {
      CR = constrain(CR, 0, (1 << BAM_RESOLUTION) - 1);
      CG = constrain(CG, 0, (1 << BAM_RESOLUTION) - 1);
      CB = constrain(CB, 0, (1 << BAM_RESOLUTION) - 1);
    
      int WhichByte = int(((CZ<<4) + (CY<<2) + CX) >> 3);
      int WhichBit = (((CZ<<4) + (CY<<2) + CX) - (WhichByte << 3));
    
      if (inrange(CZ,CY,CX))
      {
      
        for (byte I = 0; I < BAM_RESOLUTION; I++) 
        {
          //*** RED ***
          bitWrite(red[I][WhichByte], WhichBit, bitRead(CR, I));
    
          //*** GREEN ***
          bitWrite(green[I][WhichByte], WhichBit, bitRead(CG, I));
    
          //*** BLUE ***
          bitWrite(blue[I][WhichByte], WhichBit, bitRead(CB, I));
        }
      }
    }
    

View all 4 instructions

Enjoy this project?

Share

Discussions

Dagdernit Diditagain wrote 06/24/2020 at 19:06 point

Awesome work! You have a steady hand and great patience =)  I have attempted to make a couple LED cubes and they look like they should be named the 3d Eiffel Cube, lol. Getting those LED's perfect like that isnt easy. Thumbs up!

  Are you sure? yes | no

tuenhi.n2012 wrote 06/25/2020 at 01:42 point

Hi Dagdernit Diditagain. Thank you for being interested in my project & encouraging me! :-)

  Are you sure? yes | no

Mike Szczys wrote 06/22/2020 at 19:05 point

Super clean job soldering all of those busses together in such a tight space. Looks great!

  Are you sure? yes | no

tuenhi.n2012 wrote 06/23/2020 at 01:20 point

Thank you, Mike!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates