Introduction: Celestial Sphere - Sky Dome

This project is an astronomy educational tool teaching about stars’ constellations, where the user can pick and choose any constellation they would like out of 15 different ones. The dome is manually rotatable so the user can imitate the relative movement of the stars.

Supplies

  • PLA Filament
  • Swedish Wood 30*30*4 cm
  • ATmega 328p
  • LEDs 120 pieces
  • Resistors
  • Wires
  • LCD
  • Rotary Encoder
  • Ardiono Nano
  • Slip ring conductive connector
  • Mosfets
  • Pin Headers
  • Glitter, colors and all things shiny
  • Some miscellaneous components

Step 1: Preparing the Sphere

First off, download the file named "Sphere" for the dome from the attachments. I 3D printed it using PLA on Ultimaker2, yet any printer should do fine. Check the settings I used from the image above.

After you print the dome, paint it with some shades of blue, and lots and lots of glitter.

Now, use the image of the constellations to trace the 15 constellations. you should find the following:

  • LYNX
  • Leo Minor
  • Aries
  • Pisces
  • Pegasus
  • Lyra
  • Camelopardalis
  • Draco
  • Cephus
  • Ursa Minor
  • Hercules
  • Ursa Major
  • Corona Borealis
  • Bootes
  • Cassiopeia

This should take p around 117 stars. Tape the lines of each constellation together, you'll need it later.

Step 2: The Bases

In this part you'll need to thoroughly check the images above.

The STL Files for this part are attached, but depending on the type of your CNC machine you might want to use the projections of each side.

I started by uploading the projection of each part on vCarve. Let's start with the rotating base as it's only one sided. After Uploading the DXF file (you can find it in the attachements), I added the dimensions and all, and moved on to select the toolpaths.

To make things easier, I attached the dxf files for the upper sides of both bases. for the lower base, you'll need to use the STL because the cut has a slope and not a one line cut.

The first toolpath I added was the inner pocket, I clicked on toolpaths, chose pocket, and then added the settings which you can check in the image above.

One by one, I added the rest of the settings, leaving the outer cut last to ensure the piece is fixed well and isn't moving.

Next, I uploaded the other piece, I dealt with it as two half and worked on the side that has the 2d pockets the same way I did before.

What I did next is that I flipped the wooden piece, but I maintained the center in place by drawing a square on the machine's bed before removing the piece and then putting in back flipped in the same square. I also used 2 new toolpaths as shown in the images, with the settings for each of them.

Note here that I used tabs, as I don't want the piece to fall or move since the first half is already cut.

After preparing the 2 pieces, we'll be done with woodworking and ready for the next step.

Step 3: Electronics

For the electronics, I had 2 boards: one of them is the ATmega board controlling the encoder and the screen, and the other one contains the mosfets and the Arduino nano. You can download the schematics and the board of the ATmega board, and you can also download the schematics and the board of the mosfets from the attached files.The settings I used for the mosfet's traces are shown in the images.

and as for the holes and outercut, I changed the process from the top left to PCB outline (1/32) and used different settings, also shown in the images.

I repeated the traces settings for the other boards, and same for the outer cut's and holes' of the other board. I made them using the SRM-20 milling machine, before I soldered the components on each board. The images show the ATmega board that is connected to the encoder and the LCD.

The second board that contains the mosfets and the Arduino Nano.Mosfets are some sort of a gate, when they receive a signal, they open their gates allowing the current to pass through to the LEDs. Then, solder all the parts together.

Something that I did on the Arduino Nano board is that after I soldered all the parts, I taped the board because it was going to go inside the dome, and although everything in there was insulated with hot silicone, I preferred to double it to make sure no accidents will occur. You can see how it looked from the images.

I soldered all the parts together, then I calculated the resistor to be placed for each constellation, you can see the table in the photos.

Next I soldered the star constellations together. I did that by connecting the number of LEDs on each constellations together in parallel, and left the + and - on one side longer, I added the required resistor to each constellation (as stated in the table above), in order to connect them to the Vin and GND on the mosfets board.

Step 4: Programming

I assigned a different letter for each constellation, This letter will be sent from the ATmega board through i2c communication to the Arduino Nano which will recieve it, and depending on which number it is, it will send the signal to a mosfet to allow the current to pass to the LED group chosen.

I programmed each board with the function I want it to have, below is the code I used for the ATmega board. I found a code online, you can check it from here. The tutorial has a menu shown on a screen and a rotatry encoder. The code was complicated, and I had to do A LOT of manipulation to get it to work= according to my needs. To be honest, There was a lot of trial and error in making this code, the tutorial had the video of the code working, but the code itself didn't say what each line does, and so I had to figure it out for my self.Also, in this code I added the constellations names to the menu, and I assigned a different letter (which then turned Hex) to each one.

The code is:

#include <OneButton.h>
#include <Encoder.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal.h>
#include <Wire.h>

const int rs = 12, en = 11, d4 = 8, d5 = 7, d6 = 6, d7 = 5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// ROTARY ENCODER
long oldPosition  = 0;
int encoderDTpin = 3;
int encoderCLKpin = 2;
Encoder myEnc(encoderDTpin, encoderCLKpin);

int buttonPin = 4;
OneButton button0(buttonPin, true);


// MENU ARRAY 
// First number in array = amount of menu items in root layer. Same goes for next layer. (Example: first value in array is 4. This means Layer 0 has 4 menu items. Layer 1 has only 2 menu items.)
// First number infront of menu text is the layer number that item points to. (Example: 1_Rotation points to Layer 1)
// Second number infront of menu text is the number of the value connected to that menu item in the values array. (Example: 15Direction points to position 5 in the values array)

String menu[] = {"15","056Lynx","056Leo Minor","056Aries","056Pisces","056Pegasus","056Lyra","056Camelopardalis","056Draco","056Cephus","056Ursa Minor","056Hercules","056Ursa Major","056CronaBorealis","056Bootes","056Cassiopeia"};      
                 

// VALUES ARRAY
// TYPES, 1 numeric / 2 character value range
// 1 - type,value,increments,min,max
// 2 - type,starting value in options array,lowest value options array,max value options array
int values[] = {1,11,25,50,1450, //0-4 WATCH1
                2,2,0,2,         //5-8
                1,600,25,75,600, //9-13
                
                1,11,25,50,1450, //14-18 WATCH2
                2,2,0,2,         //19-22
                1,600,25,75,600, //23-27
                
                1,11,25,50,1450, //28-32 WATCH3
                2,2,0,2,         //33-36
                1,600,25,75,600, //37-41
                 
                1,11,25,50,1450, //42-46 WATCH4
                2,2,0,2,         //47-50
                1,600,25,75,600, //51-55
                
                2,4,3,4,         //56-59 WATCH1 ACTIVE
                2,4,3,4,         //60-63 WATCH2 ACTIVE
                2,4,3,4,         //64-67 WATCH3 ACTIVE
                2,4,3,4};        //68-71 WATCH4 ACTIVE
                
                
String options[] = {"CW","CCW","MIX",
                    "Y","N"};                 

// Custom character for LCD.
byte cursor[8] = {
  0b10000,
  0b10000,
  0b01000,
  0b00110,
  0b01000,
  0b10000,
  0b10000,
  0b00000
};

byte watch[8] = {
  0b01110,
  0b01110,
  0b11011,
  0b10001,
  0b10001,
  0b11011,
  0b01110,
  0b01110
};


int currentType = 0;
int value = 0;
int numIncr = 0;
int Min = 0;
int Max = 0;

int currentLayer = 0;
int lastLayer = 99;
int currentLength = menu[0].toInt();
int currentPosition = 0;
int currentSelect = 1;
int currentChange = 0;
String currentPress = "";
float currentlcdLayerFloat = 0;
int currentlcdLayer = 0;
int lastlcdLayer = 0;
int lcdUpdated = 0;
int currentLine = 0;
int cursorLayer = 0;
int cursorPosition = 0;
int valueLength = 0;




void setup() {
  Serial.begin(9600);

  Wire.begin(); // join i2c bus (address optional for master)


  // Map rotary button to actions single and doubleclick.
  button0.attachClick(singleClick);


  lcd.begin (16,2);
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home();

  // Create the custom character.
  lcd.createChar(0, cursor);
  lcd.createChar(1, watch);

  lcd.setCursor (2,0);  
  lcd.print("Hello stars!");
  delay(1000);
  clearLine(0);

  // Set the select cursor on the first line.
  cursorLayer = 0;
  lcd.setCursor (0,cursorLayer);  
  writeCursor();

}

void loop() {
    
    // Listen to button presses.
    button0.tick();

    // Listen if the rotary encoder moves.
    rotary_check();
    
    // Print the LCD menu.
    lcdMenu();

}

void singleClick() {

  // IF current layer number is the same as redirect layer number, we stay on the same layer
  // AND no item is selected in the menu
  // AND the selected item has a redirect to another layer
  if(currentLayer == menu[currentPosition + currentSelect].substring(0,1).toInt() && menu[currentPosition + currentSelect].substring(1,3) != "__" && currentPress == ""){
    
    currentPress = menu[currentPosition + currentSelect].substring(3);
    currentChange = menu[currentPosition + currentSelect].substring(1,3).toInt();
    
    Serial.println("Currentpress: " + currentPress); // send every constellation's assigned letter to the Arduino board


   if(currentPress == "Lynx")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("A");        // sends 1 byte
  Wire.endTransmission(); 
   }

   if(currentPress == "Leo Minor")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("B");        // sends 1 byte
  Wire.endTransmission(); 
   }

      if(currentPress == "Aries")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("C");        // sends 1 byte
  Wire.endTransmission(); 
   }

  if(currentPress == "Pisces")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("D");        // sends 1 byte
  Wire.endTransmission(); 
   }

   if(currentPress == "Pegasus")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("E");        // sends 1 byte
  Wire.endTransmission(); 
   }

    if(currentPress == "Lyra")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("F");        // sends 1 byte
  Wire.endTransmission(); 
   }
  if(currentPress == "Camelopardalis")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("G");        // sends 1 byte
  Wire.endTransmission(); 
   }

 if(currentPress == "Draco")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("H");        // sends 1 byte
  Wire.endTransmission(); 
   }

if(currentPress == "Cephus")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("I");        // sends 1 byte
  Wire.endTransmission(); 
   }

   if(currentPress == "Ursa Minor")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("J");        // sends 1 byte
  Wire.endTransmission(); 
   }

   if(currentPress == "Hercules")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("K");        // sends 1 byte
  Wire.endTransmission(); 
   }

   if(currentPress == "Ursa Major")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("L");        // sends 1 byte
  Wire.endTransmission(); 
   }
   
   if(currentPress == "CronaBorealis")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("M");        // sends 1 byte
  Wire.endTransmission(); 
   }
   
   if(currentPress == "Bootes")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("O");        // sends 1 byte
  Wire.endTransmission(); 
   }
   
   if(currentPress == "Cassiopeia")
   {
     Wire.beginTransmission(8); // transmit to device #8
  Wire.write("P");        // sends 1 byte
  Wire.endTransmission(); 
   }



    currentType = values[currentChange];
    value = values[currentChange + 1];

    // Type select change is numeric
    if(currentType == 1){
      Min = values[currentChange + 3];
      Max = values[currentChange + 4];
      numIncr = values[currentChange + 2];
      
      Serial.println("Currentvalue: " + String(value));
      Serial.println("Increments: " + String(numIncr));
      Serial.println("Min: " + String(Min));
      Serial.println("Max: " + String(Max));

      
      valueLength = String(value).length();
      
    // Type select change is character range
    } else if(currentType == 2){
      Min = values[currentChange + 2];
      Max = values[currentChange + 3];

      Serial.println("Currentvalue: " + options[value]);
      Serial.println("Options: ");

      Wire.beginTransmission(8); // transmit to device #8
  Wire.write(options[value].c_str());              // sends one byte
  Wire.endTransmission();



      for (int i=Min; i <= Max; i++){
        Serial.println(options[i]);
      }

      valueLength = options[value].length();

    }

    clearSelect();
    cursorPosition = 15 - valueLength;
    lcd.setCursor(cursorPosition,cursorLayer);
    writeCursor();

  // ELSE IF something is selected in the menu, and the button is pressed again. We deselect the item.  
  } else if(currentPress != ""){
    
    currentValues();
    currentPress = "";
    currentChange = 0;

    clearChar(cursorPosition,cursorLayer);
    lcd.setCursor(0,cursorLayer);
    writeCursor();
    
  // IF nothing is selected and nothing will be deselected, move to the redirect layer listed in the first position of the array.  
  } else {
    
    currentLayer = menu[currentPosition + currentSelect].substring(0,1).toInt();
    currentSelect = 1;
    currentlcdLayerFloat = 0;
    currentlcdLayer = 0;
    lastlcdLayer = 0;

    clearSelect();
    cursorLayer = 0;
    lcd.setCursor (0,cursorLayer);  
    writeCursor();
    
  }
  
}


void rotary_check(){

  // Constantly read the position of the rotary encoder
  long newPosition = myEnc.read() / 4;

  // IF the new position of the encoder is different then the old position
  if (newPosition != oldPosition) {
       
    // IF nothing has been selected in the menu
    if(currentPress == ""){

      if(newPosition > oldPosition && currentSelect < currentLength){
        clearSelect();
        currentSelect++;
        currentlcdLayerFloat = currentlcdLayerFloat + 0.5;
        currentlcdLayer = currentlcdLayerFloat;

        cursorSelect();
        
        lcd.setCursor (0,cursorLayer);  
        writeCursor();
        Serial.println("> " + menu[currentPosition + currentSelect].substring(3));

      } else if (newPosition < oldPosition && currentSelect != 1){
        clearSelect();
        currentSelect--;
        currentlcdLayerFloat = currentlcdLayerFloat - 0.5;
        currentlcdLayer = currentlcdLayerFloat;

        cursorSelect();

        lcd.setCursor (0,cursorLayer);  
        writeCursor();
        Serial.println("> " + menu[currentPosition + currentSelect].substring(3));
  
      }
      
      if(lastlcdLayer != currentlcdLayer){
        lcdUpdated = 0;
      }
      
      lastlcdLayer = currentlcdLayer;      
      oldPosition = newPosition;



    // IF something has been selected in the menu, we are going to change the value of a menu item.
    } else if(currentPress != ""){

      
      lcd.setCursor(cursorPosition + 1,cursorLayer);
      // IF the new position is HIGHER then the old position
      if(newPosition > oldPosition){
        clearChar(cursorPosition,cursorLayer);
        
        // IF the selected item has a change type that is NUMERIC.
        // AND the MAXIMUM of the selected item has not been reached. 
        // We change the value UPWARDS with the icrements listed in the array.
        // SAME applies for next ELSE IF, just for the change type character. And the next ELSE IF we just go down.
        if(currentType == 1 	&& value < Max){
            value = value + numIncr;
            values[currentChange + 1] = value;
            Serial.println(value);

            clearValue();
            valueLength = String(value).length();
            cursorPosition = 15 - valueLength;
            lcd.setCursor(cursorPosition + 1,cursorLayer);
            lcd.print(value);
          }

        if(currentType == 2 	&& value < Max){
            value++;
            values[currentChange + 1] = value;
            Serial.println(options[value]);

            clearValue();
            valueLength = options[value].length();
            cursorPosition = 15 - valueLength;
            lcd.setCursor(cursorPosition + 1,cursorLayer);
            lcd.print(options[value]);
          }
          lcd.setCursor(cursorPosition,cursorLayer);
          writeCursor();
        
      } else {
        clearChar(cursorPosition,cursorLayer);
        
        if(currentType == 1 	&& value > Min){
          value = value - numIncr;
          values[currentChange + 1] = value;
          Serial.println(value);

          clearValue();
          valueLength = String(value).length();
          cursorPosition = 15 - valueLength;
          lcd.setCursor(cursorPosition + 1,cursorLayer);
          lcd.print(value);
        }

        if(currentType == 2 && value > Min){
            value--;
            values[currentChange + 1] = value;
            Serial.println(options[value]);

            clearValue();
            valueLength = options[value].length();
            cursorPosition = 15 - valueLength;
            lcd.setCursor(cursorPosition + 1,cursorLayer);
            lcd.print(options[value]);
          }
          lcd.setCursor(cursorPosition,cursorLayer);
          writeCursor();
        
      }

      
        
      oldPosition = newPosition;
    } else {
      oldPosition = newPosition;
    }
    
    
    
  }
}

void lcdMenu(){
  if (lastLayer != currentLayer || lcdUpdated == 0){

    currentLength = menu[0].toInt();
    currentPosition = 0;
    
    for (int i=0; i < currentLayer; i++){
      currentPosition = (menu[currentPosition].toInt() + 1) + currentPosition;
      currentLength = menu[currentPosition].toInt();
    }

    clearMenu();
    int tempPosition = currentPosition;
    
    if(currentlcdLayer != 0){
      
      currentPosition = currentPosition + (currentlcdLayer * 2);
    }
    
    Serial.println("LCD-------------");

    for (int i=1; i <	= 2; i++){
      lcd.setCursor (1,i - 1);  
      lcd.print(menu[currentPosition + i].substring(3));
      
      currentType = 0;
      value = values[menu[currentPosition + i].substring(1,3).toInt() + 1];
      String tempvalue = "";
      
      if(menu[currentPosition + i].substring(1,3) != "__" && menu[currentPosition + i].substring(1,3) != ""){
        currentType = values[menu[currentPosition + i].substring(1,3).toInt()];
        if(currentType == 1){
          lcd.setCursor (16 - String(value).length(),i - 1);
          lcd.print(value);
          tempvalue = " "+ String(value);
        }else if(currentType == 2){
          lcd.setCursor (16 - options[value].length(),i - 1);
          lcd.print(options[value]);
          tempvalue = " "+ options[value];
        } 
        
      }
      
      Serial.println(menu[currentPosition + i].substring(3) + tempvalue);
    }
    Serial.println("----------------");
    
    currentPosition = tempPosition;
    lastLayer = currentLayer;
    lcdUpdated = 1;
    
    /**
    Serial.println("Layer " + String(currentLayer + 1));
    Serial.println("Layer length " + String(currentLength));
    Serial.println("Layer position " + String(currentPosition));
    **/
    
  }
}


void currentValues(){

  Serial.println("Currentpress: " + currentPress);
  
  if(currentType == 1){
      Serial.println("Currentvalue: " + String(value));
      Serial.println("Increments: " + String(numIncr));
      Serial.println("Min: " + String(Min));
      Serial.println("Max: " + String(Max));
      
    } else if(currentType == 2){
      Serial.println("Currentvalue: " + options[value]);
      Serial.println("Options: ");
      
      for (int i=Min; i <= Max; i++){
        Serial.println(options[i]);
      }
    }
}

void clearChar(int charPosition, int line){
  lcd.setCursor (charPosition,line);
  lcd.print(" ");
}

void clearLine(int line){
  lcd.setCursor (0,line);
  lcd.print("                ");
}

void clearMenu(){
  lcd.setCursor (1,0);
  lcd.print("               ");
  lcd.setCursor (1,1);
  lcd.print("               ");
}

void clearSelect(){
  lcd.setCursor (0,0);
  lcd.print(" ");
  lcd.setCursor (0,1);
  lcd.print(" ");
}

void cursorSelect(){
  switch (currentSelect){  // here You choose how you want the cruiser to move in each page, as in to move to each choice
          case 1:
            cursorLayer = 0;
            break;
          case 2:
            cursorLayer = 1;
            break;
          case 3:
            cursorLayer = 0;
            break;
          case 4:
            cursorLayer = 1;
            break;
          case 5:
            cursorLayer = 0;
            break;
          case 6:
            cursorLayer = 1;
            break;
          case 7:
            cursorLayer = 0;
            break;
          case 8:
            cursorLayer = 1;
            break;
          case 9:
            cursorLayer = 0;
            break;
          case 10:
            cursorLayer = 1;
            break;
          case 11:
            cursorLayer = 0;
            break;
          case 12:
            cursorLayer = 1;
            break;
          case 13:
            cursorLayer = 0;
            break;
          case 14:
            cursorLayer = 1;
            break;
          case 15:
            cursorLayer = 0;
            break;
        }
}

void writeCursor(){
  lcd.write(byte(0));
}

void clearValue(){
  for (int i = 16 - valueLength; i <= 16; i++){
        lcd.setCursor (i,cursorLayer);
        lcd.print(" ");
      }
      
  
}

    

After that I uploaded another code, the one below on the Arduino nano. I found a code online that shows how to use I2C communication, and I edited it according to my needs, going back to the previous table, I aasigned the numbers of each group to a certain pin, and added the Y and N (yes and no) as on and off, and they Had the numbers 89 and 78 respectively. I also defined the pins from 2 to 16 as outputs, with each one connected to a certain constellation. This board Is called a slave reciever because it gets the signals from the master, which is the ATmega board with the encoder. Here is the code:

    // Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" ekample for use with this

// Created 29 March 2006

// This ekample code is in the public domain.


#include <Wire.h>
int k;
  int con;
int onoff;

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);
 pinMode(6, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);
 pinMode(9, OUTPUT);
 pinMode(10, OUTPUT);
 pinMode(11, OUTPUT);
 pinMode(12, OUTPUT);
 pinMode(13, OUTPUT);
 pinMode(14, OUTPUT);
 pinMode(15, OUTPUT);
 pinMode(16, OUTPUT);

}

void loop() {
  delay(100);


}

// function that ekecutes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
  char c = Wire.read(); // receive byte as a character
 // Serial.print(c);         // print the character
} 
 int x  = Wire.read();    // receive byte as an integer
//Serial.println(k);         // print the integer

k=x;
test1();
}

 
void test1()
{
  
if ((k >=65 && k<=77 )|| k==79 || k == 80)
{  con = k;
}
else if (k ==89 || k == 78)
{  onoff = k;
}
else
{
  
}


if (con == 65 && onoff == 89)
{ digitalWrite(16, HIGH);
} 

if (con == 65 && onoff == 78)
{ digitalWrite(16, LOW);
} 





if (con == 66 && onoff == 89)
{ digitalWrite(15, HIGH);
} 

if (con == 66 && onoff == 78)
{ digitalWrite(15, LOW);
} 





if (con == 67 && onoff == 89)
{ digitalWrite(14, HIGH);
} 

if (con == 67 && onoff == 78)
{ digitalWrite(14, LOW);
} 



if (con == 68 && onoff == 89)
{ digitalWrite(13, HIGH);
} 

if (con == 68 && onoff == 78)
{ digitalWrite(13, LOW);
} 




if (con == 69 && onoff == 89)
{ digitalWrite(12, HIGH);
} 

if (con == 69 && onoff == 78)
{ digitalWrite(12, LOW);
} 




if (con == 70 && onoff == 89)
{ digitalWrite(11, HIGH);
} 

if (con == 70 && onoff == 78)
{ digitalWrite(11, LOW);
} 




if (con == 71 && onoff == 89)
{ digitalWrite(10, HIGH);
} 

if (con == 71 && onoff == 78)
{ digitalWrite(10, LOW);
} 




if (con == 72 && onoff == 89)
{ digitalWrite(9, HIGH);
} 

if (con == 72 && onoff == 78)
{ digitalWrite(9, LOW);
} 




if (con == 73 && onoff == 89)
{ digitalWrite(8, HIGH);
} 

if (con == 73 && onoff == 78)
{ digitalWrite(8, LOW);
} 




if (con == 74 && onoff == 89)
{ digitalWrite(7, HIGH);
} 

if (con == 74 && onoff == 78)
{ digitalWrite(7, LOW);
} 




if (con == 75 && onoff == 89)
{ digitalWrite(6, HIGH);
} 

if (con == 75 && onoff == 78)
{ digitalWrite(6, LOW);
} 




if (con == 76 && onoff == 89)
{ digitalWrite(5, HIGH);
} 

if (con == 76 && onoff == 78)
{ digitalWrite(5, LOW);
} 



if (con == 77 && onoff == 89)
{ digitalWrite(4, HIGH);
} 

if (con == 77 && onoff == 78)
{ digitalWrite(4, LOW);
} 



if (con == 79 && onoff == 89)
{ digitalWrite(3, HIGH);
} 

if (con == 79 && onoff == 78)
{ digitalWrite(3, LOW);
} 




if (con == 80 && onoff == 89)
{ digitalWrite(2, HIGH);
} 

if (con == 80 && onoff == 78)
{ digitalWrite(2, LOW);
}

Serial.print(con);
Serial.print("                  ");
Serial.println(onoff);
  int con=0;
int onoff=0;
k=0;
}

Unfortunately I couldn't attach the Arduino codes, so you can go ahead and copy/paste them it on Arduino

Step 5: Assembly

Well, I know this is a hot mess, but at least it's hot!


First things first, I used hot silicone gun to put the constellations in place. I used the silicone for 2 reasons, to keep them in place, and to insulated all the conductive parts from the other ones, avoiding any accidents that could happen. after that, I tested each constellation to make sure I didn't break anything in this step.

And I also locked the parts of the encoder and screen in place.

so to recap all, I now have the components in each board, the wires of the LEDs ready, and the encoder/screen case ready to roll.

So, I started with the fixed base, I fixed the slip ring onto it. Then I added the rotating Base and through the middle hole I passed all the wires of the slip ring. on the slip ring, I connected 3 wires to the VCC of the plug on the arduino nano board, and 3 to the GND, and connected the 2 wires of the I2C communication, in addition to a GND and 5V to get to the ATmega board.on the outer side of the base, I connected the 3 positive wires to the cable (the one I'll connect the the wall power source) and also the 3 GND, I connected the 5V and GND to come from the Arduino Nano to the ATmega since it has a built-in regulator. I also connected the I2C from this side.

An attached sketch/diagram show what is connected to what and what goes where, to work as a guide in building the celestial sphere.

After assembling all the components and parts together, there was only one thing left to do: TUCK IT ALL IN! tuck the wires and the arduino board inside the dome, tuck the screen inside the casing, tuck all the wires together with the black tape.

Step 6: Look at It

Tadaaaa! You've made it this far, great job done.

A side note here, You might find it easier to follow the same steps on my FabAcademy website as the pictures there are included as I explain, and the codes and other files are also available.