I needed to program the time pulse (TP-5) output on a Ublox NEO-7M GPS module, that is strait forward with the U-center software (connect serial and power betwen PC and GPS module), only problem is that software only runs on Windows and I'm more a Linux user.
The module can also be programed via the Arduino or any device with a serial port as long as you know the u-blox programing specification/protocol.
For the correct command to be sent you can either read the u-blox programing/documentation manual and calculate/generate the string plus the crc or you deploy U-center software on Windows, take the hex output for your needed output and program that on Arduino.
I started to read the specs and try to recreate the command but half way trough it just decided to boot a Windows and deploy U-center and then get the needed outputs, example here:
The two Hex lines are is in the bottom right.
Most of the details on how to accomplish this here were taken from a nice tutorial from "iforce2d" channel at:
https://www.youtube.com/watch?v=ylxwOg2pXrc
Have a go there, it's very well explained from someone who really knows what is doing.... not my case :)
The output of some of the frequencies tested with the module directly at the "PPS" output pin (not the internal blinking LED).
2Mhz
2.5Mhz, all the ones that are not integer division of 48Mhz appear with some jitter.
24Mhz is not the most square, also due to probes.
The module used is one like the above.
Vcc is 5v, txd and rxd to Arduino softserial 3,4 and PPS is the output.
In the code are 2Mhz, 2.5Mhz, 10Mhz and 24Mhz output examples, all with 1Hz timepulse if not enough satelites to provide a precise frequency are avaiable.
If other frequencies are needed I suggest installing U-center and then generate the needed Hex code and insert it on the code bellow.
The code also includes one output for I2C LCD, serial and LED to indicate status, it can be removed, if you just need to program the module. I added it as part of some experiemtes, don't expect to be perfect was mostly for troubleshooting some GPS modules I have.
Arduino code bellow:
/////////////////////
// programing of the u-blox 7m module from Arduino for timepulse TP-5
// hex was taken from u-center software configuration view
//
//
// plus, flashing LED connected to pin 10 indicates when enough sat's in view
// u-blox module to connect o 3 and 4 for using soft serial of Arduino
// CT2GQV 2019 mixing multiple libs and examples.
// copy code from the image because blogger screws completely any attempt of including the includes...
const char UBLOX_INIT[] PROGMEM = {
// the actual programing string, uncoment for the one needed. 10Mhz, 2.5Mhz, 24Mhz or 2Mhz
// any frequency not integer divide of 48Mhz will have some jitter since module reference is 48. Best use is for 24 or 2 Mhz
/*
// CFG-TP5 1Hz / 10Mhz sync
0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x96,
0x98, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x08, 0x00, 0x00, 0x7E, 0xA8,
*/
/*
// CFG-TP5 1Hz / 10Mhz no sync 50ms cable delay
0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x96, 0x98, 0x00,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0xA8, 0x08,
*/
/*
// CFG-TP5 1Hz / 24 Mhz no sync 0ms cable delay
0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6E, 0x01,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x6D, 0x8D,
*/
/*
// CFG-TP5 1Hz / 2.5Mhz no sync 50ms cable delay
0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xA0, 0x25, 0x26, 0x00,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0xE5, 0x21,
*/
// CFG-TP5 1Hz / 2 Mhz no sync 50ms cable delay
0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x84, 0x1E, 0x00,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x1C, 0x1E,
/*
// UBX-CFG-TP5 parameters (not fully complete)
0xB5, 0x62, // header
0x06, 0x31, // time pulse get/set
0x20, // lenght 32
0x00, // tpIdx time pulse selection = 0 = timepulse, 1 = timepulse2 (U1 Char)
0x00, // reserved0 U1
0x01, 0x00, // reserved1 U2
0x00, 0x32, // antCableDelay ns
0x00, 0x00, // rf group delay I2
0x00, 0x90, 0xD0, 0x03, // freqPeriod
0x00, 0x40, 0x42, 0x0F, // freqPeriodLoc
0x00, 0xF0, 0x49, 0x02, // pulselenRatio
0x00, 0x60, 0xAE, 0x0A, // pulselenRatio
0x00, 0x00, 0x00, 0x00, // userConfigDelay ns
0x00, 0x77, 0x00, 0x00, // flags - page 135 u-blox 7 Receiver Description Including Protocol Specification V14.pdf
0x00, 0x48, 0x65,
*/
};
int SATLED = 10; // for showing we have satelites
TinyGPS gps;
// SoftwareSerial ss(4, 3);
SoftwareSerial ss(3, 4);
int sats = 0 ;
void setup()
{
lcd.begin(16, 2); // LCD set for 16 by 2 display
lcd.setBacklightPin(3,POSITIVE); // (BL, BL_POL)
lcd.setBacklight(HIGH); // LCD backlight turned ON
lcd.setCursor(0, 0); //
lcd.print("Booting...");
ss.begin(9600);
pinMode(SATLED, OUTPUT); // to indicate we have enough satelites
digitalWrite(SATLED, HIGH);
delay(2000);
digitalWrite(SATLED, LOW);
// actual u-blox 7m programing
for(int i = 0; i < sizeof(UBLOX_INIT); i++) {
ss.write( pgm_read_byte(UBLOX_INIT+i) );
delay(5); // simulating a 38400baud pace (or less), otherwise commands are not accepted by the device.
}
// ends here
Serial.begin(9600);
Serial.println("= sent init string to GPS =");
lcd.setCursor(0, 0); lcd.print("NO DATA ");
}
void loop()
{
bool newData = false;
unsigned long chars;
unsigned short sentences, failed;
// For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
Serial.write(c); // uncomment this line if you want to see the GPS data flowing
if (gps.encode(c)) // Did a new valid sentence come in?
newData = true;
}
}
if (newData)
{
float flat, flon;
unsigned long age;
gps.f_get_position(&flat, &flon, &age);
Serial.print("LAT=");
Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
Serial.print(" LON=");
Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
Serial.print(" SAT=");
Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
sats = gps.satellites();
lcd.setCursor(0, 0); lcd.print("Satelites:");lcd.print(sats);
if (sats >= 3){digitalWrite(SATLED, HIGH); delay(20);digitalWrite(SATLED, LOW );};
//if (sats < 3 ){digitalWrite(SATLED, LOW );};
Serial.print(" PREC=");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
}
gps.stats(&chars, &sentences, &failed);
if (chars == 0)
Serial.println("** No characters received from GPS: check wiring **");
}
////////////////////
..code ended.
Have a nice week!
The module can also be programed via the Arduino or any device with a serial port as long as you know the u-blox programing specification/protocol.
For the correct command to be sent you can either read the u-blox programing/documentation manual and calculate/generate the string plus the crc or you deploy U-center software on Windows, take the hex output for your needed output and program that on Arduino.
I started to read the specs and try to recreate the command but half way trough it just decided to boot a Windows and deploy U-center and then get the needed outputs, example here:
The two Hex lines are is in the bottom right.
Most of the details on how to accomplish this here were taken from a nice tutorial from "iforce2d" channel at:
https://www.youtube.com/watch?v=ylxwOg2pXrc
Have a go there, it's very well explained from someone who really knows what is doing.... not my case :)
The output of some of the frequencies tested with the module directly at the "PPS" output pin (not the internal blinking LED).
2Mhz
2.5Mhz, all the ones that are not integer division of 48Mhz appear with some jitter.
24Mhz is not the most square, also due to probes.
The module used is one like the above.
Vcc is 5v, txd and rxd to Arduino softserial 3,4 and PPS is the output.
In the code are 2Mhz, 2.5Mhz, 10Mhz and 24Mhz output examples, all with 1Hz timepulse if not enough satelites to provide a precise frequency are avaiable.
If other frequencies are needed I suggest installing U-center and then generate the needed Hex code and insert it on the code bellow.
The code also includes one output for I2C LCD, serial and LED to indicate status, it can be removed, if you just need to program the module. I added it as part of some experiemtes, don't expect to be perfect was mostly for troubleshooting some GPS modules I have.
Arduino code bellow:
/////////////////////
// programing of the u-blox 7m module from Arduino for timepulse TP-5
// hex was taken from u-center software configuration view
//
//
// plus, flashing LED connected to pin 10 indicates when enough sat's in view
// u-blox module to connect o 3 and 4 for using soft serial of Arduino
// CT2GQV 2019 mixing multiple libs and examples.
// copy code from the image because blogger screws completely any attempt of including the includes...
const char UBLOX_INIT[] PROGMEM = {
// the actual programing string, uncoment for the one needed. 10Mhz, 2.5Mhz, 24Mhz or 2Mhz
// any frequency not integer divide of 48Mhz will have some jitter since module reference is 48. Best use is for 24 or 2 Mhz
/*
// CFG-TP5 1Hz / 10Mhz sync
0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x96,
0x98, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x08, 0x00, 0x00, 0x7E, 0xA8,
*/
/*
// CFG-TP5 1Hz / 10Mhz no sync 50ms cable delay
0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x96, 0x98, 0x00,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0xA8, 0x08,
*/
/*
// CFG-TP5 1Hz / 24 Mhz no sync 0ms cable delay
0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6E, 0x01,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x6D, 0x8D,
*/
/*
// CFG-TP5 1Hz / 2.5Mhz no sync 50ms cable delay
0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xA0, 0x25, 0x26, 0x00,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0xE5, 0x21,
*/
// CFG-TP5 1Hz / 2 Mhz no sync 50ms cable delay
0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x84, 0x1E, 0x00,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x1C, 0x1E,
/*
// UBX-CFG-TP5 parameters (not fully complete)
0xB5, 0x62, // header
0x06, 0x31, // time pulse get/set
0x20, // lenght 32
0x00, // tpIdx time pulse selection = 0 = timepulse, 1 = timepulse2 (U1 Char)
0x00, // reserved0 U1
0x01, 0x00, // reserved1 U2
0x00, 0x32, // antCableDelay ns
0x00, 0x00, // rf group delay I2
0x00, 0x90, 0xD0, 0x03, // freqPeriod
0x00, 0x40, 0x42, 0x0F, // freqPeriodLoc
0x00, 0xF0, 0x49, 0x02, // pulselenRatio
0x00, 0x60, 0xAE, 0x0A, // pulselenRatio
0x00, 0x00, 0x00, 0x00, // userConfigDelay ns
0x00, 0x77, 0x00, 0x00, // flags - page 135 u-blox 7 Receiver Description Including Protocol Specification V14.pdf
0x00, 0x48, 0x65,
*/
};
int SATLED = 10; // for showing we have satelites
TinyGPS gps;
// SoftwareSerial ss(4, 3);
SoftwareSerial ss(3, 4);
int sats = 0 ;
void setup()
{
lcd.begin(16, 2); // LCD set for 16 by 2 display
lcd.setBacklightPin(3,POSITIVE); // (BL, BL_POL)
lcd.setBacklight(HIGH); // LCD backlight turned ON
lcd.setCursor(0, 0); //
lcd.print("Booting...");
ss.begin(9600);
pinMode(SATLED, OUTPUT); // to indicate we have enough satelites
digitalWrite(SATLED, HIGH);
delay(2000);
digitalWrite(SATLED, LOW);
// actual u-blox 7m programing
for(int i = 0; i < sizeof(UBLOX_INIT); i++) {
ss.write( pgm_read_byte(UBLOX_INIT+i) );
delay(5); // simulating a 38400baud pace (or less), otherwise commands are not accepted by the device.
}
// ends here
Serial.begin(9600);
Serial.println("= sent init string to GPS =");
lcd.setCursor(0, 0); lcd.print("NO DATA ");
}
void loop()
{
bool newData = false;
unsigned long chars;
unsigned short sentences, failed;
// For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
Serial.write(c); // uncomment this line if you want to see the GPS data flowing
if (gps.encode(c)) // Did a new valid sentence come in?
newData = true;
}
}
if (newData)
{
float flat, flon;
unsigned long age;
gps.f_get_position(&flat, &flon, &age);
Serial.print("LAT=");
Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
Serial.print(" LON=");
Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
Serial.print(" SAT=");
Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
sats = gps.satellites();
lcd.setCursor(0, 0); lcd.print("Satelites:");lcd.print(sats);
if (sats >= 3){digitalWrite(SATLED, HIGH); delay(20);digitalWrite(SATLED, LOW );};
//if (sats < 3 ){digitalWrite(SATLED, LOW );};
Serial.print(" PREC=");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
}
gps.stats(&chars, &sentences, &failed);
if (chars == 0)
Serial.println("** No characters received from GPS: check wiring **");
}
////////////////////
..code ended.
Have a nice week!
3 comments:
Hi,
I want to build an GPS based frequency Oscillator, but your sketch is not complete. Got errors while compiling. "Include" missing librarys, ...
Have you a working sketch?
Regards,
André
Hello André,
Thank you for the comment.
Blogger breaks formatting on the code, I haven't noticed on this one yet.
Post is updated with an image of the include part. Should be good now.
73 de Ricardo / CT2GQV
Hi Ricardo
thanks for the update after playing a lot with the Liquidcristal_I2C it compiles correctly.
73, LX1LW
Post a Comment