Advertisement
Guest User

Untitled

a guest
Mar 6th, 2012
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.96 KB | None | 0 0
  1. #include <TinyGPS.h>
  2. #include <OneWire.h>
  3. #include <stdio.h>
  4. #include <util/crc16.h>
  5. #define EN A2
  6. #define TX0 A1
  7. #define TX1 A0
  8. #define ASCII 7
  9. #define START 1
  10. #define STOP 2
  11. #define BAUD 50
  12. #define INTER_BIT_DELAY (1000/BAUD)
  13.  
  14. TinyGPS gps;
  15. OneWire ds(A3); // DS18x20 Temperature chip i/o One-wire
  16.  
  17. //Tempsensor variables
  18. byte address0[8] = {0x10, 0x81, 0x4, 0x51, 0x2, 0x8, 0x0, 0x57}; // Internal DS18B20
  19. byte address1[8] = (0x28, 0x4F, 0x91, 0x93, 0x3, 0x0, 0x0, 0xB8);
  20.  
  21. int temp0 = 0, temp1 = 1;
  22.  
  23. int count = 1;
  24. byte navmode = 99;
  25. float flat, flon;
  26. unsigned long date, time, chars, age;
  27.  
  28. int hour = 0 , minute = 0 , second = 0, oldsecond = 0;
  29. char latbuf[12] = "0", lonbuf[12] = "0", altbuf[12] = "0";
  30. long int ialt = 123;
  31. int numbersats = 99;
  32.  
  33.  
  34. // ------------------------
  35. // RTTY Functions
  36. void rtty_txstring (char * string)
  37. {
  38.     /* Simple function to send a char at a time to
  39.     ** rtty_txbyte function.
  40.     ** NB Each char is one byte (8 Bits)
  41.     */
  42.     char c;
  43.     c = *string++;
  44.     while ( c != '\0')
  45.     {
  46.         rtty_txbyte (c);
  47.         c = *string++;
  48.     }
  49. }
  50.  
  51. void rtty_txbyte (char c)
  52. {
  53.     /* Simple function to send each bit of a char to
  54.     ** rtty_txbit function.
  55.     ** NB The bits are sent Least Significant Bit first
  56.     **
  57.     ** All chars should be preceded with a 0 and
  58.     ** proceded with a 1. 0 = Start bit; 1 = Stop bit
  59.     **
  60.     ** ASCII_BIT = 7 or 8 for ASCII-7 / ASCII-8
  61.     */
  62.     int i;
  63.     rtty_bit (0); // Start bit
  64.     // Send bits for for char LSB first
  65.     for (i=0;i<8;i++)
  66.     {
  67.         if (c & 1) rtty_bit(1);
  68.             else rtty_bit(0);  
  69.         c = c >> 1;
  70.     }
  71.     rtty_bit (1); // Stop bit
  72.         rtty_bit (1); // Stop bit
  73. }
  74.  
  75. void rtty_bit (int b)
  76. {
  77.   digitalWrite(TX0,(b>0)?HIGH:LOW);
  78.   digitalWrite(TX1,HIGH);
  79.   //digitalWrite(TX1,(b>0)?LOW:HIGH);
  80.   delay(INTER_BIT_DELAY);
  81. }
  82.  
  83. uint16_t gps_CRC16_checksum (char *string)
  84. {
  85.     size_t i;
  86.     uint16_t crc;
  87.     uint8_t c;
  88.  
  89.     crc = 0xFFFF;
  90.  
  91.     // Calculate checksum ignoring the first two $s
  92.     for (i = 2; i < strlen(string); i++)
  93.     {
  94.         c = string[i];
  95.         crc = _crc_xmodem_update (crc, c);
  96.     }
  97.  
  98.     return crc;
  99. }
  100.  
  101. // Send a byte array of UBX protocol to the GPS
  102. void sendUBX(uint8_t *MSG, uint8_t len) {
  103.   for(int i=0; i<len; i++) {
  104.     Serial.print(MSG[i], BYTE);
  105.   }
  106. }
  107.  
  108. // Calculate expected UBX ACK packet and parse UBX response from GPS
  109. boolean getUBX_ACK(uint8_t *MSG) {
  110.     uint8_t b;
  111.     uint8_t ackByteID = 0;
  112.     uint8_t ackPacket[10];
  113.         Serial.flush();
  114.     unsigned long startTime = millis();
  115.  
  116.     // Construct the expected ACK packet    
  117.     ackPacket[0] = 0xB5;    // header
  118.     ackPacket[1] = 0x62;    // header
  119.     ackPacket[2] = 0x05;    // class
  120.     ackPacket[3] = 0x01;    // id
  121.     ackPacket[4] = 0x02;    // length
  122.     ackPacket[5] = 0x00;
  123.     ackPacket[6] = MSG[2];  // ACK class
  124.     ackPacket[7] = MSG[3];  // ACK id
  125.     ackPacket[8] = 0;       // CK_A
  126.     ackPacket[9] = 0;       // CK_B
  127.  
  128.     // Calculate the checksums
  129.     for (uint8_t i=2; i<8; i++) {
  130.         ackPacket[8] = ackPacket[8] + ackPacket[i];
  131.         ackPacket[9] = ackPacket[9] + ackPacket[8];
  132.     }
  133.  
  134.     while (1) {
  135.  
  136.         // Test for success
  137.         if (ackByteID > 9) {
  138.                 // All packets in order!
  139.                                 navmode = 1;
  140.                 return true;
  141.         }
  142.  
  143.         // Timeout if no valid response in 3 seconds
  144.         if (millis() - startTime > 3000) {
  145.                         navmode = 0;
  146.             return false;
  147.         }
  148.  
  149.         // Make sure data is available to read
  150.         if (Serial.available()) {
  151.             b = Serial.read();
  152.  
  153.             // Check that bytes arrive in sequence as per expected ACK packet
  154.             if (b == ackPacket[ackByteID]) {
  155.                 ackByteID++;
  156.                                 //Serial.print(ackPacket[ackByteID], HEX);
  157.                                 //Serial.print(" ");
  158.             } else {
  159.                 ackByteID = 0;  // Reset and look again, invalid order
  160.             }
  161.  
  162.         }
  163.     }
  164. }
  165.  
  166. //Function to poll the NAV5 status of a Ublox GPS module (5/6)
  167. //Sends a UBX command (requires the function sendUBX()) and waits 3 seconds
  168. // for a reply from the module. It then isolates the byte which contains
  169. // the information regarding the NAV5 mode,
  170. // 0 = Pedestrian mode (default, will not work above 12km)
  171. // 6 = Airborne 1G (works up to 50km altitude)
  172. //Adapted by jcoxon from getUBX_ACK() from the example code on UKHAS wiki
  173. // http://wiki.ukhas.org.uk/guides:falcom_fsa03
  174. boolean checkNAV(){
  175.   uint8_t b, bytePos = 0;
  176.   uint8_t getNAV5[] = { 0xB5, 0x62, 0x06, 0x24, 0x00, 0x00, 0x2A, 0x84 }; //Poll NAV5 status
  177.  
  178.   Serial.flush();
  179.   unsigned long startTime = millis();
  180.   sendUBX(getNAV5, sizeof(getNAV5)/sizeof(uint8_t));
  181.  
  182.   while (1) {
  183.     // Make sure data is available to read
  184.     if (Serial.available()) {
  185.       b = Serial.read();
  186.      
  187.       if(bytePos == 8){
  188.         navmode = b;
  189.         return true;
  190.       }
  191.                        
  192.       bytePos++;
  193.     }
  194.     // Timeout if no valid response in 3 seconds
  195.     if (millis() - startTime > 3000) {
  196.       navmode = 0;
  197.       return false;
  198.     }
  199.   }
  200. }
  201.  
  202. void setupGPS() {
  203.   //Turning off all GPS NMEA strings apart on the uBlox module
  204.   Serial.println("$PUBX,40,GLL,0,0,0,0*5C");
  205.   Serial.println("$PUBX,40,GGA,0,0,0,0*5A");
  206.   Serial.println("$PUBX,40,GSA,0,0,0,0*4E");
  207.   Serial.println("$PUBX,40,RMC,0,0,0,0*47");
  208.   Serial.println("$PUBX,40,GSV,0,0,0,0*59");
  209.   Serial.println("$PUBX,40,VTG,0,0,0,0*5E");
  210.  
  211.   delay(3000); // Wait for the GPS to process all the previous commands
  212.  
  213.  // Check and set the navigation mode (Airborne, 1G)
  214.   uint8_t setNav[] = {0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC};
  215.   sendUBX(setNav, sizeof(setNav)/sizeof(uint8_t));
  216.  
  217.   getUBX_ACK(setNav);
  218.  
  219. }
  220.  
  221. // gets temperature data from onewire sensor network, need to supply byte address, it'll check to see what type of sensor and convert appropriately
  222. int getTempdata(byte sensorAddress[8]) {
  223.   int HighByte, LowByte, TReading, SignBit, Tc_100, Whole;
  224.   byte data[12], i, present = 0;
  225.  
  226.   ds.reset();
  227.   ds.select(sensorAddress);
  228.   ds.write(0x44,1);         // start conversion, with parasite power on at the end
  229.  
  230.   delay(1000);     // maybe 750ms is enough, maybe not
  231.   // we might do a ds.depower() here, but the reset will take care of it.
  232.  
  233.   present = ds.reset();
  234.   ds.select(sensorAddress);    
  235.   ds.write(0xBE);         // Read Scratchpad
  236.  
  237.   for ( i = 0; i < 9; i++) {           // we need 9 bytes
  238.     data[i] = ds.read();
  239.   }
  240.  LowByte = data[0];
  241.   HighByte = data[1];
  242.   TReading = (HighByte << 8) + LowByte;
  243.   SignBit = TReading & 0x8000;  // test most sig bit
  244.   if (SignBit) // negative
  245.   {
  246.     TReading = (TReading ^ 0xffff) + 1; // 2's comp
  247.   }
  248.  
  249.   if (sensorAddress[0] == 0x10) {
  250.     Tc_100 = TReading * 50;    // multiply by (100 * 0.0625) or 6.25
  251.   }
  252.   else {
  253.     Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25
  254.   }
  255.  
  256.  
  257.   Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  258.  
  259.   if (SignBit) // If its negative
  260.   {
  261.      Whole = Whole * -1;
  262.   }
  263.   return Whole;
  264. }
  265.  
  266. void setup()
  267. {
  268.   pinMode(EN, OUTPUT);
  269.   pinMode(TX0, OUTPUT);
  270.   pinMode(TX1, OUTPUT);
  271.   digitalWrite(EN, HIGH);
  272.  
  273.   Serial.begin(9600);
  274.  
  275.   delay(5000); // We have to wait for a bit for the GPS to boot otherwise the commands get missed
  276.  
  277.   setupGPS();
  278.  
  279. }
  280.  
  281. void loop() {
  282.     char superbuffer [120];
  283.     char checksum [10];
  284.     int n;
  285.    
  286.     if((count % 10) == 0) {
  287.      digitalWrite(6, LOW);
  288.      checkNAV();
  289.      delay(1000);
  290.      if(navmode != 6){
  291.        setupGPS();
  292.        delay(1000);
  293.      }
  294.      checkNAV();
  295.      delay(1000);
  296.      digitalWrite(6, HIGH);
  297.    }
  298.    
  299.     Serial.println("$PUBX,00*33"); //Poll GPS
  300.    
  301.     while (Serial.available())
  302.     {
  303.       int c = Serial.read();
  304.       if (gps.encode(c))
  305.       {
  306.         //Get Data from GPS library
  307.         //Get Time and split it
  308.         gps.get_datetime(&date, &time, &age);
  309.         hour = (time / 1000000);
  310.         minute = ((time - (hour * 1000000)) / 10000);
  311.         second = ((time - ((hour * 1000000) + (minute * 10000))));
  312.         second = second / 100;
  313.      
  314.       //Get Position
  315.       gps.f_get_position(&flat, &flon);
  316.  
  317.       //convert float to string
  318.       dtostrf(flat, 7, 4, latbuf);
  319.       dtostrf(flon, 7, 4, lonbuf);
  320.      
  321.       //just check that we are putting a space at the front of lonbuf
  322.       if(lonbuf[0] == ' ')
  323.       {
  324.         lonbuf[0] = '+';
  325.       }
  326.      
  327.       // +/- altitude in meters
  328.       ialt = (gps.altitude() / 100);  
  329.       itoa(ialt, altbuf, 10);
  330.     }
  331.     }
  332.    
  333.     temp0 = getTempdata(address0);
  334.     temp1 = getTempdata(address1);
  335.     numbersats = gps.sats();
  336.    
  337.     n=sprintf (superbuffer, "$$ATS-1,%d,%02d:%02d:%02d,%s,%s,%ld,%i,%d,%d,%d", count, hour, minute, second, latbuf, lonbuf, ialt, numbersats, navmode, temp0, temp1);
  338.     if (n > -1){
  339.       n = sprintf (superbuffer, "%s*%04X\n", superbuffer, gps_CRC16_checksum(superbuffer));
  340.       rtty_txstring(superbuffer);
  341.      
  342.     }
  343.     count++;
  344.  
  345. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement