Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. #include "Wire.h"
  2. #include "SD.h"
  3. #include "Adafruit_BMP085.h"
  4. #include "leonardo_GPS.h"
  5. #include "ServoTimer2.h"
  6. #include "VirtualWire.h"
  7.  
  8. ServoTimer2 chute;
  9.  
  10. //sdcard
  11. const int SDSelect = 8;
  12.  
  13. //GPS shit
  14. leonardo_GPS GPS(&Serial1);
  15. #define GPSECHO  true
  16. boolean usingInterrupt = false;
  17. void useInterrupt(boolean);
  18. int locked;
  19. String lat, lon;
  20.  
  21. //mostly Altimeter shit
  22. Adafruit_BMP085 bmp;
  23. int ground;
  24. int alti, altf, apogee;
  25. int ti, tf;
  26. int vinit, velocity, vmax;
  27. boolean dep = false;
  28.  
  29. //shit for the radio
  30. char temp[20];
  31.  
  32.  
  33. void setup() {
  34.   vw_set_tx_pin(5);
  35.   vw_setup(1200);    // Bits per sec for radio
  36.   chute.attach(9);
  37.   chute.write(0);
  38.   chute.detach();
  39.   //init sd
  40.   pinMode(SDSelect, OUTPUT);
  41.   pinMode(10, OUTPUT);
  42.   SD.begin(SDSelect);
  43.  
  44.   //init radio
  45.   pinMode(4,OUTPUT);
  46.   pinMode(5,OUTPUT);
  47.   pinMode(6,OUTPUT);
  48.   pinMode(7,OUTPUT);
  49.  
  50.   bmp.begin();
  51.   ground=3.28084*bmp.readAltitude(); //get ground level altitude. We do this so we don't have to actually set the altimeter seperately with SLP. calculated at a temperature of 15c
  52.  
  53.   //set up the GPS
  54.   GPS.begin(9600);
  55.   GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  56.   GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  57.   GPS.sendCommand(PGCMD_ANTENNA);
  58.   useInterrupt(true);
  59.   delay(1000);
  60.   Serial1.println(PMTK_Q_RELEASE);
  61.   tx_data("BOOT");
  62. }
  63.  
  64. // Interrupt is called once a millisecond, looks for any new GPS data, and stores it
  65. SIGNAL(TIMER0_COMPA_vect) {
  66.   char c = GPS.read();
  67.   // if you want to debug, this is a good time to do it!
  68. #ifdef UDR0
  69.   if (GPSECHO)
  70.     if (c) UDR0 = c;  
  71.     // writing direct to UDR0 is much much faster than Serial.print
  72.     // but only one character can be written at a time.
  73. #endif
  74. }
  75.  
  76. void useInterrupt(boolean v) {
  77.   if (v) {
  78.     // Timer0 is already used for millis() - we'll just interrupt somewhere
  79.     // in the middle and call the "Compare A" function above
  80.     OCR0A = 0xAF;
  81.     TIMSK0 |= _BV(OCIE0A);
  82.     usingInterrupt = true;
  83.   } else {
  84.     // do not call the interrupt function COMPA anymore
  85.     TIMSK0 &= ~_BV(OCIE0A);
  86.     usingInterrupt = false;
  87.   }
  88. }
  89. uint32_t timer = millis();
  90. int time = millis();
  91.  
  92. void loop() {
  93.   String transmit = "";
  94.   String tempstr = "";
  95.  
  96.  if (! usingInterrupt) {
  97.     // read data from the GPS in the 'main loop'
  98.     char c = GPS.read(); // if you want to debug, this is a good time to do it!
  99.     if (GPSECHO);
  100.   }
  101.  
  102.   // if a sentence is received, we can check the checksum, parse it...
  103.   if (GPS.newNMEAreceived()) {
  104.     // a tricky thing here is if we print the NMEA sentence, or data
  105.     // we end up not listening and catching other sentences!
  106.     // so be very wary if using OUTPUT_ALLDATA and trytng to print out data
  107.     //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
  108.  
  109.     if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
  110.       return;  // we can fail to parse a sentence in which case we should just wait for another
  111.   }
  112.   // if millis() or timer wraps around, we'll just reset it
  113.   if (timer > millis())  timer = millis();
  114.  
  115.   // approximately every 2 seconds or so, print out the current stats
  116.   if (millis() - timer > 2000) {
  117.     timer = millis(); // reset the timer
  118.    
  119.     if (GPS.fix) {
  120.       digitalWrite(13, LOW);
  121.       lat = GPS.latitude;
  122.       lon = GPS.longitude;
  123.     }
  124.     else {
  125.       digitalWrite(13, HIGH);
  126.       tx_data("SIGNAL LOST");
  127.     }
  128.   }
  129.   tf = ti; //needed for velocity calculation
  130.   ti = time; //get time since boot from the timer - real time is not needed since we are only
  131.              //interested in current flight
  132.     // Calculate altitude assuming 'standard' barometric
  133.     // pressure of 1013.25 millibar = 101325 Pascal
  134.     //calculate altitude AGL, in feet to increase resolution, so we can safely ignore the decimals of
  135.     //a meter and still have accurate enough altitude data without using a floating point number.
  136.     alti = altf; //make the initial alt equal to the alt last recorded, so we store it for comparison
  137.     altf = 3.28084*bmp.readAltitude(); //convert alt to ft
  138.     altf = altf - ground; //get alt AGL
  139.    
  140.     vinit = velocity; //store previous velocity for logging
  141.     velocity = (altf - alti)/(tf - ti);
  142.    
  143.     if (altf > alti) {
  144.       apogee = altf;
  145.     }
  146.     if (altf < alti) {
  147.        if (apogee > 100) {
  148.          transmit = "Apogee at ";
  149.          transmit += String(apogee);
  150.          transmit += "M";
  151.          tx_data(transmit);
  152.          if (altf <= 150) {
  153.            if (dep = false) {
  154.              chute.attach(9);
  155.              chute.write(180);
  156.              chute.detach();
  157.              dep = true;
  158.              transmit = "Seconary Deployment at "; transmit += String(altf); transmit += "ft, "; transmit += lat; transmit += ", "; transmit += lon;
  159.              tx_data(transmit);
  160.            }
  161.            if (altf < 50){
  162.              transmit = String(altf); transmit += "ft, "; transmit += lat; transmit += ", "; transmit += lon;
  163.              tx_data(transmit);
  164.            }
  165.            if (altf <= 10) {
  166.              tx_data("ALIVE");
  167.            }
  168.          }
  169.        }
  170.     }
  171.    
  172.     if (velocity > vinit) {
  173.       vmax = velocity;
  174.     }
  175.     if (vmax > velocity) {
  176.        if (apogee > 20) {
  177.          transmit = "Max Velocity: ";
  178.          transmit += String(vmax);
  179.          transmit += "ft/s";
  180.          tx_data(transmit);
  181.        }
  182.     }
  183.     tempstr = String(time); tempstr += ","; tempstr += String(velocity); tempstr += ","; ; tempstr += String(altf); tempstr += ","; tempstr += lat; tempstr += ","; tempstr += lon;
  184.     File logFile = SD.open("flightlog.csv", FILE_WRITE);
  185.     logFile.println(tempstr);
  186.     logFile.close();
  187. }
  188.  
  189. //needed for radio
  190.  
  191. void tx_data(String tx_d)
  192. {
  193.   byte packet;
  194.   int length = tx_d.length()+1;
  195.   char buf[length];
  196.   tx_d.toCharArray(buf, length);
  197.   vw_send((uint8_t *)buf, length);
  198.   vw_wait_tx(); // Wait until the whole message is gone
  199. }