Event logging with RTKLIB and the u-blox M8T receiver

Event logging is a nice feature that has been available in the Emlid version of RTKLIB for a long time.  In the latest version of the demo5 code (b29e), I have ported this feature from their open-source code repository.  Their version is specifically for the u-blox M8T receiver but I have extended it to support the Swiftnav receiver as well.  I mentioned this feature in my previous post and had a couple requests for more information, hence this post.

Both the u-blox and Swiftnav receivers have hardware/firmware to capture the precise time an external pin changes state and send out a binary message with this information.  The RTKLIB event logging code decodes these messages and logs the events to the rinex file.  The events in the rinex file are then used in post-processing to generate a position log containing an interpolated position for each timing event. The most popular use for this feature is probably to record camera shutter times but it can also be used for other purposes such as marking survey locations in the data stream.

Here is an example of a drone flight from a data set containing events that I downloaded from the Emlid forum.  On the left is the ground track of the standard position solution plotted with RTKPLOT.  It includes one point for every rover observation epoch.  On the right is a plot of the event positions from the new event position file.  In this case there is one point for every event which gives precise locations for each camera image.  This is very useful information when processing the images.


Here are the positions of the two plotted on top of each other, green dots are the rover observation epochs from the position file and the blue dots are the events from the event position file.  As you can see from the plot, the event positions are interpolated from the observation epochs.



There is information in the Emlid and Swiftnav documentation on how to connect an external trigger to their hardware so I won’t cover that here.

Instead, I will go through an example using an M8T receiver from CSGShop.  I will also use this example to try and validate this feature since there has been some discussion on the Emlid forum about potential issues that as far as I can tell have not been completely resolved on the forum.

The CSGShop M8T receiver comes in several variations.  To use event logging you will need to choose a board that provides access to the external interrupt pins.  You can use either EXINT0 or EXINT1.  For this experiment I also use the TIMEPULSE pin to provide triggers for the event logging.  Here is an image of the receiver and the interface pins.


The goal of this experiment is to generate events for which I know their precise timing so I can use them to validate the RTKLIB event logging results.  To do this, I configured the M8T TIMEPULSE output for a period of two seconds and a falling edge that occurs at 0.2 seconds, all in GPST time.  I then connected the TIMEPULSE output pin to the EXTINT1 input pin so that each state change of the output pulse will be recorded as an event.  Although the M8T will record both rising edges and falling edges, RTKLIB is setup to record only the falling edges.

To configure the timing pulse, I used the u-blox u-center app to setup the UBX-CFG-TP5 command as shown below.


I then enabled the UBX-TIM-TM2 messages which the receiver uses to output the event information.  Next, I opened the table view in u-center and configured it to log GPS time, and the rise and fall times for EXTINT1.  This information is extracted from GPRMC and TIM-TM2 messages.  As you can see the falling edges of the pulse are occurring at exactly 0.2 seconds on the even seconds in GPS time so it looks like we have correctly configured the output pulse


Now that I have external events occurring at precisely known times, I can use these to test the RTKLIB code.   The u-blox example command files that I include with the demo5 executables already are setup to enable the UBX-TIM-TM2 messages, so there is no need to make any changes there.

The next step is to collect some base and rover data using the modified receiver as rover.  I did that, and then converted the raw .ubx files to rinex using the new demo5 version of RTKCONV.  The events appear with a time stamp followed by a 5 in the next field to indicate an external event as shown below.  The zero in the last field indicates it is a valid time mark.


The observation epochs are occurring every second, so notice that the event is being logged out of sequence with a one sample delay.  I did not see this with the Emlid data set example described above.  However, I do see the same delay  if I use the Emlid code to convert the binary file instead of my code.  I don’t know if the Emlid hardware has somehow been configured to avoid this sequencing issue or whether it can occur on the Emlid hardware as well.  I’ll get back to this in a minute.

Next I ran RTKPOST to calculate a position solution.  With the new code changes, a *.events.pos file is generated in addition to the *.pos file.  It is the same format as the *.pos file but contains the event positions instead of the observation epoch positions.  Note, that it will be generated for absolute solutions (XYZ,LLH) LLH but not for relative (ENU) solutions.

I first did this with the Emlid code and got the following result when plotting both the position file and event position file.


The events are occurring at the correct times, but note that unlike the previous example, the positions are not being correctly interpolated between the two closest observation epochs.  In fact, if you look carefully you will see they are being extrapolated from the two previous observation epochs.  This is most obvious in the N-S axis points and is occurring because the events are being logged out of sequence.

To fix this, I modified the interpolation code to use the nearest observation epochs even when the event logging was delayed by one sample.  Here is the result using the latest demo5 b30 code.


Looking at the time stamps from the position log and the event position log, shown below, you can see that the observation epochs are occurring on the integer seconds and the events are occurring 0.2 seconds later on the even seconds, all in GPST time, just as we set them up to occur and verified with u-center.


So I don’t fully understand why the time stamps are appearing out of sequence with the CSGShop M8T data and not in the Emlid M8T data.  It may be that Emlid has configured the hardware somehow so this can not happen.  If this is true, then there should be no issue using the Emlid RTKLIB code with Emlid data but be careful using it with data from other hardware.  If anybody has any additional insight into this discrepancy please leave a comment.

I should also mention that all these code changes are in the core code so are present in both the command line apps as well as the GUI apps.  The most recent demo5 executables (b29e) do not contain the fix for interpolating delayed events and will function the same as the Emlid code.  The Github respository does have this fix.  The fix will also be in the demo5 b30 executables which I hope to release soon.


35 thoughts on “Event logging with RTKLIB and the u-blox M8T receiver”

  1. Do you know if it’s normal, that an M8T syncs for RTK, but then if it’s turned off and then syncs again the coordinates taken relative to each other (between the first sync and the second sync) are slightly but noticeably off?

    Liked by 1 person

    1. Hi Epigramx. This should not happen if both positions are fixed, especially to relative coordinates between base and rover. Depending on how the base location is determined, the absolute position of the rover might change if the base position is being recalculated with standard precision. One possibility is that the configuration parameters have been adjusted such that you are getting frequent false fixes.


    1. Hi Dicky. The image in the post shows the pin-out for the CSGShop M8T receiver. I simply connected the TIMEPULSE pin to the EXTINT0 pin. Other u-blox based receivers may or may not give access to these pins.


  2. Hi Tim,
    first of all thanks for your great work in this blog. You helped me so much when starting with RTK GPS. As I want to log some Events during kinematic measurement now, I found this article about Event-Logging. I still have some questinon about it:
    Do you know of a posibility to log Events triggered by the USB-Connection? As my M8T Module just hast USB and the Basic RX, TX, SDA, SCL and GND ports (https://www.gnss.store/gnss-gps-modules/45-ublox-neo-m8t-time-raw-receiver-board-with-sma-rtk-ready.html) I can’t find any solution on how to trigger the extint port.
    The other intersting thing I stumbled upon was the button “Marker” in RTKNAVI. Does this have anything to do with event logging or what’s the Purpose of it? I sadly couldn’t find anything about it in your blog or GitHub-repo.
    Thanks again for your help and best regards,


    1. You are correct that the USB version of the M8T receiver from GNSS Store (previously CSG Shop) does not have a pin for EXTINT, only the UART version from them does. I don’t believe there is a way to record events through the USB port. If there were it seems like they would be very imprecise.

      The Marker button in RTKNAVI puts a comment into the position file when pressed so is somewhat related to event logging but again would be very imprecise.


      1. Hey, thanks for your fast reply.
        With your help I was able to set these marking points in the solution file. As they are only set as I comment I guess I can’t show them in rtkplot, Right? And it’s probably also not possible to “transfer” them to a new position file created with rtkpost? The precision is probably not exactly on Point, but for my case it would still be good enough, therefore remembering some timestamps for rtkpost would be quite usefull.
        (Use case: Measure consistently and walk some steps between fixed Points to get their coordinates. In this case the exact timing doesn’t have to be exact, but to see when/where I reached each point by setting a marker would really improve the workflow.)


        1. Hi Florian. I haven’t used the marking point capability in RTKNAVI myself but as far as I know the feature is limited to just adding comments to the solution file as you describe. I also don’t see any additional info in the RTKLIB manual about any functionality beyond that.


  3. We have collected event logs with the F9P and processed with b33c and experienced some unexpected behavior. The event points are far away from the trajectory itself and seem to be somehow randomly distributed around the flightpath. The following link contains the .ubx files (there are two helix antennas, connected to two F9Ps, what are connected to each other via Pixhawk 2.1 to have GNSS based heading estimate, the package also contains an APM log and the Virtual reference station RINEX files): https://we.tl/t-FbJ9TjxY85


    1. I also looked into the .ubx file – according to my calculation there are 151 rising edges detected (= no. of picture) but there are 166 falling edges, moreover the accuracy estimate message is present 178 times.


    2. Hi Balent. I looked at the observation file from your data. What I am seeing is that the events are being reported with an 18 second offset from the observations as shown in this example from your file.

      2020 6 24 12 7 18.3778107 5 0
      2020 6 24 12 7 36.5860000 0 43
      S23 33954206.404 1 178430559.690 2

      18 sec is the offset between GPS time and UTC time so I suspect you have the event logging configured to report UTC time instead of GPS time. You can set this with the CFG-UBX-TP5 command as shown in the post. RTKLIB can not properly handle the logged events if they are in a different time frame from the observations.

      Liked by 1 person

      1. Thanks for the find Tim! Next time we will make sure to have GPST on all observations. On the other hand the rising and falling edge difference is still interesting, I will post it on the Ardusimple forum, maybe someone encountered it before.


      2. The current Ardupilot configuration sets the config messages, so even though we set GPST in ucenter it was set back to UTC when we connected the board to Pixhawk.


  4. Hi, thanks for the great post and resources!

    I have a small issue though with events.pos output with F9P ubx receiver and i’m probably doing something wrong.

    Here is the case.

    I have ubx log file from the drone (rover) and observation file from base station. I first convert ubx to rinex with command “convbin -f 2 -od -os -oi -ot rover_filename.ubx ” . After that i run postprocessing with command “rnx2rtkp -h -t -f 3 -p 2 -o output.pos -l lat lng height rover_filename.obs base.20o rover_filename.nav”.

    The output.pos seems to be good, i have fixed solutions and it plots correctly (both timestamp and coordinates look good). However, output_events.pos is not ploting expected events, it recorded just list of some “arbitrary” logs with wrong timestamp and location. I’m really not sure why is that.

    I know it’s difficult to troubleshoot just like this but do you maybe have idea what could i be doing wrong and what should i check? I’m out of idea as this is quite new thing for me.

    Thanks 🙂

    P.S: I’m using your latest RTKLIB distribution with updates for f9p receiver.

    Liked by 1 person

    1. Hi Ivan. I have not tested event logging in the demo5 code with the u-blox F9P, only the u-blox M8T but I would have expected it to work fine with the F9P. Can anyone else report on their experience with event logging on the F9P either positive or negative?

      Liked by 1 person

  5. Hello!

    Any chance of getting the data you used for these tests?
    I can’t find it on the Emlid forum, and I really want to try this out.

    Also, thanks for working on RTKLIB, it is really useful! 🙂


  6. Thank you Paul
    I mean can I use time-based integration
    So.. we need a preview time Mark event logger
    And Camera time that already setup same as GPS time


    1. Hi Catur,
      If you want to manually tag locations, you can do this by connecting a normally open switch between EXTINT0 and GND. EXTINT0 has an internal pull-up resistor. Whenever you push the switch, a TIM-TM2 message will be logged in the data (provided you have enabled TIM-TM2 messages first). It will log both the falling edge (when you push the switch) and the rising edge (when you release the switch). Tim’s code will extract the time of the rising edge.
      This will work with my RAWX_Logger code for the Adalogger too as the code enables TIM-TM2 messages.
      You might want to connect a small capacitor across the switch contacts to help de-bounce the signal. 10nF should be perfect.
      Best wishes,


      1. Dear Paul
        Please more detail about implementing the event mark or push on switch with your RAWX_logger Code
        I mean should we add some line in your coding?


        1. Hi Catur,
          Please try connecting a push switch between EXTINT0 and GND on the CSG Shop board, collect some data while occasionally pressing the switch, and then use RTKLIB to analyse the results. You do not need to add anything to the RAWX_Logger code, the TIM-TM2 messages are already enabled.
          (You will learn much more if you try things for yourself before you ask for help.)
          Best wishes,


  7. Hi Tim,
    In the M8 protocol specification it mentions that the delay figures given in CFG-TP5 are applied to the time results for TIM-TM2. Perhaps the delay values are different for the Emild configuration vs CSGShop?
    Best wishes,


  8. Hi, I appreciate your great efforts and smart observations. I like your work.
    I played with demo code 5 b29e and I have a few observations.
    When processed with demoCode,some of the events are missing in the event.pos file.
    Emlid RTK lib also has this problem of missing events, but more number of missing events with democode.

    One more observation of missing events in EmlidRTKlib is , events are missed when time gap between event and observation data is less then 5ms, I guess its some time resolution error.


    1. Hi Flint. Events are limited by the M8T hardware (and RTKLIB code) to one event per observation epoch. If you are sampling at 5 Hz, then the time gap between events should be at least 200 ms. This should be the same for the Emlid code and the demo5 code. If you are seeing differences between the two codes, I would be interested in seeing an example if you don’t mind emailing the data to me.


      1. Hi Flint. Your rinex file was from a ComNav receiver and included a set of event observations for each event. RTKLIB is not setup to handle these. I modified the code to discard these extra event observations and interpolate as is done for the events in the RTKLIB generated rinex files. I’ve checked the modified code into the demo5 repository. It will not discard the extra observations if they are within the timing tolerance (DTTOL) of RTKLIB, so for best results, set DTTOL to a very low value (e.g. 0.001). This is defined in rtklib.h and you will need to rebuild the code after modifying this.


          1. Hi Flint. The ideal solution would be to use the event observations to generate the event position instead of interpolating from the adjacent epochs but RTKLIB is expecting evenly spaced samples and is not set up to handle the intra-epoch observations. Discarding the event observations is the best I could do with a simple solution.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: