Monday, October 5, 2009

Here Comes The Sun: Processing Code

As promised, though a little late, here is the Processing code.

// The Import Libraries
import netscape.javascript.*;
import java.util.Calendar.*;
import java.lang.Math.*;
import processing.serial.*;

// Variables Galore
int Hour = hour();
int Min = minute();
int Sec = second();
int doy = 0;
float latitude = (float)Math.toRadians(42.220); // Ann Arbor
float longitude = 83.75; // Ann Arbor
float YrFract = 0;
float eqtime = 0;
float decl = 0;
float time_offset = 0;
float tst = 0;
float ha = 0;
float za = 0;
float azim = 0;
float alt = 0;
int azimswitch=0;

int spos=0;
int wpos=0;

Serial port; // The serial port

void setup()
{
port = new Serial(this, Serial.list()[0], 9600); // Open the serial port.
azimswitch=0; // Make sure the switch is zeroed.
}

void draw()
{
Calendar cal = Calendar.getInstance();
doy = cal.get(Calendar.DAY_OF_YEAR);
Hour = hour();
Min = minute();
Sec = second();
YrFract = 2*PI/365*(doy-1+(Hour-12)/24); // Fractional Year, Radians
eqtime = 229.18*(0.000075+0.001868*cos(YrFract)-0.032077*sin(YrFract)-0.014615*cos(2*YrFract)-0.040849*sin(2*YrFract)); // Equation of Time, Minutes
decl = 0.006918-0.399912*cos(YrFract)+0.070257*sin(YrFract)-0.006758*cos(2*YrFract)+0.000907*sin(2*YrFract)-0.002697*cos(3*YrFract)+0.00148*sin(3*YrFract); // Declination, Radians
time_offset = eqtime-4*longitude+60*5; // Solar Time Offset, Minutes
tst = Hour*60+Min+Sec/60+time_offset; // True Solar Time, Minutes
ha = (float)Math.toRadians((tst/4)-180); // Solar Hour Angle, Radians
za = acos(sin(latitude)*sin(decl)+cos(latitude)*cos(decl)*cos(ha)); // Zenith Angle, Radians
azim = acos(-(sin(latitude)*cos(za)-sin(decl))/(cos(latitude)*sin(za))); // Azimuth, Radians, Clockwise from North
azim = (int)(float)Math.toDegrees(azim);

// Utilize a switching process to determine if it is before or after zenith.
if (azimswitch==0){
azim = azim - 90;
}
else if (azimswitch==1){
azim = 270 - azim;
}

// Change switch when necessary.
if ((int)azim==90){
azimswitch = 1;
}
else if ((int)azim==180){
azimswitch = 0;
}

alt = (float)(Math.toDegrees(za)); // Calculate altitude from Zenith Angle

// Print out to check whether or not calculations are correct.
println(alt);
println(azim);
println(azimswitch);

// Stop the machine from turning too far.
if((int)azim < azim =" 0;"> 180){
azim = 180;
}

alt = alt/2; // Mirror-aiming correction

update((int)alt,180-(int)azim); // Run the update to write to the servo.

delay(1000); // Only read once a second.
}

void update(int spos, int wpos)
{
//Output the servo position ( from 0 to 180)
port.write(spos+"s");
port.write(wpos+"w");
}
Took awhile to write, but it works well. I also had a gimmicky little touchpad controller code:

/**
* Servocontrol (derived from processing Mouse 1D example.)
*
* Updated 24 November 2007
*/


// Use the included processing code serial library
import processing.serial.*;


int gx = 15;
int gy = 35;
int spos=90;
int wpos=90;

float leftColor = 0.0;
float rightColor = 0.0;
Serial port; // The serial port



void setup()
{
size(720, 720);
colorMode(RGB, 1.0);
noStroke();
rectMode(CENTER);
frameRate(100);

println(Serial.list()); // List COM-ports

//select second com-port from the list
port = new Serial(this, Serial.list()[0], 9600);
}

void draw()
{
background(0.0);
update(mouseX,mouseY);
fill(mouseX/4);
rect(150, 320, gx*2, gx*2);
fill(180 - (mouseX/4));
rect(450, 320, gy*2, gy*2);
}

void update(int x, int y)
{
//Calculate servo postion from mouseX
spos= x/4;
wpos= y/4;

//Output the servo position ( from 0 to 180)
port.write(spos+"s");
port.write(wpos+"w");
// Just some graphics
leftColor = -0.002 * x/2 + 0.06;
rightColor = 0.002 * x/2 + 0.06;

gx = x/2;
gy = 100-x/2;

}
I'll post information on the two-week project soon.

No comments:

Post a Comment