NRL Satellite (ARDUINO IN SAPCE!)

BIG NEWS!
TLE data is now available!

http://celestrak.com/NORAD/elements/tle-new.txt

35691 ANDE DEB [POLLUX CYL]
35692 ANDE DEB [CASTOR CYL]

35693 ANDE POLLUX SPHERE
35694 ANDE CASTOR SPHERE

Also as promised the code to the g-1000. I... I can't find my Pollux code right now.

#include "EEPROM.h"
#include <avr/io.h>
#include <avr/interrupt.h>

#define LED_ONE     7
#define LED_TWO     6
#define MOTOR_UP    18 
#define MOTOR_DOWN  19
#define MOTOR_LEFT  16
#define MOTOR_RIGHT 17
#define ADC_EL      0
#define ADC_AZ      1

#define RX_BUFFER  256

#define CMD_SEND_POS  'C'
#define CMD_MOVE_ROT  'W'
#define CMD_CANCEL    'S'
#define CMD_RESET     'R'
#define CMD_CAL       'K'

#define CAL_DELAY   2000 //Delay in ms       

byte buff[RX_BUFFER];

typedef struct Cords{
  int az;
  int el;
};

typedef struct Rotor{
  boolean adj;
  Cords pos;
};

Rotor RotorCtrl;

struct AnalogCal { 
  float EL;
  float AZ;
  char   minAz;
  char   minEl;
};

AnalogCal CalConf = {0,0,0,0};
//interrupt stuff
#define MAX_TIMEOUT 17 //About 1 millsecond, enough for 10 bits to be transmited @ 9600 baud 
boolean TIMEOUT = false;
int TIMECOUNT = 0;

boolean valMove() {
 if (buff[1] <= '9' && buff[1] >= '0' && buff[2] <= '9' && buff[2] >= '0' && buff[3] <= '9' && buff[3] >= '0' && buff[5] <= '9' && buff[5] >= '0' && buff[6] <= '9' && buff[6] >= '0' && buff[7] <= '9' && buff[7] >= '0') 
   return true;
  else {
     error("Invalid Move Rotor Command. Syntax: Waaa eee\\r\\n Where aaa is Azimuth 000-450 and eee is Elevation 000-180");
     return false;
  }
} 

void getMovPos(byte *buff, struct Cords *position) {
    position->az = (buff[0]-'0')*100 + (buff[1]-'0')*10 + (buff[2]-'0');
    position->el = (buff[4]-'0')*100 + (buff[5]-'0')*10 + (buff[6]-'0');
}

boolean getPos(struct Cords *position) {
   if (CalConf.AZ == 0 || CalConf.EL == 0) {
      error("Could Not Get Current Rotor Position! Device is not calibrated. Please calibrate.");
      return false;
   }
   unsigned int samples = 0;
   unsigned long az = 0;
   unsigned long el = 0;
   for (samples = 0; samples < 1024; samples++) {
      az +=  analogRead(ADC_AZ);
      el +=  analogRead(ADC_EL);
   }
    position->az = (int)(((az>>10)-CalConf.minAz)*CalConf.AZ);
    position->el = (int)(((el>>10)-CalConf.minEl)*CalConf.EL);
  return true;    
}

void sendPos(){
 Cords pos;
if (getPos(&pos)){
 Serial.print("+0");
 if (pos.az/100 > 0) {
    Serial.print(pos.az,DEC);
 } else if (pos.az/10 > 0) {
    Serial.print("0");
    Serial.print(pos.az,DEC);
 } else {
    Serial.print("00");
    Serial.print(pos.az,DEC); 
 }
 Serial.print("+0");
 if (pos.el/100 > 0) {
    Serial.print(pos.el,DEC);
 } else if (pos.el/10 > 0) {
    Serial.print("0");
    Serial.print(pos.el,DEC);
 } else {
    Serial.print("00");
    Serial.print(pos.el,DEC); 
 }
 Serial.print("\r\n");
} else {
  error("Send Pos: Could not get position info! Is the device Calibrated?");
 }
}


ISR(TIMER2_OVF_vect) {
    if (++TIMECOUNT == MAX_TIMEOUT) { 
      TIMSK2 = 0x00;
      TIMEOUT = true;
      TIMECOUNT = 0;
    }
}

int readSerial(void) {
    //start time out interrupt  
    TIMEOUT = false;
    TIMECOUNT = 0;
    TIMSK2 = _BV(TOIE2);
   
    int count = 0;
    if (Serial.available() > 1) {
       byte newByte = 0;   
       byte oldByte = 0;
       newByte = (char)Serial.read();
       buff[count++] = newByte;
     do {
       if (Serial.available() > 0) {
         oldByte = newByte;
         newByte = (char)Serial.read();
         buff[count++] = newByte;
         TIMECOUNT=0; //reset count for timeout
       }
     }  while (!TIMEOUT && count < RX_BUFFER && !(newByte == '\n' && oldByte == '\r')); 
      if (TIMEOUT || count >= RX_BUFFER) {
         count = 0;
         TIMEOUT = false;
       }
     Serial.flush();
   }
  return count;
}


void error(char *Str) {  
  Serial.print("?>");
  Serial.print(Str);
  Serial.print("\r\n");
}

int oneSample (int pin) {
      int i = 0;
      unsigned long int sample = 0;
      for (i = 0; i < 512; i++) 
            sample += analogRead(pin);
      return sample >> 9;
}

void calibrate(struct AnalogCal * cal) {
      char adjustAz = 2;
      char adjustEl = 2;
      int AzPrev = oneSample(ADC_AZ);
      int ElPrev = oneSample(ADC_EL);
      int Az = -1;
      int El = -1;      
      int Azmin;
        int Elmin;
      //Moving to max range
      while (adjustAz > 0 | adjustEl > 0) {
            if (abs(Az - AzPrev) < 2) { 
                    if (adjustAz == 2) { 
                          Azmin = Az; 
                          adjustAz = 1;
                    } else if (adjustAz == 1) adjustAz = 0;
            } else 
                  AzPrev = Az;

            if (abs(El - ElPrev) < 2) {
                    if (adjustEl == 2) { 
                          Elmin = El; 
                          adjustEl = 1;
                    } else if (adjustEl == 1) adjustEl = 0;
            } else 
                  ElPrev = El;
                  
            //Update motors State :D
                                               
            digitalWrite(MOTOR_RIGHT,adjustAz == 1);
            digitalWrite(MOTOR_UP,adjustEl == 1);
                digitalWrite(MOTOR_LEFT,adjustAz == 2);
            digitalWrite(MOTOR_DOWN,adjustEl == 2);            

            delay(CAL_DELAY); //give some time for the motor to move ^_^
            El = oneSample(ADC_EL);
            Az = oneSample(ADC_AZ);
      }

        if ((El-Elmin) > 180 && (Az-Azmin) > 450) {
          Serial.print("\r"); 
        cal->EL = (float)(180.000/(El-Elmin)); //Our multiplyer to convert sample to angel
        cal->AZ = (float)(450.000/(Az-Azmin)); //Our multiplyer to convert sample to angel
          cal->minEl = Elmin;
          cal->minAz = Azmin;
          save();
        } else {
          error("The Voltage Range On the g-5500 is way too low! Please read the manual to learn how to adjust the Output Voltage.");
          cal->EL = 0;
          cal->AZ = 0;
          save();
        }
    }

void moveTo(struct Rotor *rotor) {
  digitalWrite(13,HIGH);
   Cords pos;
   if (getPos(&pos)) {
     digitalWrite(MOTOR_UP, (pos.el < rotor->pos.el && abs(pos.el-rotor->pos.el) > 1 && rotor->pos.el > -1));
     digitalWrite(MOTOR_DOWN, (pos.el > rotor->pos.el && abs(pos.el-rotor->pos.el) > 1 && rotor->pos.el > -1));
     digitalWrite(MOTOR_LEFT, (pos.az > rotor->pos.az && abs(pos.az-rotor->pos.az) > 1 && rotor->pos.az > -1));
     digitalWrite(MOTOR_RIGHT, (pos.az < rotor->pos.az && abs(pos.az-rotor->pos.az) > 1 &&rotor->pos.az > -1));
     digitalWrite(LED_ONE,rotor->pos.el>-1); 
     digitalWrite(LED_TWO,rotor->pos.az>-1);
   
     if (pos.el == rotor->pos.el)
           rotor->pos.el = -1;
     if (pos.az == rotor->pos.az)
           rotor->pos.az = -1;
     if (rotor->pos.az < 0 && rotor->pos.el < 0) {
        rotor->adj = false;
     }
   } else {
      error("Move Rotors: Can not Get Current Position! Is the device calibrated?");
      rotor->adj = false;
   }
}


void load() {
  byte *ptr;
  ptr = (byte*)(void*) &CalConf;
  int i = 0;
  for (i = 0; i < sizeof(CalConf); i++) 
     ptr[i] = EEPROM.read(i);

}

void save() {
  byte *ptr;
  ptr = (byte*)(void*) &CalConf;
  int i = 0;
  for (i = 0; i < sizeof(CalConf); i++) {
     EEPROM.write(i,ptr[i]);
   } 
}


void setup() {
 Serial.begin(9600);
 pinMode(LED_ONE,OUTPUT);
 pinMode(LED_TWO,OUTPUT);
 pinMode(MOTOR_UP,OUTPUT);
 pinMode(MOTOR_DOWN,OUTPUT);
 pinMode(MOTOR_LEFT,OUTPUT);
 pinMode(MOTOR_RIGHT,OUTPUT);
 //setup interupts
 TCCR2A = 0x00;
 TCCR2B = (_BV(CS22) | _BV(CS20));
 load();
 }

int read = 0;

void loop() {
  read = readSerial();


 if (read > 0 ) {
   switch (buff[0]) {
    case CMD_CAL:
        calibrate(&CalConf);
        break;
    case CMD_SEND_POS:
        sendPos();
        break;    
    case CMD_CANCEL:
        RotorCtrl.adj = false;
        break;    
    case CMD_RESET:
        load();
        RotorCtrl.adj = false;
        break;
    case CMD_MOVE_ROT:
        if (read == 10) {
           if (valMove()) {
             getMovPos(buff+1,&RotorCtrl.pos);
             if (RotorCtrl.pos.az > 450 || RotorCtrl.pos.el > 180) {
               error("Move Rotor Out Of Range! Azimuth is 0-450 and Elevation is 0-180");
             } else {
               Serial.print("\r");
               RotorCtrl.adj = true;
             }
           }
        } else {
           error("Invalid Move Rotor Command. Syntax: Waaa eee\\r\\n Where aaa is Azimuth 000-450 and eee is Elevation 000-180");
        }
        break;    
    default:
        error("No Such command!");
        break;
     } 
 }
 // End of Serial 
  if (RotorCtrl.adj) moveTo(&RotorCtrl);
  else {                        
    digitalWrite(13, LOW);          
    digitalWrite(MOTOR_UP, LOW);    
    digitalWrite(MOTOR_DOWN, LOW);  
    digitalWrite(MOTOR_LEFT, LOW);   
    digitalWrite(MOTOR_RIGHT, LOW);
    digitalWrite(LED_ONE, LOW);      
    digitalWrite(LED_TWO, LOW);
  } 
}

Feel free to critique the code