/ RFout1MHzV1_02 / RFout1MHzV1_02.ino
RFout1MHzV1_02.ino
  1  #include <NMEAGPS.h>
  2  #include <SoftwareSerial.h>
  3  SoftwareSerial gpsPort(2, 3); // RX, TX
  4  #define LEDIndicator1 5  //LED indicator for GPS Lock on pin A3
  5  #define FIXOut 4         //Pin Out at IDC. Indicator for GPS Lock on pin 4
  6  #define LDO_Enable A3    //GPS Voltage regulator Enable on pin A0
  7  boolean GPSOK;
  8  const char softwareversion[] = "1.02" ; //Version of this program, sent to serialport at startup
  9  NMEAGPS  gps; // This parses the GPS characters
 10  gps_fix  fix; // This holds on to the latest values
 11  
 12  
 13  
 14  //--------------------------  SETUP -----------------------
 15  
 16  void setup()
 17  {
 18    Serial.begin(9600);
 19    while (!Serial)
 20      ;
 21    
 22    Serial.print(F("Zachtek GPS referenced RF, Software version: "));
 23    Serial.println(softwareversion);
 24     
 25     pinMode(LDO_Enable, OUTPUT); // Set Voltage Regulator Enable pin as output.
 26     digitalWrite(LDO_Enable, HIGH); //Turn on 3.1V Power supply for the Ublox GPS module
 27     Serial.println (F("Turning on Voltage Regulator for GPS module"));
 28     pinMode(LEDIndicator1, OUTPUT); // Set GPS Lock  LED pin as output.
 29     pinMode(FIXOut, OUTPUT);        // Set GPS Lock line as output.
 30     digitalWrite(LEDIndicator1, LOW); //Turn off Lock LED 
 31     digitalWrite(FIXOut, LOW);        //Go low on Lock line 
 32     delay(500);//Wait for GPSmodule to complete it's power on.
 33     gpsPort.begin(9600);
 34     GPSOK=true;
 35    
 36     //Program GPS to output RF
 37     if (setGPS_OutputFreq1MHz()) {
 38      Serial.println ("GPS Initialized to output RF at 1MHz");
 39      Serial.println ("Initialization is complete.");
 40      Serial.println ("");
 41      GPSOK=true; 
 42    }
 43    else
 44    {
 45      Serial.println ("Error! Could not program GPS!"); 
 46      GPSOK=false;  
 47    }
 48  }
 49  
 50  //--------------------------
 51  
 52  
 53  
 54  
 55  //--------------------------  Main loop -----------------------
 56  void loop()
 57  {
 58    while (gps.available( gpsPort )) {
 59      fix = gps.read();
 60      if (fix.valid.location && fix.valid.date && fix.valid.time) 
 61        {
 62        Serial.print( F("Location: ") );  
 63        digitalWrite(LEDIndicator1, HIGH);   // turn the LED on 
 64        digitalWrite(FIXOut, HIGH);          // Set Lock Line high  
 65        Serial.print( fix.latitude(), 6 );
 66        Serial.print( ',' );
 67        Serial.print( fix.longitude(), 6 );
 68        Serial.println();
 69    
 70      }
 71      else
 72      {
 73        if (GPSOK) { //If the GPS is connected but not locked then short blink
 74          digitalWrite(LEDIndicator1, HIGH);   // turn the LED on 
 75          digitalWrite(FIXOut, LOW);          // Set Lock Line low 
 76          delay(100); 
 77          digitalWrite(LEDIndicator1, LOW);    // turn the LED off   
 78          Serial.println(F("Waiting for GPS fix")); 
 79        }  
 80      }
 81    }
 82  }
 83  
 84  
 85  //--------------------------
 86  
 87  bool setGPS_OutputFreq100kHz()
 88  {
 89   int gps_set_sucess=0;
 90   uint8_t setOutputFreq[] = {
 91   0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00,
 92   0x00, 0x00, 0xA0, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
 93   0x00, 0x00, 0xEF, 0x00, 0x00, 0x00, 0x20, 0x1B };
 94  
 95   sendUBX(setOutputFreq, sizeof(setOutputFreq)/sizeof(uint8_t));
 96   gps_set_sucess=getUBX_ACK(setOutputFreq);
 97   //Serial.println("Set output Freq Done");
 98   return gps_set_sucess;
 99  }
100  
101  bool setGPS_OutputFreq1MHz()
102  {
103   int gps_set_sucess=0;
104   uint8_t setOutputFreq[] = {
105   0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00,
106   0x00, 0x00, 0x40, 0x42, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
107   0x00, 0x00, 0xEF, 0x00, 0x00, 0x00, 0x8A, 0x8B };
108  
109   sendUBX(setOutputFreq, sizeof(setOutputFreq)/sizeof(uint8_t));
110   gps_set_sucess=getUBX_ACK(setOutputFreq);
111   //Serial.println("Set output Freq Done");
112   return gps_set_sucess;
113  }
114  
115  bool setGPS_OutputFreq2MHz()
116  {
117   int gps_set_sucess=0;
118   uint8_t setOutputFreq[] = {
119   0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00,
120   0x00, 0x00, 0x80, 0x84, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
121   0x00, 0x00, 0xEF, 0x00, 0x00, 0x00, 0x1B, 0x7F };
122  
123   sendUBX(setOutputFreq, sizeof(setOutputFreq)/sizeof(uint8_t));
124   gps_set_sucess=getUBX_ACK(setOutputFreq);
125   //Serial.println("Set output Freq Done");
126   return gps_set_sucess;
127  }
128  
129  
130  bool setGPS_OutputFreq4MHz()
131  {
132   int gps_set_sucess=0;
133   uint8_t setOutputFreq[] = {
134   0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00,
135   0x00, 0x00, 0x00, 0x09, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
136   0x00, 0x00, 0xEF, 0x00, 0x00, 0x00, 0x3F, 0x8C };
137  
138   sendUBX(setOutputFreq, sizeof(setOutputFreq)/sizeof(uint8_t));
139   gps_set_sucess=getUBX_ACK(setOutputFreq);
140   //Serial.println("Set output Freq Done");
141   return gps_set_sucess;
142  }
143  
144  //8MHz is the highest low-jitter frequency possible
145  bool setGPS_OutputFreq8MHz()
146  {
147   int gps_set_sucess=0;
148   uint8_t setOutputFreq[] = {
149   0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
150   0x00, 0x00, 0x00, 0x12, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
151   0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0xD4, 0x28 };
152  
153   sendUBX(setOutputFreq, sizeof(setOutputFreq)/sizeof(uint8_t));
154   gps_set_sucess=getUBX_ACK(setOutputFreq);
155   //Serial.println("Set output Freq Done");
156   return gps_set_sucess;
157  }
158  
159  //10 MHz is very jittery. Numbers that can be done with an integer division from 48MHz will produce
160  //the lowest jitter so 16 ,12 ,8 ,6 ,4 ,2 and 1 MHz is low jitter but 10MHz is not
161  //If 10MHz low jitter is needed then one option is to output 2MHz and then filter out the 5th overtone arriving at 10MHz in that way.
162  bool setGPS_OutputFreq10MHz()
163  {
164   int gps_set_sucess=0;
165   uint8_t setOutputFreq[] = {
166   0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
167   0x00, 0x00, 0x80, 0x96, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
168   0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0xF6, 0x10 };
169  
170   sendUBX(setOutputFreq, sizeof(setOutputFreq)/sizeof(uint8_t));
171   gps_set_sucess=getUBX_ACK(setOutputFreq);
172   //Serial.println("Set output Freq Done");
173   return gps_set_sucess;
174  }
175  
176  //16MHz is above the specs for lUblox Neo-6, only included for experiments. 
177  //This will not produce as clean Square wave.
178  bool setGPS_OutputFreq16MHz()
179  {
180   int gps_set_sucess=0;
181   uint8_t setOutputFreq[] = {
182   0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
183   0x00, 0x00, 0x00, 0x24, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
184   0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x60, 0x12 };
185  
186   sendUBX(setOutputFreq, sizeof(setOutputFreq)/sizeof(uint8_t));
187   gps_set_sucess=getUBX_ACK(setOutputFreq);
188   //Serial.println("Set output Freq Done");
189   return gps_set_sucess;
190  }
191  
192  
193  void sendUBX(uint8_t *MSG, uint8_t len) {
194   gpsPort.flush();
195   gpsPort.write(0xFF);
196   _delay_ms(500);
197   for(int i=0; i<len; i++) {
198   gpsPort.write(MSG[i]);
199   }
200  }
201  
202  boolean getUBX_ACK(uint8_t *MSG) {
203   uint8_t b;
204   uint8_t ackByteID = 0;
205   uint8_t ackPacket[10];
206   unsigned long startTime = millis();
207   
208  // Construct the expected ACK packet
209   ackPacket[0] = 0xB5; // header
210   ackPacket[1] = 0x62; // header
211   ackPacket[2] = 0x05; // class
212   ackPacket[3] = 0x01; // id
213   ackPacket[4] = 0x02; // length
214   ackPacket[5] = 0x00;
215   ackPacket[6] = MSG[2]; // ACK class
216   ackPacket[7] = MSG[3]; // ACK id
217   ackPacket[8] = 0; // CK_A
218   ackPacket[9] = 0; // CK_B
219   
220  // Calculate the checksums
221   for (uint8_t ubxi=2; ubxi<8; ubxi++) {
222   ackPacket[8] = ackPacket[8] + ackPacket[ubxi];
223   ackPacket[9] = ackPacket[9] + ackPacket[8];
224   }
225   
226    while (1) {  // Test for success
227      if (ackByteID > 9) {
228        // All packets in order!
229        return true;
230      }
231   
232    // Timeout if no valid response in 3 seconds
233    if (millis() - startTime > 3000) {
234      return false;
235    }
236   
237    // Make sure data is available to read
238    if (gpsPort.available()) {
239      b = gpsPort.read();
240      // Check that bytes arrive in sequence as per expected ACK packet
241      if (b == ackPacket[ackByteID]) {
242        ackByteID++;
243      }
244      else {
245        ackByteID = 0; // Reset and look again, invalid order
246      }//else
247    }//If
248   }//While
249  }//getUBX_ACK