Thursday, October 1, 2009

Here Comes The Sun

Our team project for the week was to design and implement a modular, scalable solar tracker.

The project started out the same way that last week's project did - I stepped into coding like it is my true calling or something. The sun follows a path defined by two variables - azimuth and altitude. Therefore, we developed a design very similar to the design that Eric's group and my group both utilized last week, with two axes - rotation and tilt. We chose to utilize the base scheme that his group developed, as it was much more stable and easier to work with for this implementation.

The Arduino code for our project is as follows:

#include
#include

Servo servo1; Servo servo2;
Potentiometer potentiometer1 = Potentiometer(3);
Potentiometer potentiometer2 = Potentiometer(4);

void setup() {
servo1.attach(9);
servo2.attach(10);
pinMode(13,OUTPUT);
Serial.begin(9600);
Serial.println("Ready");
potentiometer1.setSectors(180);
potentiometer2.setSectors(180);
}

void loop() {

static int v = 0;
if (Serial.available()) {
char ch = Serial.read();

switch(ch) {
case '0'...'9':
v = v * 10 + ch - '0';
digitalWrite(13,LOW);
break;
case 's':
servo1.write(v);
v = 0;
break;
case 'w':
servo2.write(v);
v = 0;
break;
case 'p':
do{
servo1.write(potentiometer1.getSector());
servo2.write(potentiometer2.getSector());
digitalWrite(13,HIGH);
}
while(Serial.read()!='i');
break;
}
}
}

It allows for both serial input and potentiometer utilization to control the servos. Really quite simple, but it does so much. I prefer to have the Arduino as simple as possible whenever possible, and to utilize the computer to do any real processing and calculations. Therefore, the remainder of the code was written in Processing. Here is a snippet from the Processing code.

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

This code is the calculation for solar position, given inputs (doy is day of year, the rest is fairly self-explanatory). The azimuth is always positive, so a switch in the code must be utilized to switch between rising and setting. I'll post the full code on Friday morning at the start of class, it's not 100% yet.

I feel like this team has meshed the best out of all the teams that I have worked with so far. Neil and I worked on the electronics portion, and we work very well together. The design process was universal, with everyone inputting, but the implementation process essentially was niche, with engineers doing circuitry and coding, architects doing Schmigital Schmroject and some construction, and artists doing construction. Overall, the project has worked really well, and I look forward to the final result.

No comments:

Post a Comment