Project showcase
Icosahedron Sphere NeoPixel Device (No Plutonium Used)

Icosahedron Sphere NeoPixel Device (No Plutonium Used) © GPL3+

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

  • 513 views
  • 1 comment
  • 2 respects

Components and supplies

Necessary tools and machines

Apps and online services

About this project

A common project among the members of the LVL1.org Hackerspace is a LED blinking thing. Some are just the Blinky sketch on an Arduino while others are a bit more involved. This is my LED blinking project.

Found at http://wiki.lvl1.org/Neopixel_Icosahedron is a full write up along with links to other projects.

Code

Example Code DemoArduino
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();  
}

Custom parts and enclosures

Parts Listing
Yep, parts.
Jac i20 16 2k9tiawqbd

Schematics

Basic Measurements
General measurements for device.
Jac i20 20 kk1b3zzpmq
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.
Jac i20 40 biuuzea4ih
Neopixel Signal Line Through Vertex
The signal line for the Neopixels covers all edges and is then routed through the vertex strips.
Jac i20 44 ns1uv9iidv
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.
Jac i20 28 zhrkaotz6x
Vertices Wiring
The vertices are each matched to a specific wiring setup. This image displays how each vertex is is wired for signal routing.
Jac i20 48 8yvvdqqbgg
LED Numbering
The Neopixels are identified by address per edge and vertex.
Jac i20 52 imnlrgxuem

Comments

Similar projects you might like

Neopixel LED EyeBall

Project tutorial by HomeMadeGarbage

  • 6,878 views
  • 22 comments
  • 28 respects

Portable Range Detection Device

Project tutorial by Viktor S

  • 8,828 views
  • 5 comments
  • 21 respects

Carfox: A Device to Find Them All

Project tutorial by Luis Roda Sánchez

  • 7,673 views
  • 2 comments
  • 28 respects

Arduino Powered CPR Feedback Device

Project showcase by David Escobar

  • 6,028 views
  • 9 comments
  • 28 respects

S(mart) - Coop

Project showcase by Nadeem Ahmed

  • 2,135 views
  • 1 comment
  • 8 respects

Unicorn Horn With NeoPixel LEDs and Arduino Lilypad

Project tutorial by Hilal Güngör and Merve GUNGOR

  • 1,631 views
  • 3 comments
  • 11 respects
Add projectSign up / Login