Virtual Planets Meet Actual Planets

For the assignment of connecting Processing to Arduino I decided to use the Solar System I created in Processing two weeks ago and also create a physical model of it by using LEDs as outputs. I stopped the rotating motion of the planets and aligned them in one line in Processing and created a similar model in real space. Once you click on a planet in Processing, the appropriate planet lights up in my model. This is what I did to create my project:

  1. I did some alterations in my Processing sketch so that the initial view of the planets would be different than before and I also took away their speed. Because they are now on the same line, I determined the X-coordinates for each of the planet, therefore I could divide the screen in parts and make the appropriate LED in my model light up.
  1. In Arduino I set 8 LEDs as outputs, each representing one of the Solar System’s planets. The logic behind my project is that when the mouse is pressed on one of the planets, the respective LED lights up. However, when the mouse is pressed again, the LED turns off, therefore you can control which planets you want to light up and which ones you don’t.
  1. As for my actual model I created a cardboard base with a starry night sky base and glued on 8 planets and the Sun. Each of the LEDs is pierced through each planet. There is also the name of each planet next to it, as well as the information about its size in the Solar System. The whole construction is standing on two awesome tapes that I found in the IM lab!

The code in Processing:

import processing.serial.*;
import peasy.*;
Serial myPort;
PeasyCam cam;

int led2=0;
int led3=0;
int led4=0;
int led5=0;
int led6=0;
int led7=0;
int led8=0;
int led9=0;


Planet earth;
Planet mercury;
Planet venus;
Planet mars;
Planet jupiter;
Planet saturn;
Planet uranus;
Planet neptune;
Planet sun;
Planet moon;

boolean orbitSwitch = true;
boolean moonSwitch=true;


void setup() {
 String portname = Serial.list()[2];
 myPort = new Serial(this, portname, 9600);
 myPort.clear();
 myPort.bufferUntil('\n');
 size(1280, 720, P3D);
 float fov = PI/3.0;
 float aspect=float(width)/float(height);
 perspective(fov, aspect, height, 0);
 cam = new PeasyCam(this, 200);
 cam.setMinimumDistance(50);
 cam.setMaximumDistance(5000);



 earth = new Planet(70, "earth.jpg", 6, 0);
 mercury = new Planet(30, "pl_mercury.jpg", 5, 0);
 venus = new Planet(50, "ven0aaa2.jpg", 6, 0);
 mars = new Planet(85, "2k_mars.jpg", 6, 0);
 jupiter = new Planet (110, "Jupiter.jpg", 12, 0);
 saturn = new Planet (140, "2k_saturn.jpg", 10, 0);
 uranus = new Planet (165, "2k_uranus.jpg", 8, 0);
 neptune = new Planet (190, "preview_neptune.jpg", 8, 0);
 sun = new Planet (0, "texture_sun.jpg", 11, 0);
 moon = new Planet (60, "moon.jpg", 2, 0);
}

void draw() {
 background(0);
 if(mousePressed){
 if (mouseX>700 && mouseX<=750)
 if (led2==0)
 led2=1;
 else led2=0;


 if (mouseX>750 && mouseX<=850)
 if (led3==0)
 led3=1;
 else led3=0;

 if (mouseX>850 && mouseX<=900)
 if (led4==0)
 led4=1;
 else led4=0;

 if (mouseX>900 && mouseX<=950)
 if (led5==0)
 led5=1;
 else led5=0;

 if (mouseX>950 && mouseX<=1050)
 if (led6==0)
 led6=1;
 else led6=0;


 if (mouseX>1050 && mouseX<=1100)
 if (led7==0)
 led7=1;
 else led7=0;


 if (mouseX>1100 && mouseX<=1150)
 if (led8==0)
 led8=1;
 else led8=0;

 if (mouseX>1200 && mouseX<=1280)
 if (led9==0)
 led9=1;
 else led9=0;
}

//planet
earth.planet();
mercury.planet();
venus.planet();
mars.planet();
jupiter.planet();
saturn.planet();
uranus.planet(); 
neptune.planet();
sun.planet();

//orbit circles
if (orbitSwitch==true) {
 earth.orbit();
 mercury.orbit();
 venus.orbit();
 mars.orbit();
 jupiter.orbit();
 saturn.orbit();
 uranus.orbit();
 neptune.orbit();
}

//moon
if (moonSwitch==true) {
 moon.planet();
}

}

void serialEvent(Serial myPort) {
 myPort.write(led2+","+led3+","+led4+","+led5+","+led6+","+led7+","+led8+","+led9+"\n");
}

void keyPressed() {
 if (key=='o') {
 orbitSwitch=!orbitSwitch;
 }

 if (key=='m') {
 moonSwitch=!moonSwitch;
 }
}

class Planet {
 int orbit;
 float x, z;
 PImage img;
 int planetSize;
 float angle;
 float speed;
 int numPointsW;
 int numPointsH_2pi; 
 int numPointsH;

float[] coorX;
float[] coorY;
float[] coorZ;
float[] multXZ;
 
 Planet(int _orbit, String _imageName, int _planetSize, float _speed){
 orbit=_orbit;
 x=0;
 z=0;
 img = loadImage(_imageName);
 planetSize=_planetSize;
 angle=0.;
 speed=_speed;
 initializeSphere(30,30);
 }
 
 
 void planet(){
 //planet
 pushMatrix();
 x = cos(angle)*orbit;
 z = sin(angle)*(orbit+7);
 translate(x,0,z);
 noStroke();
 textureSphere(planetSize, planetSize, planetSize, img);
 popMatrix();
 angle+=speed;
 }
 
 void orbit() {
 stroke(255,120);
 noFill();
 pushMatrix();
 rotateX(radians(90));
 ellipseMode(CENTER);
 ellipse(width/2, height/2, orbit*2, orbit*2+14);
 popMatrix();
 
 
 }
 
 void initializeSphere(int numPtsW, int numPtsH_2pi) {

 // The number of points around the width and height
 numPointsW=numPtsW+1;
 numPointsH_2pi=numPtsH_2pi; // How many actual pts around the sphere (not just from top to bottom)
 numPointsH=ceil((float)numPointsH_2pi/2)+1; // How many pts from top to bottom (abs(....) b/c of the possibility of an odd numPointsH_2pi)

 coorX=new float[numPointsW]; // All the x-coor in a horizontal circle radius 1
 coorY=new float[numPointsH]; // All the y-coor in a vertical circle radius 1
 coorZ=new float[numPointsW]; // All the z-coor in a horizontal circle radius 1
 multXZ=new float[numPointsH]; // The radius of each horizontal circle (that you will multiply with coorX and coorZ)

 for (int i=0; i<numPointsW ;i++) { // For all the points around the width
 float thetaW=i*2*PI/(numPointsW-1);
 coorX[i]=sin(thetaW);
 coorZ[i]=cos(thetaW);
 }
 
 for (int i=0; i<numPointsH; i++) { // For all points from top to bottom
 if (int(numPointsH_2pi/2) != (float)numPointsH_2pi/2 && i==numPointsH-1) { // If the numPointsH_2pi is odd and it is at the last pt
 float thetaH=(i-1)*2*PI/(numPointsH_2pi);
 coorY[i]=cos(PI+thetaH); 
 multXZ[i]=0;
 } 
 else {
 //The numPointsH_2pi and 2 below allows there to be a flat bottom if the numPointsH is odd
 float thetaH=i*2*PI/(numPointsH_2pi);

 //PI+ below makes the top always the point instead of the bottom.
 coorY[i]=cos(PI+thetaH); 
 multXZ[i]=sin(thetaH);
 }
 }
}

void textureSphere(float rx, float ry, float rz, PImage t) { 
 // These are so we can map certain parts of the image on to the shape 
 float changeU=t.width/(float)(numPointsW-1); 
 float changeV=t.height/(float)(numPointsH-1); 
 float u=0; // Width variable for the texture
 float v=0; // Height variable for the texture

 beginShape(TRIANGLE_STRIP);
 texture(t);
 for (int i=0; i<(numPointsH-1); i++) { // For all the rings but top and bottom
 // Goes into the array here instead of loop to save time
 float coory=coorY[i];
 float cooryPlus=coorY[i+1];

 float multxz=multXZ[i];
 float multxzPlus=multXZ[i+1];

 for (int j=0; j<numPointsW; j++) { // For all the pts in the ring
 normal(-coorX[j]*multxz, -coory, -coorZ[j]*multxz);
 vertex(coorX[j]*multxz*rx, coory*ry, coorZ[j]*multxz*rz, u, v);
 normal(-coorX[j]*multxzPlus, -cooryPlus, -coorZ[j]*multxzPlus);
 vertex(coorX[j]*multxzPlus*rx, cooryPlus*ry, coorZ[j]*multxzPlus*rz, u, v+changeV);
 u+=changeU;
 }
 v+=changeV;
 u=0;
 }
 endShape();
}
}

The code in Arduino:

int ledPin2 = 3;
int ledPin3 = 4;
int ledPin4 = 5;
int ledPin5 = 6;
int ledPin6 = 7;
int ledPin7 = 8;
int ledPin8 = 9;
int ledPin9 = 10;

void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);
 Serial.println("0,0");
 pinMode(ledPin2, OUTPUT);
 pinMode(ledPin3, OUTPUT);
 pinMode(ledPin4, OUTPUT);
 pinMode(ledPin5, OUTPUT);
 pinMode(ledPin6, OUTPUT);
 pinMode(ledPin7, OUTPUT);
 pinMode(ledPin8, OUTPUT);
 pinMode(ledPin9, OUTPUT);
}

void loop() {
 // put your main code here, to run repeatedly:
 while (Serial.available() > 0) {
 int input2 = Serial.parseInt();
 int input3 = Serial.parseInt();
 int input4 = Serial.parseInt();
 int input5 = Serial.parseInt();
 int input6 = Serial.parseInt();
 int input7 = Serial.parseInt();
 int input8 = Serial.parseInt();
 int input9 = Serial.parseInt();
 if (Serial.read() == '\n') {


 if (input2 == 1) {
 digitalWrite(ledPin2, HIGH);
 }

 if (input2 == 0) {
 digitalWrite(ledPin2, LOW);
 }
 if (input3 == 1) {
 digitalWrite(ledPin3, HIGH);
 }

 if (input3 == 0) {
 digitalWrite(ledPin3, LOW);
 }
 if (input4 == 1) {
 digitalWrite(ledPin4, HIGH);
 }

 if (input4 == 0) {
 digitalWrite(ledPin4, LOW);
 }
 if (input5 == 1) {
 digitalWrite(ledPin5, HIGH);
 }

 if (input5 == 0) {
 digitalWrite(ledPin5, LOW);
 }
 if (input6 == 1) {
 digitalWrite(ledPin6, HIGH);
 }

 if (input6 == 0) {
 digitalWrite(ledPin6, LOW);
 }
 if (input7 == 1) {
 digitalWrite(ledPin7, HIGH);
 }

 if (input7 == 0) {
 digitalWrite(ledPin7, LOW);
 }
 if (input8 == 1) {
 digitalWrite(ledPin8, HIGH);
 }

 if (input8 == 0) {
 digitalWrite(ledPin8, LOW);
 }
 if (input9 == 1) {
 digitalWrite(ledPin9, HIGH);
 }

 if (input9 == 0) {
 digitalWrite(ledPin9, LOW);
 }
 }
 }
}

Some pictures:

all of the planets are on
the virtual planets meet the actual planets (and the tapes!!)

the labels

Here are 2 videos of me turning the LEDs in the planets on and off: