uBlox Library

nice thing about I2C is you might/don’t need to pull/parse the entire data if your looking for a specific value in the gps string. You could pull that data specifically from the static I2C location without the overhead of parsing.
 
Problem UBLOX Lib with Arduino Nano

Hi!
I planned to use UBLOX (Not UBLOX2) library for Arduino Nano 5Volt -only one serial port! GPS Ublox M8N-0-01.
For the test, I used a simple sketch
#include "UBLOX.h"
UBLOX gps(Serial, 9600); //Serial-not Serial 1-3!!!!!
void setup() {
pinMode(2, OUTPUT);
gps.begin();
}
void loop() {

if (gps.readSensor()) {
digitalWrite(2, HIGH);
}
delay(500);
digitalWrite(2, LOW);
}
Led flashes if gps.readSensor() == true. Led flashes sometimes. But often do not catch fire. This means that the library does not accept the package from the GPS.
The receiver outputs a level of 3.3V. Therefore, I decided to check whether the Arduino rerceives such a signal. I wrote the next sketch. Bit by bit broadcast through Arduino.

int BAUD = 9600;
byte oneword = 0;
void setup() {
Serial.begin(BAUD);
}
void loop() {
if ( Serial.available() )
{
oneword = Serial.read() ;
Serial.write( oneword) ;
}

}

Packages as in my opinion are broadcast through Arduino without problems. Ublox-center accepts and decodes them correctly. Full packet length of 100 bytes.
09:20:23 R -> UBX NAV-PVT, Size 100, 'Navigation PVT Solution'
09:20:24 R -> UBX NAV-PVT, Size 100, 'Navigation PVT Solution'
09:20:25 R -> UBX NAV-PVT, Size 100, 'Navigation PVT Solution'

The header is correct, the length indicated is 92 bits = 0x5C - the same too. I can not understand what the problem is the second day! Please help!

09:02:45 0000 B5 62 01 07 5C 00 58 89 17 07 E3 07 03 04 09 02 µb��\�X���ã�����
0010 2D 37 12 00 00 00 B7 3F FC FF 03 01 0A 08 13 99 -7����·?üÿ������
0020 4D 12 54 DE 05 1E B8 F2 01 00 26 8F 01 00 98 1E M�TÞ��¸ò��&�����
0030 00 00 31 21 00 00 FF FF FF FF E9 FF FF FF 15 00 ��1!��ÿÿÿÿéÿÿÿ��
0040 00 00 17 00 00 00 2B 51 0E 01 D9 01 00 00 E5 EF ������+Q��Ù���åï
0050 56 00 CD 00 00 E0 AC 4C 22 00 00 E0 00 E0 00 00 V�Í��à¬L"��à�à��
0060 00 80 49 8F ��I��

09:02:46 0000 B5 62 01 07 5C 00 40 8D 17 07 E3 07 03 04 09 02 µb��\�@���ã�����
0010 2E 37 12 00 00 00 DD 3F FC FF 03 01 0A 07 04 99 .7����Ý?üÿ������
0020 4D 12 72 DE 05 1E 4E F3 01 00 BD 8F 01 00 D9 1E M�r��N�����
0030 00 00 46 21 00 00 A0 00 00 00 B7 FF FF FF FE FF ��F!�� ���·ÿÿÿþÿ
0040 FF FF B0 00 00 00 2B 51 0E 01 9B 03 00 00 5A 0C ÿÿ°���+Q������Z�
0050 57 00 D5 00 00 E0 AC 4C 22 00 00 E0 00 E0 00 00 W�Õ��à¬L"��à�à��
0060 00 80 3E D6 ��>�

09:02:47 0000 B5 62 01 07 5C 00 28 91 17 07 E3 07 03 04 09 02 µb��\�(���ã�����
0010 2F 37 12 00 00 00 04 40 FC FF 03 01 0A 07 F8 98 /7�����@üÿ����ø�
0020 4D 12 88 DE 05 1E 67 F3 01 00 D5 8F 01 00 05 1F M��Þ��gó��Õ�����
0030 00 00 50 21 00 00 44 00 00 00 D4 FF FF FF 09 00 ��P!��D���Ôÿÿÿ��
0040 00 00 51 00 00 00 2B 51 0E 01 50 03 00 00 7C 26 ��Q���+Q��P���|&
0050 57 00 D5 00 00 E0 AC 4C 22 00 00 E0 00 E0 00 00 W�Õ��à¬L"��à�à��
0060 00 80 25 57

ublox lib .jpg
 
Last edited:
At 9600 baud even the nano should be able to keep up - I only used with a Teensy 3.6 and did so with much higher baud rates. Of course using a Teensy would be better - I just peeked at the code and there is a note that Teensy uses hardware serial - maybe this code has something Teensy (or 32 bit) specific in it.

What was shown with the sketch to manually read and show the incoming 'UBX-NAV-PVT packet' message? Counting the bytes per message and showing that would be helpful as the data coming includes binary data that is hard to interpret the header bytes start with "UBX_HEADER[] = { 0xB5, 0x62 };". When running the end use sketch instead of the test above - how much RAM is left?

IIRC the indicated packet size didn't match the transferred number of bytes - or the count of bytes in the message received excluded the checksum and overhead bytes - so it isn't clear that is indicating anything.

Does the GPS have a lock? The message may be incomplete or rejected if no GPS lock - not sure if that was the case. There may be some other setting in the uBlox config that is changing the message output as expected for the 'UBX-NAV-PVT packet'?
 
Sorry, but I partially did not understandfrom what you wrote. The function gps.readSensor() tracks the correctness of the package in length, headers and checksums. Visually, the packet is accepted correctly — headers and length are correct, I don’t know is the checksums correct? The U-center will receive the information and decode correctly. Why the library does not work is unclear. Yesterday, sometimes it worked several times in a row — up to five. Today never. 3D-Fix mode is judging by the screen there is. Memory is enough. ublox lib .jpg
 
Last edited:
There is only one problem — I can't force M8N to save UBX-NAV-PVT mode in memory. After turning off the power of the M8N, it jumps to UBX-NAV-SOL with the UART1 port turned off. See screen. But packages in the UBX-NAV-PVT format are still transmitted to format continue to be transmitted to the U-Center or to another terminal program TERMITE 3.2 both via Arduino and so on via Uart -> Usb.

TERMITE 3.2
b5 62 01 07 5c 00 60 a3 c7 07 e3 07 03 04 0c 0f µb..\.`ЈЗ.г.....
06 37 1b 00 00 00 b8 de 03 00 03 01 0a 06 58 98 .7....ёЮ......X˜
4d 12 a8 e1 05 1e a6 fd 01 00 14 9a 01 00 0f 1a M.Ёб..¦э...љ....
00 00 33 38 00 00 de ff ff ff f0 ff ff ff ab 00 ..38..Юяяяряяя«.
00 00 26 00 00 00 00 00 00 00 90 02 00 00 1e bf ..&.......ђ....ї
ec 00 70 01 00 e0 ac 4c 22 00 00 e0 00 e0 00 00 м.p..а¬L"..а.а..
00 80 c7 cb

total=100byte
.ЂЗЛ
b5 62 01 07 5c 00 48 a7 c7 07 e3 07 03 04 0c 0f µb..\.H§З.г.....
07 37 1b 00 00 00 fc de 03 00 03 01 0a 06 57 98 .7....ьЮ......W˜
4d 12 a9 e1 05 1e 2d fd 01 00 9b 99 01 00 fc 19 M.©б..-э..›™..ь.
00 00 2b 38 00 00 c6 ff ff ff d5 ff ff ff ac 00 ..+8..ЖяяяХяяя¬.
00 00 48 00 00 00 00 00 00 00 95 02 00 00 9c c6 ..H.......•...њЖ
ec 00 70 01 00 e0 ac 4c 22 00 00 e0 00 e0 00 00 м.p..а¬L"..а.а..
00 80 63 5c

total=100byte

ublox lib2 .jpg
 
Last edited:
Get rid of the delay in your test program, it might be causing issues:
Code:
#include "UBLOX.h"
UBLOX gps(Serial, 9600); //Serial-not Serial 1-3!!!!!
bool led = LOW;
void setup() 
{
  pinMode(2, OUTPUT);
  gps.begin();
}
void loop() 
{
  if (gps.readSensor()) {
    led = !led;
    digitalWrite(2, led);
  }
}

Make sure you aren't sending any packets other than UBX-NAV-PVT and turn down the rate to 1 Hz for now.
 
Get rid of the delay in your test program, it might be causing issues:

Make sure you aren't sending any packets other than UBX-NAV-PVT and turn down the rate to 1 Hz for now.

Hi!
Thanks you! You helped me a lot! It all worked! Added output to terminal on the same serial port. It works too !!!!

Code:
#include "UBLOX.h"
UBLOX gps(Serial, 9600); //Serial-not Serial 1-3!!!!!
bool led = LOW;
void setup() 
{
  pinMode(2, OUTPUT);
  gps.begin();
}
void loop() 
{
  if (gps.readSensor()) {
    led = !led;
    digitalWrite(2, led);

    Serial.print(gps.getNumSatellites());       ///< [ND], Number of satellites used in Nav Solution
    Serial.print("\t");
    Serial.print(gps.getLatitude_deg(), 10);    ///< [deg], Latitude
    Serial.print("\t");
    Serial.print(gps.getLongitude_deg(), 10);   ///< [deg], Longitude
    Serial.print("\t");
    Serial.println(gps.getMSLHeight_ft());      ///< [ft], Height above mean sea level
       
  }
}

Data from terminal :

7 50.7201324462 30.9476091766 369.85


Now I can use your library in my project. Please check if I did it right?

Code:
#include  "UBLOX.h"

double   Latitude_deg       = 0;         
double   Longitude_deg      = 0;         
double   Latitude_rad       = 0;        
double   Longitude_rad      = 0;        
double   MSLHeight_m        = 0;         
uint8_t  NumSatellites      = 0;         
double   GroundSpeed_ms     = 0;         
float    pDOP               = 0;    
    
UBLOX gps(Serial, 9600);

void setup()
{
//my code here
}

void loop {

if (gps.readSensor())
  {
    Longitude_rad = gps.getLongitude_rad();
    Latitude_rad = gps.getLatitude_rad();
    Longitude_deg = gps.getLongitude_deg();
    Latitude_deg = gps.getLatitude_deg();
    MSLHeight_m = gps.getMSLHeight_m();
    GroundSpeed_ms  =  gps.getGroundSpeed_ms();
    pDOP = gps.getpDOP();

   }
//my code here
}


Could you indicate at what time the execution of my code in the Loop after the acceptance of the UBX-NAV-PVT data will be stable and the data will be received correctly? The speed is 9600, 1Hz. I have given that the parsing takes place asynchronously as the new packet arrives from the receiver and the program cycle time does not matter. I think my code will take up to one hundred milliseconds.

UPD:
I inserted a delay of 100 milliseconds. Almost does not work. Set a delay of 50. Earned. If there are problems with the duration of the execution of my code, I will have to insert into the program a trigger waiting for decoding data and only after that put my code into operation in each cycle. Thus, the likelihood of “capturing” data from NEO will increase.

Best regards,

Gennady
 
Last edited:
Hi!
Thanks you! You helped me a lot! It all worked! Added output to terminal on the same serial port. It works too !!!!

Code:
#include "UBLOX.h"
UBLOX gps(Serial, 9600); //Serial-not Serial 1-3!!!!!
bool led = LOW;
void setup() 
{
  pinMode(2, OUTPUT);
  gps.begin();
}
void loop() 
{
  if (gps.readSensor()) {
    led = !led;
    digitalWrite(2, led);

    Serial.print(gps.getNumSatellites());       ///< [ND], Number of satellites used in Nav Solution
    Serial.print("\t");
    Serial.print(gps.getLatitude_deg(), 10);    ///< [deg], Latitude
    Serial.print("\t");
    Serial.print(gps.getLongitude_deg(), 10);   ///< [deg], Longitude
    Serial.print("\t");
    Serial.println(gps.getMSLHeight_ft());      ///< [ft], Height above mean sea level
       
  }
}

Data from terminal :

7 50.7201324462 30.9476091766 369.85


Now I can use your library in my project. Please check if I did it right?

Code:
#include  "UBLOX.h"

double   Latitude_deg       = 0;         
double   Longitude_deg      = 0;         
double   Latitude_rad       = 0;        
double   Longitude_rad      = 0;        
double   MSLHeight_m        = 0;         
uint8_t  NumSatellites      = 0;         
double   GroundSpeed_ms     = 0;         
float    pDOP               = 0;    
    
UBLOX gps(Serial, 9600);

void setup()
{
//my code here
}

void loop {

if (gps.readSensor())
  {
    Longitude_rad = gps.getLongitude_rad();
    Latitude_rad = gps.getLatitude_rad();
    Longitude_deg = gps.getLongitude_deg();
    Latitude_deg = gps.getLatitude_deg();
    MSLHeight_m = gps.getMSLHeight_m();
    GroundSpeed_ms  =  gps.getGroundSpeed_ms();
    pDOP = gps.getpDOP();

   }
//my code here
}


Could you indicate at what time the execution of my code in the Loop after the acceptance of the UBX-NAV-PVT data will be stable and the data will be received correctly? The speed is 9600, 1Hz. I have given that the parsing takes place asynchronously as the new packet arrives from the receiver and the program cycle time does not matter. I think my code will take up to one hundred milliseconds.

UPD:
I inserted a delay of 100 milliseconds. Almost does not work. Set a delay of 50. Earned. If there are problems with the duration of the execution of my code, I will have to insert into the program a trigger waiting for decoding data and only after that put my code into operation in each cycle. Thus, the likelihood of “capturing” data from NEO will increase.

Best regards,

Gennady

The
Code:
if (gps.readSensor())
returns true only on a valid packet. It is safe to use that data afterwards.

The issue with delays in your code seem to be your arduino board (a nano) seems to have a very small serial buffer. Too long of a delay and received GPS data falls out of buffer and you get corrupted packets. You could call
Code:
if (gps.readSensor())
often during your code so that it can parse the incoming serial data. Or you can try to increase the buffer size (I don't know how to do this on a nano), tie into the serial receive interrupt (again, don't know how to do this on a nano), or get a more capable board.
 
The
Code:
if (gps.readSensor())
returns true only on a valid packet. It is safe to use that data afterwards.

The issue with delays in your code seem to be your arduino board (a nano) seems to have a very small serial buffer. Too long of a delay and received GPS data falls out of buffer and you get corrupted packets. You could call
Code:
if (gps.readSensor())
often during your code so that it can parse the incoming serial data. Or you can try to increase the buffer size (I don't know how to do this on a nano), tie into the serial receive interrupt (again, don't know how to do this on a nano), or get a more capable board.

Hi!
Arduino Nano has a buffer size of 1 byte in hardware and 64 bytes in the Serial library. I made it easier. I set the trigger inside the if (gps.readSensor ()) parsing procedure and reset it in my part of the code, which can only be entered if the trigger is set. Thus, until the data is parsed from NEO, my code is not executed.
Your library helped me a lot!
Thank you for your help!
Gennady
 

Hi!


I needed to get some data from the UBX_MON-HW package. Not all, but only three parameters. I will, with your permission, change your library to fit my needs. In principle, I understood how it works. But I think that I myself can hardly achieve the result. May I ask you to help me in case I fail.

Thanks in advance!
Gennady
 
Hi!


I needed to get some data from the UBX_MON-HW package. Not all, but only three parameters. I will, with your permission, change your library to fit my needs. In principle, I understood how it works. But I think that I myself can hardly achieve the result. May I ask you to help me in case I fail.

Thanks in advance!
Gennady

The beauty of the MIT license is that you can do what you want with the code. I can take a look if I have time, no guarantees.
 

Thank you for your support! I modified your library under the reception of MON-HW. After correcting errors, it all worked!

It is time to connect all this to the PIXHAWK autopilot. It programs the NEO M8N (UBX only, 5HZ, 38400 baud) to transmit the following NAV packets: SOL, STATUS, DOP, POSLLH, VELNED. Also then I add a PVT package for my needs via U-Center. Total 290 bytes.

The program in the cycle consists of two parts. The first part is the parsing of the PVT package and the writing of values ​​into variables. After that, a trigger is set up that allows the operation of another part — my code.
My code does some transformations with the variables obtained above and produces the result on the UART TX. After that, the trigger is reset. Thus, my code is executed only after receiving new data through your library.

Code:
loop{

if (gps.readSensor())
    { digitalWrite(6, HIGH);
      Longitude_deg = gps.getLongitude_deg();
      Latitude_deg  = gps.getLatitude_deg();   
      GnssFixOk     = gps.isGnssFixOk();
      startLatitude_rad  = gps.getLatitude_rad();
      startLongitude_rad = gps.getLongitude_rad();
      MSLHeight_m   = gps.getMSLHeight_m();
      NumSatellites = gps.getNumSatellites();
      triggerParse = 1;
      digitalWrite(6, LOW);
    }

if (  triggerParse == 1 ) 
    { digitalWrite(9, HIGH);

//my code here....

      triggerParse = 0;
      digitalWrite(9, LOW);

    }
}

The problem is that at any speeds of 19200, 38400, 57600, everything works if I reduce the transfer from NEO to 240 bytes. I experimented throwing away SOL or STATUS + DOP.

I came to the conclusion that there is not enough buffer for Serial RX. I increased the buffer from 64 by default to 320. That didn't help! Please advise what I can try to do?


I also give a picture - channels from top to bottom: parsing, UART RX, my code, UART TX.


Thanks in advance!

Gennady
neo1.JPG
 
Last edited:
@Gennady1990 - what Teensy and what Serial port # is the GPS connected to where the buffer was increased? OR is this still on a Nano?
 
in nano! but problem not in speed!

Just a question to the hardware in use - even on Teensy there is a diff between Serial1/2 and Serial3.
When I was working with @brtaylor on T_3.5/3.6 the baud was 100K>900K baud and worked quickly to keep the PVT (?) message flowing. Not sure we did messages that large - the rate was typically 5/sec rate - but the faster baud worked.
 
There is only one problem — I can't force M8N to save UBX-NAV-PVT mode in memory. After turning off the power of the M8N, it jumps to UBX-NAV-SOL with the UART1 port turned off. See screen. But packages in the UBX-NAV-PVT format are still transmitted to format continue to be transmitted to the U-Center or to another terminal program TERMITE 3.2 both via Arduino and so on via Uart -> Usb.

Gennady1990 did you figure this out? Just so you know The ublox chips dont't have any permanent memory unless you attached a QSPI flash chip. The Flash chip can store configurations, firmware, and AssistNow information.
So every time you boot up the M8N you need to send a configuration package.

For my application this is the startup packet:
You can build your own configure information from u-Center. Although it would be nice if some of these functions were in brtaylor's library.
Code:
//Setup UART connection
//Increase to Baud 38400
static const byte UBX_CFG_PRT[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x00, 0x96,
                                   0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x90
                                  };

//MSG Config
//Turn on NAV-PVT
static const byte UBX_CFG_MSG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0x01, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x19, 0xE7,
                                   //Turn off  GGA
                                   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x23,
                                   //Turn off GLL
                                   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A,
                                   //Turn off GSA
                                   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31,
                                   //Turn off GSV
                                   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38,
                                   //Turn off RMC
                                   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3F,
                                   //Turn off VTG
                                   0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46
                                  };

//Setup Ext Power
//EXINT 0, ExBackup
static const byte UBX_CFG_PM2[] = {0xB5, 0x62, 0x06, 0x3B, 0x2C, 0x00, 0x01, 0x06, 0x00, 0x00, 0x4E, 0x18, 0x42, 0x01, 0xC8, 0x00, 0x00,
                                   0x00, 0x10, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00,
                                   0x4F, 0xC1, 0x03, 0x00, 0x86, 0x02, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x64, 0x40, 0x01, 0x00, 0x87,
                                   0x39
                                  };

//Save Config, Not sure exactly what this does but U-Center does it, so...
static const byte UBX_CFG_CFG[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1D, 0xAB };
 
@jacky4566-
The NEO 6,7,8 chip has a memory that is powered by a battery. If you save the configuration in BBR, with a normal battery, it will automatically load every time you turn it on. This info is in neo pdf and checked many time.
 

In my case, the transfer of all packets included in the PVT parsing, my code and the transfer of my data on the TX is placed in the interval between updates on RX (200 millis = 5 Hz) with a big margin at start from speed 19200. Maybe there are limitations in the Arduino Serial library on the length of continuously received data?
 
@jacky4566-
The NEO 6,7,8 chip has a memory that is powered by a battery. If you save the configuration in BBR, with a normal battery, it will automatically load every time you turn it on. This info is in neo pdf and checked many time.

Ah my mistake. I didn't see that the Neo M8N had flash. I'm used to working with the Max and Eva series. Space and power savings on 1.8v!
 
Its from arduino IDE 1.8.2 core - Serial lib for Nano, Uno, etc.
 

Attachments

  • HardwareSerial.h
    5.1 KB · Views: 105
  • HardwareSerial.cpp
    7.6 KB · Views: 88
@brtaylor-
Today I experimented with the messages in the package. NEO 57600baud, 5Hz. The working version is the following and the only one.

UBX NAV-SOL, Size 60, 'Navigation Solution'
UBX NAV-PVT, Size 100, 'Navigation PVT Solution'
UBX NAV-POSLLH, Size 36, 'Geodetic Position'
UBX NAV-VELNED, Size 44, 'Velocity in WGS 84'

Total 240 bytes.

In this order, NEO builds them.

I add MON-HW2 long 36 byte. He stands in front of SOL on some time lead. But its frequency of appearance is 1 Hz. At this point, the parsing does not work. After that, I removed MON-HW2, but I inserted the message DOP 26 byte. It fell AFTER the POSLLH message. With him, the parsing also disappeared. At lower speeds 38400, 19200 the same.


I noticed that after pressing the reset button, the first parsing takes place under any conditions.
It seems that with a packet of more than 240 bytes, some kind of buffer overflows.


I do not know what to do anymore ((((
 
Back
Top