Monday, January 10, 2011

Week 2

Well after a little hiatus with Christmas holidays and then getting back into the swing of working full time again I was able to finally sit down and nail out some more of the intricacies of the Attitude Sensor project.

For week 2 I continued to test the hardware I have on hand and then try to interface everything via code and hardwiring.Im glad to say that I am about 75% of the way done with the selected parts. I had some problems with the CHR-6dm sensor and reinitializing it so it has been sent back to manufacturer for reprogramming. Seems like the problem was on my end with a faulty usb - serial adapter. So while I wait for the unit to come back to me I have a Sparkfun 5DOF board to play with and try to convert accelerometer data to angular pitch roll data. After A LOT of reading and searching I have found code that does exactly what I need. I'm confident I could have figured it out but it would have taken months to get to a point where I would be confident with the numbers I am getting. I would like to thank the Arduino forum for this because without it I would be lost. the code can be found at http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1286541868 for anyone looking or interested.

My next problem is to take the code for polling GPS data and combine it with the accelerometer code to get 2 solid strings output to my Logomatic Datalogger. The code for the GPS searches for a GPRMC string and then parses the data out to the serial line. The problem I am having is that for every character parsed the accelerometer data is posted so I end up with nonsense data for gps and current pitch roll data. If I insert the pitch roll code into the GPS parser then I end up with current GPS data and lagging pitch roll data because I am only interested in acquiring data every 1s and not continuous. Here is my code to date.... Feel free to read over and tear apart.


#include <string.h>
#include <ctype.h>
#include <math.h>

#define xAcc 0
#define yAcc 1
#define zAcc 2
#define xGyro 4
#define yGyro 5
#define vRef 3.3
#define sen 0.330
#define gSen 0.002
#define gyroZero 1.350


int x0,y0,z1,gx0,gy0,gz0; //x0,y0,z0 is x,y,z axis zero G  ADC value gx0,gy0 no rotation ADC values
float xAngle,yAngle,xAtan,yAtan,zAngle,dxAngle,dyAngle =0;
unsigned long time,dt = 0;

int ledPin = 13;                  // LED test pin
int rxPin = 0;                    // RX PIN
int txPin = 1;                    // TX TX
int byteGPS=-1;
char linea[300] = "";
char comandoGPR[7] = "$GPRMC";
int count=0;
int counta=0;
int countb=0;
int index[13];
const int xpin = A0;                  // x-axis of the accelerometer
const int ypin = A1;                  // y-axis
const int zpin = A2;                  // z-axis (only on 3-axis models)
const int xRate = A4;
const int yRate = A5;
 
 void setup() {
   pinMode(ledPin, OUTPUT);       // Initialize LED pin
   pinMode(rxPin, INPUT);
   pinMode(txPin, OUTPUT);
   Serial.begin(38400);
   delay(1000);
   getZeros();
   for (int i=0;i<300;i++){       // Initialize a buffer for received data
     linea[i]=' ';
   }  
 }

 void getZeros()
  {
  x0=analogRead(xAcc);
  y0=analogRead(yAcc);
  z1=analogRead(zAcc);
  gx0=analogRead(xGyro);
  gy0=analogRead(yGyro);
  }

 void loop() {
   digitalWrite(ledPin, HIGH);
   byteGPS=Serial.read();         // Read a byte of the serial port
   if (byteGPS == -1) {           // See if the port is empty yet
     delay(1000);
   } else {
     linea[counta]=byteGPS;        // If there is serial port data, it is put in the buffer
     counta++;                    
     Serial.print(byteGPS, BYTE);
     if (byteGPS==13){            // If the received byte is = to 13, end of transmission
       digitalWrite(ledPin, LOW);
       count=0;
       countb=0;
       for (int i=1;i<7;i++){     // Verifies if the received command starts with $GPR
         if (linea[i]==comandoGPR[i-1]){
           countb++;
         }
       }
       if(countb==6){               // If yes, continue and process the data
         for (int i=0;i<300;i++){
           if (linea[i]==','){    // check for the position of the  "," separator
             index[count]=i;
             count++;
           }
           if (linea[i]=='*'){    // ... and the "*"
             index[12]=i;
             count++;
           }
         }
         Serial.println("");
         Serial.print("$CTAH,");
         Serial.print("xpin,");
         Serial.print(analogRead(xpin));
         Serial.print(",");
         Serial.print("ypin,");
         Serial.print(analogRead(ypin));
         Serial.print(",");
         Serial.print("zpin,");
         Serial.print(analogRead(zpin));
         Serial.print(",");                    
         Serial.print(analogRead(xRate), DEC);
         Serial.print(",");
         Serial.print(analogRead(yRate), DEC);
         Serial.println();
         Serial.print("Roll");
         Serial.print("\t");
         Serial.print("Pitch");
         Serial.println();
         GetPR();          
       }
       counta=0;                    // Reset the buffer
       for (int i=0;i<300;i++){    //
         linea[i]=' ';            
       }                
     }
   }
 }

 void GetPR()
   {
    //******************** CF filter******************************************************************
    time=millis();
    xAtan=atan2((analogRead(xAcc)-x0)*vRef/(1024*sen),(analogRead(zAcc)-z1)*vRef/(1024*sen)+1)*180/PI;
    yAtan=atan2((analogRead(yAcc)-y0)*vRef/(1024*sen),(analogRead(zAcc)-z1)*vRef/(1024*sen)+1)*180/PI;

    dxAngle=(analogRead(yGyro)-gy0)*vRef/(1024*gSen);
    dyAngle=(analogRead(xGyro)-gx0)*vRef/(1024*gSen);
    xAngle = 0.9615 * (xAngle + dxAngle*dt*0.001) + 0.0385*xAtan;
    yAngle =0.9615 * (yAngle + dyAngle*dt*0.001) + (0.0385 *yAtan);

    //0.9615 is a and its given by a=tau/(tau-dt), 0.0385=1-a
    // dt is 1-2 ms

    //************************************************************************************************
    Serial.print(xAngle);
    Serial.print("\t");
    Serial.print(yAngle);
    Serial.print("\t");
    Serial.println(dt);
    dt=millis()-time;  
    }