Jose Cabrera
Published © GPL3+

Icosahedron Sphere NeoPixel Device (No Plutonium Used)

So, every time a make a project, it ends up looking like a plutonium based device. And this is one of them.

IntermediateShowcase (no instructions)1,632
Icosahedron Sphere NeoPixel Device (No Plutonium Used)

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
×1
SparkFun ProtoShield Kit
SparkFun ProtoShield Kit
×1
LED Strip, NeoPixel Digital RGB
LED Strip, NeoPixel Digital RGB
×1
power supply 5V 60A
×1
copper tape 2" wide
×1

Software apps and online services

Arduino IDE
Arduino IDE
Windows 10
Microsoft Windows 10

Hand tools and fabrication machines

Laser cutter (generic)
Laser cutter (generic)
3D Printer (generic)
3D Printer (generic)
Scissors, Free Fall
Scissors, Free Fall
Wire Stripper & Cutter, 26-14 AWG Solid & Stranded Wires
Wire Stripper & Cutter, 26-14 AWG Solid & Stranded Wires

Story

Read more

Custom parts and enclosures

Parts Listing

Yep, parts.

Schematics

Basic Measurements

General measurements for device.

Neopixel Signal Line Routing

All Neopixels are on a single logical wire. This diagram shows the routing of the signal along the edges of the Icosahedron.

Neopixel Signal Line Through Vertex

The signal line for the Neopixels covers all edges and is then routed through the vertex strips.

Vertex Construction

The Icosahedron vertices are wiring hubs for the Neopixels. They consist of two PCBs and insulators. These vertices also support the inner structures of the project.

Vertices Wiring

The vertices are each matched to a specific wiring setup. This image displays how each vertex is is wired for signal routing.

LED Numbering

The Neopixels are identified by address per edge and vertex.

Code

Example Code Demo

Arduino
This is for an Arduino Mega 2560.
#include <FastLED.h>

// How many leds in your strip?
#define NUM_LEDS 708
#define NUM_EDGE 30
#define EDGE_SIZE 18
#define NUM_VERTEX 12
#define VERTEX_SIZE 14 // 7 LEDs out to in then 7 LEDs in to out
# define VERTEX_OFFSET 540 // intial vertex LED

// Segment LED Sequence are calculated as:
// = Segment number * 18
// Vertex LED Sequence are calulated as:
// = 540 + (Vertex number * 14)

// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  
#define DATA_PIN 6
// #define CLOCK_PIN 13

// Define the array of leds
CRGB leds[NUM_LEDS];
// #define BRIGHTNESS 96

//int AdjacentVertex[12][5];
int AdjacentVertex[][5] = {{1,2,3,4,5}, {0,2,5,6,7}, {0,1,3,7,8}, {0,2,4,8,9},
                          {0,3,5,9,10}, {0,1,4,6,10}, {1,5,7,10,11}, {1,2,6,8,11},
                          {2,3,7,9,11}, {3,4,8,10,11}, {4,5,6,9,11}, {6,7,8,9,10}};

//int VertexStart[12];
int VertexStart[] = {694,666,652,638,624,680,596,582,568,554,610,540};

//int EdgeEnds[x][y][0]; 0=no linkage; -1=countdown; 1=countup 
//int EdgeEnds[x][y][1]; intitial LED number for travel from x to y

int EdgeEnds[12][12][2];

void setup() 
{ 
  	  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
//      FastLED.setBrightness(BRIGHTNESS);    
  preparestructures();  
}

void preparestructures()
{
  int x,y;

// Zero out EdgeEnds Matrix

  for(x=0;x<NUM_VERTEX;++x)
    for(y=0;y<NUM_VERTEX;++y)
      {
         EdgeEnds[x][y][0]=0;
         EdgeEnds[x][y][1]=0;
      }


  EdgeEnds[6][7][0] = 1;
  EdgeEnds[6][7][1] = 0;
  EdgeEnds[7][6][0] = -1;
  EdgeEnds[7][6][1] = 17;

  EdgeEnds[7][1][0] = 1;
  EdgeEnds[7][1][1] = 18;
  EdgeEnds[1][7][0] = -1;
  EdgeEnds[1][7][1] = 35;

  EdgeEnds[1][2][0] = 1;
  EdgeEnds[1][2][1] = 36;
  EdgeEnds[2][1][0] = -1;
  EdgeEnds[2][1][1] = 53;

  EdgeEnds[2][8][0] = 1;
  EdgeEnds[2][8][1] = 54;
  EdgeEnds[8][2][0] = -1;
  EdgeEnds[8][2][1] = 71;

  EdgeEnds[8][9][0] = 1;
  EdgeEnds[8][9][1] = 72;
  EdgeEnds[9][8][0] = -1;
  EdgeEnds[9][8][1] = 89;

  EdgeEnds[9][3][0] = 1;
  EdgeEnds[9][3][1] = 90;
  EdgeEnds[3][9][0] = -1;
  EdgeEnds[3][9][1] = 107;

  EdgeEnds[3][4][0] = 1;
  EdgeEnds[3][4][1] = 108;
  EdgeEnds[4][3][0] = -1;
  EdgeEnds[4][3][1] = 125;

  EdgeEnds[4][10][0] = 1;
  EdgeEnds[4][10][1] = 126;
  EdgeEnds[10][4][0] = -1;
  EdgeEnds[10][4][1] = 143;

  EdgeEnds[10][6][0] = 1;
  EdgeEnds[10][6][1] = 144;
  EdgeEnds[6][10][0] = -1;
  EdgeEnds[6][10][1] = 161;

  EdgeEnds[6][5][0] = 1;
  EdgeEnds[6][5][1] = 162;
  EdgeEnds[5][6][0] = -1;
  EdgeEnds[5][6][1] = 179;

  EdgeEnds[5][1][0] = 1;
  EdgeEnds[5][1][1] = 180;
  EdgeEnds[1][5][0] = -1;
  EdgeEnds[1][5][1] = 197;

  EdgeEnds[7][8][0] = 1;
  EdgeEnds[7][8][1] = 198;
  EdgeEnds[8][7][0] = -1;
  EdgeEnds[8][7][1] = 215;

  EdgeEnds[2][3][0] = 1;
  EdgeEnds[2][3][1] = 216;
  EdgeEnds[3][2][0] = -1;
  EdgeEnds[3][2][1] = 233;

  EdgeEnds[9][10][0] = 1;
  EdgeEnds[9][10][1] = 234;
  EdgeEnds[10][9][0] = -1;
  EdgeEnds[10][9][1] = 251;

  EdgeEnds[4][5][0] = 1;
  EdgeEnds[4][5][1] = 252;
  EdgeEnds[5][4][0] = -1;
  EdgeEnds[5][4][1] = 269;

  EdgeEnds[0][5][0] = 1;
  EdgeEnds[0][5][1] = 270;
  EdgeEnds[5][0][0] = -1;
  EdgeEnds[5][0][1] = 287;

  EdgeEnds[5][10][0] = 1;
  EdgeEnds[5][10][1] = 288;
  EdgeEnds[10][5][0] = -1;
  EdgeEnds[10][5][1] = 305;

  EdgeEnds[10][11][0] = 1;
  EdgeEnds[10][11][1] = 306;
  EdgeEnds[11][10][0] = -1;
  EdgeEnds[11][10][1] = 323;
  
  EdgeEnds[11][9][0] = 1;
  EdgeEnds[11][9][1] = 324;
  EdgeEnds[9][11][0] = -1;
  EdgeEnds[9][11][1] = 341;

  EdgeEnds[9][4][0] = 1;
  EdgeEnds[9][4][1] = 342;
  EdgeEnds[4][9][0] = -1;
  EdgeEnds[4][9][1] = 359;

  EdgeEnds[4][0][0] = 1;
  EdgeEnds[4][0][1] = 360;
  EdgeEnds[0][4][0] = -1;
  EdgeEnds[0][4][1] = 377;

  EdgeEnds[0][3][0] = 1;
  EdgeEnds[0][3][1] = 378;
  EdgeEnds[3][0][0] = -1;
  EdgeEnds[3][0][1] = 395;

  EdgeEnds[3][8][0] = 1;
  EdgeEnds[3][8][1] = 396;
  EdgeEnds[8][3][0] = -1;
  EdgeEnds[8][3][1] = 413;

  EdgeEnds[8][11][0] = 1;
  EdgeEnds[8][11][1] = 414;
  EdgeEnds[11][8][0] = -1;
  EdgeEnds[11][8][1] = 431;

  EdgeEnds[11][7][0] = 1;
  EdgeEnds[11][7][1] = 432;
  EdgeEnds[7][11][0] = -1;
  EdgeEnds[7][11][1] = 449;

  EdgeEnds[7][2][0] = 1;
  EdgeEnds[7][2][1] = 450;
  EdgeEnds[2][7][0] = -1;
  EdgeEnds[2][7][1] = 467;

  EdgeEnds[2][0][0] = 1;
  EdgeEnds[2][0][1] = 468;
  EdgeEnds[0][2][0] = -1;
  EdgeEnds[0][2][1] = 485;

  EdgeEnds[0][1][0] = 1;
  EdgeEnds[0][1][1] = 486;
  EdgeEnds[1][0][0] = -1;
  EdgeEnds[1][0][1] = 503;

  EdgeEnds[1][6][0] = 1;
  EdgeEnds[1][6][1] = 504;
  EdgeEnds[6][1][0] = -1;
  EdgeEnds[6][1][1] = 521;

  EdgeEnds[6][11][0] = 1;
  EdgeEnds[6][11][1] = 522;
  EdgeEnds[11][6][0] = -1;
  EdgeEnds[11][6][1] = 539;
   
}
void loop() 
{ 
  int x, y;
  int segment_offset;

  blackout();

  for(x = 10; x > 0; --x)
    {
      vertextimecycle(1,x*10,128,0,0);
      fullshell(0,0,(10-x)*20);   
    }

  fullshell(200,200,200);
  delay(200);

  for(y=0;y<10;++y)
    {
      for(x=0;x<10;++x)
      {
        fullshell(0,x*10,0);
        delay(25);
      }
      for(x=10;x>0;--x)
      {
        fullshell(0,x*10,0);
        delay(25);
      }      
    }

  for(x=0;x<10;++x)
    randomstuff();
      
// edgerollcall();
// vertexrollcall();
// edgeinsingle(); 
// edgeinall();
// vertexcycle(1);
// vertexcycle(-1);

}

void randomstuff()
{
   int x;
   for(x=0;x<NUM_EDGE;++x)
     {       
       selectedge(x, int(random(16)*14), int(random(16)*14), int(random(16)*14));
     }

   for(x=0;x<NUM_VERTEX;++x)
     {
       selectvertex(x, int(random(16)*14), int(random(16)*14), int(random(16)*14));  
     }
}

void selectedge(int edge, int red, int green, int blue)
{
  int y, segment_offset;

  segment_offset = edge * 18;    
  for (y=0;y<EDGE_SIZE;++y)
  {
    leds[segment_offset + y] = CRGB(red,green,blue);
  }
  FastLED.show();
  delay(10);  
}

void selectvertex(int vertex, int red, int green, int blue)
{
  int y, vertex_start;  

  vertex_start = (vertex * VERTEX_SIZE) + VERTEX_OFFSET;
  for(y=0; y < VERTEX_SIZE; ++y)
    {
      leds[vertex_start + y] = CRGB(red,green,blue);
    }
  FastLED.show(); 
  delay(10);
}

void blackout()
{
  for(int x=0;x<NUM_LEDS;++x)
    leds[x] = CRGB::Black;
}

void edgerollcall(int red,int green, int blue)
{
  int x,y;
  int segment_offset;
  
  for(x=0;x<NUM_EDGE;++x)
    {
      segment_offset = x * 18;    
      for (y=0;y<EDGE_SIZE;++y)
      {
        leds[segment_offset + y] = CRGB(red,green,blue);
      }
      FastLED.show();
      delay(500);
      for (y=0;y<EDGE_SIZE;++y)
      {
        leds[segment_offset + y] = CRGB::Black;
      }
      FastLED.show();
      delay(500);
    }
  
}

void vertexrollcall(int red,int green, int blue)
{
  int x,y;
  int vertex_start = VERTEX_OFFSET;
    for(x=0; x < NUM_VERTEX; ++x)
      {
        for(y=0; y < VERTEX_SIZE; ++y)
          {
            leds[vertex_start + (x*VERTEX_SIZE) + y] = CRGB(red,green,blue);
          }
        FastLED.show();
        delay(100);
        for(y=0; y < VERTEX_SIZE; ++y)
          {
            leds[vertex_start + (x*VERTEX_SIZE) + y] = CRGB::Black;
          }
        FastLED.show();  
      }
}


void edgeinsingle(int red,int green, int blue)
{
  int x,y;
  int segment_offset;
  
  for(x=0;x<NUM_EDGE;++x)
    {
      segment_offset = x * 18;    
      for (y=0;y<EDGE_SIZE/2;++y)
      {
        leds[segment_offset + y] = CRGB(red,green,blue);
        leds[segment_offset + EDGE_SIZE - y] = CRGB(red,green,blue);        
        FastLED.show();
        delay(100);
        leds[segment_offset + y] = CRGB::Black;
        leds[segment_offset + EDGE_SIZE - y] = CRGB::Black;        
        FastLED.show();        
      }
    }
  
}

void edgeinall(int red,int green, int blue)
{
  int x,y;
  int segment_offset;

  for (y=0;y<EDGE_SIZE;++y)
    { 
      for(x=0;x<NUM_EDGE;++x)
      {
        segment_offset = x * 18;            
        leds[segment_offset + y] = CRGB(red,green,blue);
        leds[segment_offset + EDGE_SIZE - y] = CRGB(red,green,blue);        
      }  
      FastLED.show();
      delay(100);
      
      for(x=0;x<NUM_EDGE;++x)        
      {
        segment_offset = x * 18;            
        leds[segment_offset + y] = CRGB::Black;
        leds[segment_offset + EDGE_SIZE - y] = CRGB::Black;        
        FastLED.show();        
      }
    }
}

void vertexcycle(int flow,int red,int green,int blue)
{
  int x,y;
  int vertex_start = VERTEX_OFFSET;

// flow in  
  if (flow > 0)
    {
        for(y=0; y < VERTEX_SIZE/2; ++y)
          {
            for(x=0; x < NUM_VERTEX; ++x)
              {
                leds[vertex_start + (x*VERTEX_SIZE) + y] = CRGB(red,green,blue);
                leds[vertex_start + ((x+1)*VERTEX_SIZE) -1 - y] = CRGB(red,green,blue);
              }
            FastLED.show();
            delay(500);
            for(x=0; x < NUM_VERTEX; ++x)
              {            
                leds[vertex_start + (x*VERTEX_SIZE) + y] = CRGB::Black;
                leds[vertex_start + ((x+1)*VERTEX_SIZE) -1 - y] = CRGB::Black;            
              }
            FastLED.show();  
          }
    }
// flow out
  if (flow < 0)
    {
        for(y=0; y < VERTEX_SIZE/2; ++y)
          {
            for(x=0; x < NUM_VERTEX; ++x)
              {
                leds[vertex_start + (x*VERTEX_SIZE) + (NUM_VERTEX/2) - y] = CRGB(red,green,blue);
                leds[vertex_start + (x*VERTEX_SIZE) + (NUM_VERTEX/2) + y + 1] = CRGB(red,green,blue);
              }
            FastLED.show();
            delay(500);
            for(x=0; x < NUM_VERTEX; ++x)
              {            
                leds[vertex_start + (x*VERTEX_SIZE) + (NUM_VERTEX/2) - y] = CRGB::Black;
                leds[vertex_start + (x*VERTEX_SIZE) + (NUM_VERTEX/2) + y + 1] = CRGB::Black;
              }
            FastLED.show();  
          }
    }     
}

void vertextimecycle(int flow, int timedelay, int red,int green, int blue)
{
  int x,y;
  int vertex_start = VERTEX_OFFSET;

// flow in  
  if (flow > 0)
    {
        for(y=0; y < VERTEX_SIZE/2; ++y)
          {
            for(x=0; x < NUM_VERTEX; ++x)
              {
                leds[vertex_start + (x*VERTEX_SIZE) + y] = CRGB(red,green,blue);
                leds[vertex_start + ((x+1)*VERTEX_SIZE) -1 - y] = CRGB(red,green,blue);
              }
            FastLED.show();
            delay(timedelay);
            for(x=0; x < NUM_VERTEX; ++x)
              {            
                leds[vertex_start + (x*VERTEX_SIZE) + y] = CRGB::Black;
                leds[vertex_start + ((x+1)*VERTEX_SIZE) -1 - y] = CRGB::Black;            
              }
            FastLED.show();  
          }
    }
// flow out
  if (flow < 0)
    {
        for(y=0; y < VERTEX_SIZE/2; ++y)
          {
            for(x=0; x < NUM_VERTEX; ++x)
              {
                leds[vertex_start + (x*VERTEX_SIZE) + (NUM_VERTEX/2) - y] = CRGB(red,green,blue);
                leds[vertex_start + (x*VERTEX_SIZE) + (NUM_VERTEX/2) + y + 1] = CRGB(red,green,blue);
              }
            FastLED.show();
            delay(timedelay);
            for(x=0; x < NUM_VERTEX; ++x)
              {            
                leds[vertex_start + (x*VERTEX_SIZE) + (NUM_VERTEX/2) - y] = CRGB::Black;
                leds[vertex_start + (x*VERTEX_SIZE) + (NUM_VERTEX/2) + y + 1] = CRGB::Black;
              }
            FastLED.show();  
          }
    }     
}

void fullshell(int red,int green, int blue)
{
  int x;
  
  for(x=0;x<VERTEX_OFFSET;++x)
    leds[x] = CRGB(red,green,blue);
  FastLED.show();  
}

Credits

Jose Cabrera

Jose Cabrera

7 projects • 0 followers
Engineer

Comments