Go Down

Topic: NRL Satellite (ARDUINO IN SAPCE!) (Read 13584 times) previous topic - next topic

Shutter

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.

Code: [Select]
#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

Shutter

#76
Aug 19, 2009, 05:12 pm Last Edit: Aug 19, 2009, 05:15 pm by Shutter Reason: 1
So anyone able to track castor or pollux yet?

the TLE is here:
http://celestrak.com/NORAD/elements/amateur.txt

armadillo

btw shutter, i just found this:

http://www.uk.amsat.org/index.php?option=com_content&task=view&id=254&Itemid=86

while looking for rotators and interfaces.

you mention on a previous post that you where coding the software to control your design... or, am i wrong and you will simply use software like gpredict, WXtrack, etc... ?

regards,
/a

Shutter

Well, yes i have seen that design before. In fact we own one. IT is big and kinda poorly designed.
My code for the g-1000 is done and posted, tough i need to add some safety code. We burnt out a motor when it got stuck so i need to add a time out.

We are about ready to release the g-1000, I can't wait

Anyone able to talk to castor or pollux here?

armadillo

About Castor and Pollux..

Just tried with castor on this downlink 145.825 MHz but got nothing, im using a good LNA and a cross dipole turnstyle antenna with which i can get good signals from the NOAA's or the ISS.

I guess it will help if i use an arrow antenna and do some tracking.

I will like to get one of your g-1000, could you help me get one?

/a

Shutter

We have been having problems with Castor, We will check it with our antenna on the next pass. It could be dead, but we also have had trouble with the antenna design. Instruments inside are messing up the signals.

We are going to do the production run for the g-1000 soon. Ill tell you when it is available.

For now you will have better luck with Pollux.

armadillo

cool, put me on the list for the g-1000.

just had a second go to Castor and got nothing, im actually switching antennas trying to get some action on the support networks for sts-128, that is 259700.. but it was also silent.

will try pollux on the next pass, AOS in 65min.

kg4wsv

We were setting up our ground station yesterday, and Pollux was the first satellite we heard (although we didn't have enough equipment hooked up to decode it).

-j

Shutter

Thats Awesome!

Hey Guys! High Res Photos are available here!
https://goby.nrl.navy.mil/ANDE/Photos.html

The_Bongmaster

firefox is showing up "untrusted link" at that address :s
B-dui in creation.

Shutter

#85
Sep 17, 2009, 08:59 pm Last Edit: Sep 17, 2009, 09:00 pm by Shutter Reason: 1
http://goby.nrl.navy.mil/ANDE/Photos.html

Yea they don't have proper certificates. Don;t worry about it, your not sending any sensitive information are you?a
It is just not a properly signed cert.

Shutter

GOOD NEWS![/b[
The Goldberg-1000 is ready to be produced!
We found one problem with the code and have fixed it, we forgot to add an auto-stop if the rotor gets caught!
With this added and our months of testing, we feel it is time to release it!

Here is the RTM board:



Thanks for all of those tracking Pollux and Castor!
If you have any questions please ask!

I have some graphs of the data if you are interested.  

chuckularone

#87
Mar 16, 2010, 07:53 pm Last Edit: Mar 16, 2010, 09:25 pm by chuckularone Reason: 1
Are either of them still up and running?

EDIT:
Never mind.  I answered my own question.
http://www.amsat.org/amsat-new/satellites/satInfo.php?satID=122&retURL=/satellites/status.php

majolsurf

Hi guys, sorry I'm late to the party...

Was anyone able to collect telemetry data from either satellite?  How current are the TLE's?  It looks like Pollux is decayed and Castor is still up...  

majolsurf

Oops sorry looks like the TLE's for Castor are as recent as yesterday...

1 35694U 09038F   10134.16770768  .00062420  12905-4  14304-3 0  3723
2 35694 051.6379 021.6508 0003600 098.6805 261.4610 15.97612265 45617

But no more Pollux?   :(

Go Up