Interactive Geodesic LED Dome

by jbumstead in Circuits > Arduino

39518 Views, 375 Favorites, 0 Comments

Interactive Geodesic LED Dome

Interactive Geodesic LED dome
P1010267.jpg
P1010225.jpg
Making of geodesic LED dome
P1010010.JPG
P1010136.jpg
P1010142.jpg
P1010070.jpg
587c50f71441aaa03e000a72.jpeg

I constructed a geodesic dome consisting of 120 triangles with an LED and sensor at each triangle. Each LED can be addressed individually and each sensor is tuned specifically for a single triangle. The dome is programmed with an Arduino to light up and produce a MIDI signal depending on which triangle you place your hand.

I designed the dome to be a fun display that gets people interested in light, electronics, and sound. Because the dome divides nicely into five parts, I designed the dome to have five separate MIDI outputs that can each have a different sound. This makes the dome a giant musical instrument, ideal for playing music with multiple people simultaneously. In addition to playing music, I also programmed the dome for light shows and playing a rendition of Simon and Pong. The final structure is a little more than a meter in diameter and 70cm tall, and is primarily constructed with wood, acrylic, and 3D printed parts.

There are several great Instructables on LED tables and cubes that inspired me to start this project. However, I wanted to try arranging the LEDs in a different geometry. I couldn’t think of a better structure for the project than a geodesic dome, which is also well documented on Instructables. So this project is a remix/mashup of LED tables and geodesic domes. Below are links to the LED table and geodesic dome Instructables that I checked out at the beginning of the project.

LED tables and cubes:

https://www.instructables.com/id/RGB-LED-Pixel-Touc...

https://www.instructables.com/id/Touch-LED-Table-Re...

https://www.instructables.com/id/Led-Cube-8x8x8/

https://www.instructables.com/id/500-LED-Pixel-RGB-...

Geodesic dome:

https://www.instructables.com/id/Folding-Geodesic-D...

https://www.instructables.com/id/Geodesic-dome-kit/

Supply List

IMG_7399.JPG
587c50daef665a25b40041de.jpeg
585618d6e02ad6a8d400339e.jpeg
IMG_7437.JPG
587c51157a9cb6bb3e001155.jpeg
585618e78852dd3371002ab9.jpeg
IMG_8007.JPG
IMG_7351.JPG
587c512ae02ad6f65b0021a6.jpeg
image.jpeg
IMG_8053.JPG

Materials:

1. Wood for struts of dome and base of dome (amount depends on type and size of dome)

2. Addressable LED strip (16.4ft/5m Addressable Color LED Pixel Strip 160leds Ws2801 Dc5v)

3. Arduino Uno (Atmega328 - assembled)

4. Prototype board (Penta Angel Double-Side Prototype PCB Universal (7x9cm))

5. Acrylic for diffusing LEDs (Cast Acrylic Sheet, Clear, 12" x 12" x 0.118" Size)

6. Power supply (Aiposen 110/220V to DC12V 30A 360W Switch Power Supply Driver)

7. Buck converter for Arduino (RioRand LM2596 DC-DC Buck Converter 1.23V-30V)

8. Buck converter for LEDs and sensors (DROK Mini Electric Buck Voltage Converter 15A)

9. 120 IR sensors (Infrared Obstacle Avoidance Sensor Module)

10. Five 16 channel multiplexers (Analog/Digital MUX Breakout - CD74HC4067)

11. Six 8 channel multiplexers (Multiplexer Breakout - 8 Channel (74HC4051))

12. Five 2 channel multiplexers (MAX4544CPA+)

13. Wire wrap wire (PCB Solder 0.25mm Tin Plated Copper Cord Dia Wire-wrapping Wire 305M 30AWG Red)

14. Hook-up wire (Solid Core, 22 AWG)

15. Pin Headers (Gikfun 1 x 40 Pin 2.54mm Single Row Breakaway Male Pin Header)

16. Five MIDI jacks (Breadboard-friendly MIDI Jack (5-pin DIN))

17. Ten 220ohm resistors for MIDI jacks

18. Stand-off spacers for mounting electronics to dome (Stand-off Spacer Hex M3 Male x M3 Female)

19. Thread adapters to connect stand-offs to wood (E-Z Lok Threaded Insert, Brass, Knife Thread)

20. Epoxy or Gorilla Superglue

21. Electrical tape

22. Solder

Tools:

1. Soldering Station

2. Power drill

3. Circular saw

4. Orbital sander

5. Jig saw

6. Miter saw

7. Protractor

8. 3D printer

9. Wire cutters

10. Wire wrap tool

11. Laser cutter for cutting LED plates (optional)

12. CNC shopbot for base of dome (optional)

Designing the Geodesic Dome

domeStructure2-01.png
3dPartsDome-01.png

As I mentioned in the intro, there are several online sources for building your own geodesic dome. These sites provide dome calculators that determine the length of each side (i.e. strut) and number of connectors required for whatever type of dome you want to build. The complexity of a geodesic dome (i.e. the density of triangles) is specified by its class (1V, 2V, 3V, and so on), with higher complexity becoming a better approximation of a perfect spherical surface. To construct your own dome, you must first select a dome diameter and class.

I used a site called Domerama to help me design a 4V dome that was truncated to 5/12 of a sphere with radius of 40cm. For this type of dome, there are six different length struts:

30 X “A” - 8.9cm

30 X “B” - 10.4cm

50 X “C” - 12.4cm

40 X “D” - 12.5cm

20 X “E” - 13.0cm

20 X “F” - 13.2cm

That is a total of 190 struts that add up to 2223cm (73 ft) of material. I used 1x3 (3/4" × 2-1/2") pine lumber for the struts in this dome. To connect the struts, I designed and 3D printed connectors using Autocad. The STL files are available to download at the end of this step. The number of connectors for a 4V 5/12 dome is:

20 X 4-connector

6 X 5-connector

45 X 6-connector

In the next step, I describe how this dome is constructed with the wooden struts and the 3D printed connectors I designed.

Constructing Dome With Struts and Connectors

IMG_7351.JPG
IMG_7347.JPG
58559beaef665ad60e00009e.jpeg
58559da9ef665a5a640004f8.jpeg
IMG_7313.JPG
IMG_7352.JPG
IMG_7353.JPG
IMG_7323.JPG
58559bbf8080cf31e8001299.jpeg
58559c588852dd33710028e0.jpeg
IMG_7370.JPG
58559e09e02ad6a8d40031a7.jpeg
58559e583dd33a5e40002c89.jpeg

Using the calculations from Domerama for a 4V 5/12 dome, I cut the struts using a circular saw. The 190 struts were labeled and placed in a box after cutting. The 71 connectors (20 four-connectors, 6 five-connectors, and 45 six-connectors) were 3D printed using a Makerbot. The wood struts were inserted into the connectors according to the diagram created by Domerama. I started the construction from the top and moved radially outward.

After all the struts were connected, I removed one strut at a time and added epoxy to the wood and connector. The connectors were designed to have flexibility in how they connected the structs, so it was important to check the symmetry of the dome before adding any epoxy.

Laser Cutting and Mounting Base Plates

5855a22c7a9cb6cdb400257b.jpeg
IMG_7130.JPG
5855a19a8852ddcc3e0004c3.jpeg
5855a19d8ae43bdd93003b57.jpeg
5855a10c8080cf515d0003cc.jpeg
IMG_7378.JPG
IMG_7465.JPG
20160917_212919.jpg
IMG_7469.JPG
IMG_7462.JPG

Now that the skeleton of the dome is constructed, it is time to cut the triangular baseplates. These baseplates are attached to the bottom of the struts, and are used to mount the LEDs to the dome. I initially cut the baseplates out of 5mm (3/16”) thick plywood by measuring the five different triangles that are on the dome: AAB (30 triangles), BCC (25 triangles), DDE (20 triangles), CDF (40 triangles), and EEE (5 triangles). The dimensions of each side and the shape of the triangles were determined using a dome calculator (Domerama) and some geometry. After cutting test baseplates with a jigsaw, I drew the triangle design using Coral Draw, and cut the remaining baseplates with a laser cutter (much faster!). If you do not have access to a laser cutter, you can draw the baseplates onto plywood using a ruler and protractor and cut all of them with a jigsaw. Once the baseplates are cut, the dome is flipped over and the plates are glued to the dome using wood glue.

Electronics Overview

domeSchematic2-01.png

Shown in the figure above is a schematic of the electronics for the dome. An Arduino Uno is used for writing and reading signals for the dome. To light up the dome, a RGB LED strip is run over the dome so that an LED is positioned at each one of the 120 triangles. For information on how an LED strip works, check out this instructable. Each LED can be addressed separately using the Arduino, which produces a serial data and clock signal for the strip (see the A0 and A1 pin in schematic). With the strip and these two signals alone, you can have an awesome light up dome. There are other ways to go about writing signals for lots of LED from an Arduino, such as Charlieplexing and shift registers.

In order to interact with the dome, I set up an IR sensor above each LED. These sensors are used to detect when someone’s hand is close to a triangle on the dome. Because each triangle on the dome has its own IR sensor and there are 120 triangles, you will have to do some sort of multiplexing before the Arduino. I decided to use five 24-channel multiplexers (MUX) for the 120 sensors on the dome. Here is a instructable on multiplexing, if you are unfamiliar. A 24 channel MUX requires five control signals. I chose pins 8-12 on the Arduino, so I could do port manipulation (see Step 10 for more information). The output of the MUX boards are read in using pins 3-7.

I also included five MIDI outputs on the dome so that it could produce sound (Step 11). In other words, five people can play the dome simultaneously with each output playing a different sound. There is only one TX pin on the Arduino, so five MIDI signals requires demultiplexing. Because the MIDI output is produced at a different time than the IR sensor reading, I used the same control signals.

After all the IR sensor inputs are read into the Arduino, the dome can light up and play sounds however you program the Arduino. I have a few examples in Step 14 of this instructable.

Mounting LEDs Onto Dome

DSC_0033.JPG
DSC_0036.JPG
DSC_0041.JPG
DSC_0046.JPG
DSC_0055.JPG
DSC_0057.JPG
5856191c3dd33a5e40002e88.jpeg
5856192ee02ad6a8d40033a1.jpeg

Because the dome is so large, the LED strip needs to be cut to place one LED on each triangle. Each LED is glued on the triangle using super glue. On either side of the LED, a hole is drilled through the baseplate for cables to be run through the dome. I then soldered hook-up wire at each contact on the LED (5V, ground, clock, signal) and feed the wires through the baseplate. These wires are cut so that they are long enough to reach the next LED on the dome. The wires are pulled through to the next LED, and the process is continued. I connected the LEDs in a configuration that would minimize the amount of wire required while still making sense for addressing the LEDs using the Arduino later. A smaller dome would eliminate the need for cutting the strip and save a lot of time soldering. Another option is to use separate RGB LEDS with shift registers.

Serial communication to the strip is achieved using two pins (a data and clock pin) from the Arduino. In other words, the data for lighting up the dome is passed from one LED to the next as it leaves the data pin. Here is example code modified from this Arduino forum:

// Make entire dome increase and decrease intensity of single color
#define numLeds 120 //Number of LEDs

// OUTPUT PINS //
int clockPin = A1; // define clock pin
int dataPin = A0; // define data pin

// VARIABLES //
int red[numLeds];      // Initialize array for LED strip
int green[numLeds];    // Initialize array for LED strip
int blue[numLeds];     // Initialize array for LED strip

//CONSTANT
double scaleA[] = {0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1}; // fraction of intensity of LEDs

void setup() {
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  memset(red, 0, numLeds);
  memset(green, 0, numLeds);
  memset(blue, 0, numLeds);
}

void updatestring(int redA[numLeds], int greenA[numLeds], int blueA[numLeds])
{
  for (int i = 0; i < numLeds; i++)
  {
    shiftOut(dataPin, clockPin, MSBFIRST, redA[i]);
    shiftOut(dataPin, clockPin, MSBFIRST, greenA[i]);
    shiftOut(dataPin, clockPin, MSBFIRST, blueA[i]);
  }
}

void loop() {
   for (int p = 0; p < 20; p++) // loop for increasing light intensity of dome
  {
    double scale = scaleA[p];
    delay(20);

    for (int i = 0; i < numLeds; i++) // cycle through all LEDS
    {
      red[i] = 255 * scale;
      green[i] = 80 * scale;
      blue[i] = 0;
    }
    updatestring(red, green, blue); // update led strip
  }
}

Sensor Mount Design and Implementation

domeSensor-01.png
IMG_7490.JPG
DSC_0031.JPG
DSC_0040.JPG
DSC_0041.JPG
DSC_0043.JPG
DSC_0044.JPG
DSC_0046.JPG
DSC_0048.JPG
DSC_0050.JPG
DSC_0051.JPG
IMG_7701.JPG
58729a908080cfca950022a1.jpeg
IMG_7698.JPG
IMG_7709.JPG
IMG_7884.JPG
DSC_0031.JPG
DSC_0029.JPG
IMG_7882.JPG
58574c863dd33a5e40003385.jpeg

I decided to use IR sensors for the dome. These sensors have an IR LED and receiver. When an object gets in front of the sensor, some IR radiation from the IR LED is reflected towards the receiver. I started this project by making my own IR sensors, which were based off Richardouvina’s instructable. All the soldering took way too long, so I purchased 120 IR sensors from eBay that each produce a digital output. The threshold of the sensor is set with a potentiometer on the board so that the output is high only when a hand is near that triangle.

Each triangle consists of a plywood LED-baseplate, a sheet of diffusive acrylic mounted about 2.5cm above the LED plate, and an IR sensor. The sensor for each triangle was mounted onto a sheet of thin plywood shaped as a pentagon or hexagon depending on the position on the dome (see the figure above). I drilled holes into the IR sensor base to mount the IR sensors, and then connected the ground and 5V pins with wire-wrap wire and a wire-wrap tool (red and black wires). After connecting ground and 5V, I wrapped long wire-wrap wire on each output (yellow), ground, and 5V to run through the dome.

The hexagon or pentagon IR sensor mounts were then epoxied to the dome, right above the 3D printed connectors, so that the wire could run through the dome. By having the sensors above the connectors, I was also able to access and adjust the potentiometers on the IR sensors that control the sensitivity of the sensors. In the next step, I will describe how the outputs of the IR sensors are connected to multiplexers and read into the Arduino.

Multiplexing Sensor Output

domeSchematic2-01.png
IMG_7440.JPG
DSC_0022.JPG
DSC_0023.JPG
DSC_0025.JPG
IMG_7442.JPG
20161119_151745.jpg
IMG_7748.JPG
IMG_7937.JPG
IMG_7907.JPG
IMG_7941.JPG

Because the Arduino Uno has only 14 digital I/O pins and 6 analog input pins and there are 120 sensor signals that must be read, the dome requires multiplexers to read in all the signals. I chose to construct five 24-channel multiplexers, each of which read 24 of the IR sensors (see the electronics overview figure). The 24-channel MUX consist of an 8-channel MUX breakout board, 16-channel MUX breakout board, and 2-channel MUX. Pin headers were soldered to each breakout board so that they could be connected to prototype board. Using a wire-wrap tool, I then connected ground, 5V, and the control signal pins of the MUX breakout boards.

A 24-channel MUX requires five control signals, which I chose to connect to pin 8-12 on the Arduino. All five 24-channel MUX receive the same control signals from the Arduino so I connected wire from the Arduino pins to the 24-channel MUX. The digital outputs of the IR sensors are connected to the input pins of the 24-channel MUX so that they can be read in serially to the Arduino. Because there are five separate pins for reading in all 120 sensor outputs, it is helpful to imagine the dome being split into five separate sections consisting of 24 triangles (check colors of dome in figure).

Using Arduino port manipulation, you can quickly increment the control signals sent by pins 8-12 to the multiplexers. I have attached some example code for operating the multiplexers here:

int numChannel = 24;

// OUTPUTS //
int s0 = 8; // MUX control 0 - PORTbD
int s1 = 9; // MUX control 1 - PORTb
int s2 = 10; // MUX control 2 - PORTb
int s3 = 11; // MUX control 3 - PORTb
int s4 = 12; // MUX control 4 - PORTb

// INPUTS //
int m0 = 3;  // MUX input 0
int m1 = 4;  // MUX input 1
int m2 = 5;  // MUX input 2
int m3 = 6;  // MUX input 3
int m4 = 7;  // MUX input 4

// VARIABLES //
int arr0r; // digital read from MUX0
int arr1r; // digital read from MUX1
int arr2r; // digital read from MUX2
int arr3r; // digital read from MUX3
int arr4r; // digital read from MUX4

void setup() {
  // put your setup code here, to run once:

  DDRB = B11111111; // sets Arduino pins 8 to 13 as inputs

  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(s4, OUTPUT);

  pinMode(m0, INPUT);
  pinMode(m1, INPUT);
  pinMode(m2, INPUT);
  pinMode(m3, INPUT);
  pinMode(m4, INPUT);

}

void loop() {
  // put your main code here, to run repeatedly:

  PORTB = B00000000; // SET control pins for mux low

  for (int i = 0; i < numChannel; i++) {

    // Digital read output of MUX0 - MUX4 for IR sensor i
    // If IR sensor is LO, the triangle is being touched by player.
    arr0r = digitalRead(m0); // reading from Mux 0, IR sensor i
    arr1r = digitalRead(m1); // reading from Mux 1, IR sensor i
    arr2r = digitalRead(m2); // reading from Mux 2, IR sensor i
    arr3r = digitalRead(m3); // reading from Mux 3, IR sensor i
    arr4r = digitalRead(m4); // reading from Mux 4, IR sensor i

    // DO SOMETHING WITH MUX INPUTS OR STORE IN AN ARRAY HERE //

    PORTB ++; // increment control signals for MUX
    
  }

}

Diffusing Light With Acrylic

586185757a9cb6529e0019a5.jpeg
586186509bad4bf7d50019a9.jpeg
58618686ef665a405f000b1d.jpeg
586186993dd33a60140019ea.jpeg
5861869565d221a90c000d2f.jpeg
586186aa8852ddf3aa0012ca.jpeg
IMG_7635.JPG
IMG_7638.JPG
IMG_7600.JPG

To diffuse the light from the LEDs, I sanded transparent acrylic with a circular orbital sander. The sander was moved over both sides of the acrylic in a figure-8 motion. I found this method to be much better than “frosted glass” spray paint.

After sanding and cleaning up the acrylic, I used a laser cutter to cut out triangles to fit over the LEDs. It is possible to cut the acrylic using an acrylic cutting tool or even a jigsaw if the acrylic does not crack. The acrylic was held over the LEDs by 5mm thick plywood rectangles also cut with a laser cutter. These small planks were glued to the struts on the dome, and the acrylic triangles were epoxied onto the planks.

Making Music With the Dome Using MIDI

IMG_8053.JPG
5872c1f0ef665a26be00245e.jpeg
IMG_8050.JPG

I wanted the dome to be capable of producing sound, so I set up five MIDI channels, one for each subset of the dome. You first need to purchase five MIDI jacks and connect it as shown in the schematic (see this tutorial from Arduino support for more info).

Because there is only one transmit serial pin on the Arduino Uno (pin 2 labeled as the TX pin), you need to de-multiplex the signals being sent to the five MIDI jacks. I used the same control signals (pin 8-12), because MIDI signals are sent at a different time than when the IR sensors are being read into the Arduino. These control signals are sent to an 8-channel demultiplexer so that you control which MIDI jack receives the MIDI signal created by the Arduino. The MIDI signals were generated by the Arduino with the terrific MIDI signal library created by Francois Best. Here is some example code for producing multiple MIDI outputs to different MIDI jacks with an Arduino Uno:

#include <MIDI.h> // include MIDI library

#define numChannel 24 //Number of IR per Triangle
#define numSections 5 // number of sections in dome, number of 24channel MUX, number of MIDI jacks

// OUTPUTS //
int s0 = 8; // MUX control 0 - PORTbD
int s1 = 9; // MUX control 1 - PORTb
int s2 = 10; // MUX control 2 - PORTb
int s3 = 11; // MUX control 3 - PORTb
int s4 = 12; // MUX control 4 - PORTb

// INPUTS //
int m0 = 3;  // MUX input 0
int m1 = 4;  // MUX input 1
int m2 = 5;  // MUX input 2
int m3 = 6;  // MUX input 3
int m4 = 7;  // MUX input 4

// VARIABLES //
int arr0r; // digital read from MUX0
int arr1r; // digital read from MUX1
int arr2r; // digital read from MUX2
int arr3r; // digital read from MUX3
int arr4r; // digital read from MUX4

int midArr[numSections];   // Store whether or not a note has been pressed by one of the players
int note2play[numSections]; // Store note to be played if sensor is touched
int notes[numChannel] = {60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83};
int pauseMidi = 4000; // pause time between midi signals

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  // put your setup code here, to run once:

  DDRB = B11111111; // sets Arduino pins 8 to 13 as inputs

  MIDI.begin(MIDI_CHANNEL_OFF);
  
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(s4, OUTPUT);

  pinMode(m0, INPUT);
  pinMode(m1, INPUT);
  pinMode(m2, INPUT);
  pinMode(m3, INPUT);
  pinMode(m4, INPUT);

}

void loop() {
  // put your main code here, to run repeatedly:

  PORTB = B00000000; // SET control pins for mux low

  for (int i = 0; i < numChannel; i++) {

    // Digital read output of MUX0 - MUX4 for IR sensor i
    // If IR sensor is LO, the triangle is being touched by player.
    arr0r = digitalRead(m0); // reading from Mux 0, IR sensor i
    arr1r = digitalRead(m1); // reading from Mux 1, IR sensor i
    arr2r = digitalRead(m2); // reading from Mux 2, IR sensor i
    arr3r = digitalRead(m3); // reading from Mux 3, IR sensor i
    arr4r = digitalRead(m4); // reading from Mux 4, IR sensor i

    if (arr0r == 0)// Sensor on section 0 was blocked
    {
      midArr[0] = 1; // Player 0 has hit a note, set HI so that there is MIDI output for player 0
      note2play[0] = notes[i];   // Note to play for Player 0
    }

    if (arr1r == 0)// Sensor on section 1 was blocked
    {
      midArr[1] = 1; // Player 0 has hit a note, set HI so that there is MIDI output for player 0
      note2play[1] = notes[i];   // Note to play for Player 0
    }

    if (arr2r == 0)// Sensor on section 2 was blocked
    {
      midArr[2] = 1; // Player 0 has hit a note, set HI so that there is MIDI output for player 0
      note2play[2] = notes[i];   // Note to play for Player 0
    }

    if (arr3r == 0)// Sensor on section 3 was blocked
    {
      midArr[3] = 1; // Player 0 has hit a note, set HI so that there is MIDI output for player 0
      note2play[3] = notes[i];   // Note to play for Player 0
    }

    if (arr4r == 0)// Sensor on section 4 was blocked
    {
      midArr[4] = 1; // Player 0 has hit a note, set HI so that there is MIDI output for player 0
      note2play[4] = notes[i];   // Note to play for Player 0
    }

    PORTB ++; // increment control signals for MUX

  }

  updateMIDI();
}

void updateMIDI()
{

  PORTB = B00000000; // SET control pins for mux low
  if (midArr[0] == 1) // Player 0 MIDI output
  {
    MIDI.sendNoteOn(note2play[0], 127, 1);
    delayMicroseconds(pauseMidi);
    MIDI.sendNoteOff(note2play[0], 127, 1);
    delayMicroseconds(pauseMidi);
  }

  PORTB ++; // increment MUX
  if (midArr[1] == 1) // Player 1 MIDI output
  {
    MIDI.sendNoteOn(note2play[1], 127, 1);
    delayMicroseconds(pauseMidi);
    MIDI.sendNoteOff(note2play[1], 127, 1);
    delayMicroseconds(pauseMidi);
  }

  PORTB ++; // increment MUX
  if (midArr[2] == 1) // Player 2 MIDI output
  {
    MIDI.sendNoteOn(note2play[2], 127, 1);
    delayMicroseconds(pauseMidi);
    MIDI.sendNoteOff(note2play[2], 127, 1);
    delayMicroseconds(pauseMidi);
  }

  PORTB ++; // increment MUX
  if (midArr[3] == 1) // Player 3 MIDI output
  {
    MIDI.sendNoteOn(note2play[3], 127, 1);
    delayMicroseconds(pauseMidi);
    MIDI.sendNoteOff(note2play[3], 127, 1);
    delayMicroseconds(pauseMidi);
  }

  PORTB ++; // increment MUX
  if (midArr[4] == 1) // Player 4 MIDI output
  {
    MIDI.sendNoteOn(note2play[4], 127, 1);
    delayMicroseconds(pauseMidi);
    MIDI.sendNoteOff(note2play[4], 127, 1);
    delayMicroseconds(pauseMidi);
  }

  midArr[0] = 0;
  midArr[1] = 0;
  midArr[2] = 0;
  midArr[3] = 0;
  midArr[4] = 0;

}

Powering the Dome

58574bfe8080cfd92e0000d0.jpeg
image.jpeg
587294eee02ad691e8000a6e.jpeg
5872950ce02ad6f65b0001c6.jpeg

There are several components that need to be powered in the dome. You will therefore need to calculate the amps drawn from each component to determine the power supply you need to purchase.

The LED strip: I used approximately 3.75meters of the Ws2801 LED strip, which consumes 6.4W/meter. This corresponds to 24W (3.75*6.4). To convert this to amps, use Power = current*volts (P=iV), where V is the voltage of the LED strip, in this case 5V. Therefore, the current drawn from the LEDs is 4.8A (24W/5V = 4.8A).

The IR sensors: Each IR sensor draws about 25mA, totaling 3A for 120 sensors.

The Arduino: 100mA, 9V

The multiplexers: There are five 24 channel multiplexers that each consist of a 16 channel multiplexer and 8 channel multiplexer. The 8 channel and 16 channel MUX each consumes about 100mA. Therefore, the total power consumption of all the MUX is 1A.

Adding up these components, the total power consumption is expected to be around 9A. The LED strip, IR sensors, and multiplexers have input voltage at 5V, and the Arduino has 9V input voltage. Therefore, I selected a 12V 15A power supply, a 15A buck converter for converting the 12V to 5V, and a 3A buck converter for converting 12V to 9V for the Arduino.

Circular Dome Base

587c52351441aafb73000498.jpeg
587c67b93dd33aeaf7005462.jpeg
DSC08064.JPG
IMG_8002.JPG
587c67e8ef665a25b400424c.jpeg
587c681f8852dd8aa300526c.jpeg
587c68433dd33aeaf7005466.jpeg
IMG_8049.JPG

The dome rests on a circular piece of wood with a pentagon cut out of the middle for easy access to the electronics. To create this circular base, a 4x6’ sheet of plywood was cut using a wood CNC router. A jigsaw could also be used for this step. After the base was cut, the dome was attached to it using small 2x3” blocks of wood.

On top of the base, I attached the power supply with epoxy and the MUX’s and Buck converters with PCB stand-off spacers. The spacers were attached to the plywood using E-Z Lok thread adapters.

Pentagon Dome Base

587c685e1441aaa03e000aea.jpeg
IMG_7957.JPG
IMG_7960.JPG
587c687f1441aaa03e000aeb.jpeg
IMG_8043.JPG
DSC_0017.JPG
DSC_0020.JPG
DSC_0012.JPG
DSC_0028.JPG
587c68b5e02ad6f65b002219.jpeg
DSC_0025.JPG
DSC_0030.JPG
DSC_0032.JPG
DSC_0042.JPG
587c68fb8ae43b268f000761.jpeg
587c69338ae43b82f0001109.jpeg
IMG_8110.JPG
587c69548ae43b82f000110a.jpeg

In addition to the circular base, I also constructed a pentagon base for the dome with a looking-glass window at the bottom. This base and looking window were also made out of plywood cut with a wood CNC router. The sides of the pentagon are made out of wooden planks with one side having a hole in it for the connectors to go through. Using metal brackets and 2x3 block joints, the wooden planks are attached to the pentagon base. A power switch, MIDI connectors, and USB connector are attached to a front panel that I created using a laser cutter. The entire pentagon base is screwed to the circular base described in Step 12.

I installed a window into the bottom of the dome so that anyone can look up into the dome to see the electronics. The looking glass is made out of acrylic cut with a laser cutter and is epoxied to a circular piece of plywood.

Programming the Dome

There are endless possibilities for programming the dome. Each cycle of the code takes in the signals from the IR sensors, which indicate the triangles that have been touched by someone. With this information you can color the dome with any RGB color and/or produce a MIDI signal. Here are a few examples of programs that I wrote for the dome:

Color the dome: Each triangle cycles through four colors as it is touched. As the colors change, an arpeggio is played. With this program, you get to color the dome in thousands of different ways.

Dome music: The dome is colored with five colors, each section corresponding to a different MIDI output. In the program, you can choose which notes each triangle plays. I chose to start at middle C at the top of the dome, and increase the pitch as the triangles moved closer to the base. Because there are five outputs, this program is ideal for having multiple people play the dome simultaneously. Using a MIDI instrument or MIDI software, these MIDI signals can be made to sound like any instrument.

Simon: I wrote a rendition of Simon, the classic memory light-up game. A random sequence of lights is illuminated one at a time over the entire dome. In each turn, the player must copy the sequence. If the player matches the sequence correctly, an additional light is added to the sequence. The high score is stored on one of the sections of the dome. This game is also very fun to play with multiple people.

Pong: Why not play pong on a dome? A ball propagates across the dome until in hits the paddle. When it does, a MIDI signal is produced, indicating the paddle hit the ball. The other player must then direct the paddle along the bottom of the dome so that it hits the ball back.

Photos of Completed Dome

P1010245.jpg
P1010161.jpg
P1010153.jpg
P1010060.jpg
P1010108.jpg
P1010010.jpg
P1010073.jpg