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