Counterfeit M8N modules

I had a few  comments recently on counterfeit u-blox M8N modules so I thought I would take a closer look at some of my receivers to see if I could spot any fakes.

Here is a photo of the module label for a unit from CSG, the most expensive M8N receiver I have and based on their reputation, the one I have the most faith that it is genuine.

csg_ubx

 

Here are photos from two of my other receivers.  The on on top is from a GYGPSV5-NEO I got from ebay.  As far as I can tell this one is genuine as well since the label looks very similar.  Performance-wise, it is also indistinguishable from the CSG unit.

real_ubxfake_ubx

The photo on the bottom is a from a very inexpensive M8N based receiver I bought recently on ebay but have not used.  They didn’t even try very hard to make it look real!  The font is different, the QR code is different, the copyright symbol is a completely different size.    I don’t think there is any question that this is a fake.  I have not used this module so I don’t know how well it performs compared to the genuine modules.  It’s possible it works just as well, I don’t know.  I also didn’t take off the module cover and look inside but I would assume it has a real ublox M8030 chip inside.  Apparently some of the fake units cut corners on some of the other components inside such as the size of the flash.  Here’s a photo of the unopened unit.

neom8n_dg

 

I did open up one of my GYGPSV5-NEO receivers that I had accidentally damaged by using 5 volts on the UART lines instead of 3.3 volts.  This is what it looked like, in case anybody is curious.

inside_ubx

 

On another note, I have just updated the demo5 executables on my website.  The new code is merged up to RTKLIB 2.4.3 b26 and now matches what I have on my Github page.  It includes the changes I described in my last post as well as a change for post-processing “combined mode” that I will describe in a future post.

Pseudorange corrections for the u-blox TRK-MEAS command

When configuring u-blox GPS receivers to output raw pseudorange and carrier phase data, we normally use the RXM-RAWX command for the M8T receiver. For the M8N receiver, since it does not support the RXM-RAWX command, we normally use the undocumented TRK-MEAS command instead. These are what the “xxx.cmd” scripts in RTKNAVI or STR2STR are doing when starting up the receivers.

Something I did not realize until fairly recently was that the M8T also supports the TRK_MEAS command and furthermore, both commands can be enabled simultaneously.

This is normally not a good thing to do since it confuses the RTKLIB decode apps and will result in a cycle slip reported for every epoch. In fact I first discovered the capability to run both at once accidentally by running the M8N “cmd” script on an M8T after previously running the M8N script. I then spent an embarrassingly long time figuring out why the data was so garbled. If you ever see two outputs in your observation file for every epoch, this is probably the cause.

But, for learning purposes, this is actually quite an interesting configuration because it allows us to directly compare the TRK-MEAS output to the RXM-RAWX output and verify if the two are providing the same information.

To do this experiment I first combined the two command scripts to create one that would enable both raw measurement commands. I then collected some data with an M8T receiver using this script to configure the receiver. Running an unmodified version of RTKCONV on the resulting raw output file allowed me to confirm I was collecting output from both commands. Here’s one epoch from the observation file with output from both commands. I’ve deleted some of the satellites to make it easier to read. The last column is SNR which is reported with a resolution of 0.25 by the TRK-MEAS command and 1.0 by the RXM-RAWX command which makes results from the two commands easy to distinguish.

trkmeas1

Psuedorange and carrier phase are the two 13 digit fields. At first glance, the two command outputs look quite different. This is at least in part because the TRK-MEAS command reports transmission time rather than pseudorange which RTKLIB converts to a sort of pseudo-pseudorange by subtracting an arbitrary constant time off each satellite in the epoch. This error will be removed later as part of the receiver clock offset so it can be ignored. It will be constant for all satellites so we can determine it’s value by removing the common offset between all satellites.

My analysis tools don’t have an easy way to separate the two sets of data from the combined observation file and I also wanted to run solutions on each data set separately so rather than work with the combined file I chose to modify RTKCONV to separate the two sets of data. I compiled two temporary versions of this app, one with the TRK-MEAS decode function disabled and one with the RXM-RAWX decode function disabled. I then ran each on the combined raw data file to create two observation files, one with the TRK-MEAS output and one with the RXM-RAWX output.

Here’s the difference between the pseudorange measurements from the two commands, the top plot is the GPS and SBAS satellites and the bottom plot is the GLONASS satellites. In both cases they are actually differenced with a reference satellite (GPS) to remove the common clock error mentioned above.

trkmeas2

What this plot shows is that once the common error is removed, the pseudorange outputs of TRK_MEAS and RXM-RAWX are identical for the GPS and SBAS satellites but differ by constant integer number of meters for the GLONASS satellites.

Halfway through this exercise I remembered someone had left a comment a few months ago with a link referencing something similar. At the time I hadn’t fully understand the significance of the comment but going back to it I realized they were talking about exactly the same thing. The link was to the OpenStreetMap project and this is the table from the link. Apparently someone there must have done a very similar experiment and their results match mine exactly.

trkmeas3

It turns out, not surprisingly, that the integer offsets correspond directly to the carrier frequency of each GLONASS satellite, and the above table can be expressed more concisely that way. They also found that the integer offsets are different between the 2.30 u-blox firmware and the 3.01 firmware which is what the column titles refer to.  My M8T receivers are running the 2.30 firmware.

trkmeas4

I find the arbitrariness of the numbers in this table quite strange but the data suggests very strongly that they are real. If they are real and unchanging then they can quite easily be corrected in the RTKLIB TRK-MEAS decode function. Of course, the data only shows they are different, it doesn’t show which is correct. It seems more likely that the RXM-RAWX would be more accurate since it is the documented command, but we can verify this.

To do that, I ran solutions for both data sets. In the plot below, the yellow/green trace is the solution for the RXM-RAWX data, and the green/blue trace is the solution for the TRK-MEAS data. The pseudorange measurements will have a steadily diminishing effect on the solution as the kalman filter converges and the carrier-phase measurements start to dominate. What this plot shows is that the initial errors, when psuedorange dominates, are smaller in all 3 axes with the RXM-RAWX data and presumably because of this, the fix occurs earlier with this data.

trkmeas5

I then modified the TRK-MEAS decode function in ublox.c to include an adjustment to the pseudorange measurements based on the values in the table above. Rerunning the solutions with this change gave the following result. As you can see the two commands now give virtually identical solutions.

 

trkmeas6

It would not be very useful if this correction to the TRK-MEAS results applied only to the M8T and not to the M8N, but since the two modules share the same hardware, it is very likely that the corrections apply to both.

I had collected some data with an M8N receiver running 2.01 firmware at the same time I collected the M8T data above, so let’s take a look at that data next to see if we can confirm this. I converted the M8N TRK-MEAS raw data to two sets of observation files using the unmodified and modified version of RTKCONV to give uncorrected and corrected measurements. I then ran solutions on both sets of data.

In the plot below, the yellow/green trace is the solution for the corrected measurements and the green/blue trace is the uncorrected measurements. Again all three axes show smaller initial errors with the corrected measurements, although in this case it didn’t result in an earlier fix. On average, smaller position errors result in earlier fixes, but the correlation is not 100% and the fix times tend to be quite discrete so I believe the reduced initial position errors are significant even though they did not result in an earlier fix in this particular example.

trkmeas7

Just to be sure though, let’s dig in a little deeper to see if we can find some more convincing data.  Let’s look at the pseudorange residuals first.  We would expect that reducing errors in the GLONASS pseudorange measurements should be most visible in the pseudorange residuals.  Plotting the pseudorange residuals for just the GLONASS satellites, uncorrected on the left, corrected on the right confirms this.

trkmeas9

The same plot for the GPS satellite pseudorange residuals shows little change between corrected and uncorrected, again as we would expect since we have not corrected those.

trkmeas10

All of this is quite encouraging and suggests it would be worthwhile to add this correction feature to the code. So I’ve gone ahead and done this to the demo5 RTKLIB code by adding a receiver option for the u-blox receivers. Receiver options are entered from the “Options” menu from RTKCONV or RTKNAVI and from the command line with CONVBIN. Below is an example of setting the new option with RTKCONV. The name of the option is “-TRKM_ADJ” and it is set to “2” to apply the 2.01 or 2.30 firmware offsets and “3” to apply the 3.01 firmware corrections. (Note:  the second dash in the option specified in the image below is incorrect, it should be an underscore.)

trkmeas8

The options used by RTKLIB during decoding are listed in the header of the observation file so you can verify which options were used by looking there.

This change should help the M8N solutions get to a first fix quicker and more reliably.

I’ve already uploaded the source code changes to my Github page and plan to update the executables soon.

 

New website

My previous post is actually part of a new website I am in the process of building to eventually replace this blog.  It’s been nearly a year since I started this blog and while it has been a good experience, I am starting to feel the blog format can be somewhat limiting.  A website should make it easier to organize and maintain the existing information and also allows for  better upload and download capabilities for code and data.   It will be intended more as a general resource and less of a description of my own personal experiences but I will also continue to post what I’m up doing to my blog, either as part of the website, or link to it from there.   I haven’t figured out exactly how to integrate the two yet.

However, the most important reason I’m making the change is to try and migrate to a much more user-interactive experience.  A place where every reader can have their own page and can describe what they are doing and communicate with others rather than just read about what I am doing.  The only similar forum with high activity that specializes in low-cost precision GPS that I am aware of is the Emlid forum, and while it is very good, it is obviously intended just for users of their products.  I’d like to create something somewhat similar, but to serve a broader audience to include any hardware, software, or application related to low-cost precision GPS.  I want to find out what everyone else is doing with RTKLIB.

The website is not quite ready for prime time but it is getting close.  If you’d like to check it out you can go to rtkexplorer.com and let me know if you have any ideas or suggestions to improve it.  I took the “lib” out of the name partially to make it easier to remember but also to broaden the potential scope beyond RTKLIB.

 

Selecting a GPS receiver (M8N vs M8T)

 

[This is an updated version of my very first post with more info about the differences between the M8N and M8T]

Selecting a GPS receiver

The first thing you will need to begin your journey into low-cost precision GPS is a receiver that provides access to the raw GPS position signals;  pseudorange and carrier phase.  There are only a few low cost GPS chips that provide these signals.  I chose the u-blox receivers because they seem to be the most available and lowest cost option out there.  Also I was able to find examples of other people successfully using them with RTKLIB, including Tomoji Takasu, the author of RTKLIB (see here).

The NEO-M8 series is the latest generation from Ublox.  There are three basic versions of the chip, the NEO-M8N,  the NEO-M8T, and the NEO-M8P.  The NEO-M8P uses u-blox’s own integerated RTK (real-time kinematics) solution and is significantly more expensive than the other two.  I have not worked with this version and don’t know anything about it.  Assuming you plan to use the RTKLIB open-source software to process the raw GPS signals, then you will want to choose between the M8T and the M8N.

NEO-M8T

The NEO-M8T is more capable and more expensive than the NEO-M8N.  Unlike the M8N, it is specifically intended to be used for precision positioning and officially supports output of the raw signals.  The current firmware supports the GPS and GLONASS satellite systems and newer firmware should be available soon to also support the Galileo system.

The best source for a M8T based receiver that I am aware of is from CSG Shop for $75.  It has a USB interface which means it can easily be connected directly to a computer without any kind of adapter.  It does not come with an antenna but CSG also sells a u-blox antenna for an additional $20.  I have had good results with this antenna and would recommend it.  Assuming you buy two units, one for a base and one for a rover, this setup will cost just over $200 with shipping.  If you are looking for maximum performance and easy setup, and the $200 is within your budget, I would recommend this choice over the M8N.  Here’s a photo of the receiver and antenna from CSG.

UBLOX NEO-M8N GPS GNSS receiver board with SMA for UAV, Robotsantenna

Another M8T-based option, if you are looking for a more integrated solution and willing to spend a little more is the  Emlid Reach.  This is a pair of M8T receivers combined with Intel Edison SBCs with wireless and bluetooth as well as higher quality Tallysman antennas for $570 for the pair.  It uses RTKLIB for the GPS solutions but also includes an additional layer of code to make setup and use easier for the average user.

NEO-M8N

If you’d prefer a less expensive choice than the M8T and are willing to accept a few compromises then you should consider the M8N.  The NEO-M8N chip does not officially support output of the raw GPS signals but can be configured to do so with undocumented and unsupported commands over the serial port.  These commands are no longer available in the latest firmware (3.01).  However most units shipping today still have the older 2.01 firmware and so still work.  Also, the firmware can be downgraded from 3.01 to 2.01 if you did end up with a receiver with the newer firmware.  The older firmware does not support Galileo.  Going forward, as that system becomes more capable,  this will become a more significant disadvantage of the M8N receiver.

Performance-wise, the M8N and M8T are based on the same core and for the most part are very similar.  There is one noticeable difference however in the way the M8N processes the GLONASS measurements.  Without getting into too many of the details, the issue is that normally when using two identical receivers, the GLONASS satellites can be used to solve the integer ambiguities, but with the M8N this is generally not true because of some additional error terms.  I have added a partial fix to my public branch of RTKLIB to calibrate out these errors after first fix.  If you are using the standard 2.4.3 version of RTKLIB, though, you will not have this capability, and either way you will not have this for the initial acquisition which means it will take a little longer with the M8N to get a good fix.

Most of the inexpensive M8N receivers are intended for use in drones and use a UART interface rather a USB interface.  This means you will need an FTDI type adapter to translate UART to USB and most likely will need to solder a few wires to get this hooked up.  You will find many choices available online for $15 to $40 per receiver including shipping.  These usually include an inexpensive, lower-performance antenna.  You will have to add $5-$15 for the FTDI adapter.  Still, you should be able to put together a pair of receivers fairly easily for under $75, less than half the cost of using the M8Ts.  If you are willing to wait for parts from China, you could do it for less than $50 for the pair.  Although not quite as capable as the M8Ts, if you are careful to collect good quality data and include a little more time for initial acquire, much of the time the results will be indistinguishable between the M8N and the M8T.

I have experience with three different M8N based receivers and have gotten good results with all three.  The first was from CSG Shop and while a perfectly good receiver I would not recommend it because the price is only ten dollars less than the M8T so if you are going to go that route, get the M8T.

The second receiver I have used is intended for drones and is marked as a GY-GPSV3-NEOM8N.  It is available from several suppliers, I bought it on Ebay for $25.78 including antenna and shipping.

The third type of receiver I have used is very similar but includes an on-board magnetometer.  It is labeled as GY-GPSV5-NEOM8N and sells for about $5 more than the GY-GPSV3-NEOM8N and is also available from multiple sources.  The magnetometer can be useful for collecting additional information about heading and orientation but I have not used it much yet.

Here’s a couple of other M8N receivers worth considering.  I have ordered both of them but have not had time to evaluate them yet.  For the very lowest cost and with an integrated receiver/antenna package, the unit on the left from ebay, shipped from China is  $16.65 including shipping.   The Reyax RY835AI unit on the right includes an accelerometer, gyroscope, and magnetometer with onboard antenna, all for $18.99 from Amazon Prime  (thanks to Ken McGuire for this suggestion).

[Update 12/6/16:  I have not tested the unit on the left yet but have verified the M8N module is counterfeit based on inconsistencies between the labels on this module and my other modules.  Preliminary testing of the Reyax unit was disappointing for me with low satellite count and low SNRs.  I suspect it may be because the antenna is passive unlike my other receivers that all have active antennas, but Ken has shown data with his receiver that looks much better so I’m not sure why the differences.  He has extended the ground plane on his unit but that doesn’t usually have a large enough effect to explain the differences I see.]

 

neom8n_dg 81yneho8uxl-_sl1500_

 

In summary, I would recommend the M8T receiver with a u-blox antenna for someone that has a specific application in mind and is looking for maximum performance and ease of setup.  However, the M8N with included antennas is how I got started and I still think it is a good choice for anyone that just wants to explore the capability of precision GPS without spending a lot of money.  It could also be a good choice for someone planning on building multiple units for a more price-sensitive application and is willing to work within it’s constraints.   Combining the M8N with a u-blox or other external antenna is another possibility that will put you somewhere in the middle for both capability and cost.

Demo5 code features

I’ve had a couple questions about what’s different between my demo5 code and the 2.4.3 release code. Here’s a list of what I think are the significant differences.  Any changes that I have made but have then been ported back to the release code are not included here.

 1 Calculation of GPS Solution (RTKNAVI, RTKPOST, RNX2RTKP)

1.1 Significant Functional Differences

(1) The kalman filter state update has been re-written to remove all the zero-element multiplies. This significantly reduces the computation time when receiver dynamics is enabled.

(2) Code has been added to calibrate and manage inter-channel biases for the GLONASS and SBAS satellites based on an extension of the fix-and-hold method (direct feedback from the ambiguity resolution results to the kalman filter states).  This enables use of the GLONASS and SBAS satellites for ambiguity resolution with the M8N receiver or when the base and rover receivers are not identical.

(3) Integer ambiguity resolution has been enhanced to include up to three attempts per sample to resolve the ambiguities using different combinations of satellites. Additional attempts may remove GLONASS and SBAS satellites and/or remove newly acquired satellites depending on various conditions.

(4) Additional adjustable constraints for ambiguity resolution have been added to help minimize the chance of false fixes.

(5) The common component of the phase-biases has been moved to a separate variable instead of spreading it out among all the satellites. This makes the phase-bias states easier to interpret during debug and also removes some issues with improper adding of cycles from satellites with different carrier wavelengths.

(6) Comments have been added to most of the core positioning algorithm code.

(7) The trace output has been enhanced and modified to provide more relevant information for debugging poor solutions.

1.2 Additional Input Parameters and Options

(1) pos1-posmode = static-start: Begins solution in “static” mode but switches to “kinematic” mode after first fix. This mode will normally acquire first fix faster than kinematic mode if the rover is stationary but will fail if the rover starts moving before the first fix.

(2) pos2-gloarmode = fix-and-hold: Extends the fix-and-hold method to calibrate the inter-channel biases for the GLONASS satellites and similar errors for the SBAS satellites. Note that fix-and-hold feedback only occurs after the first fix.

(3) pos2-arfilter = on,off: Rejects new or recovered satellites from being used in ambiguity resolution if the AR ratio was significantly degraded by their addition. This is an alternative or enhancement to using the blind delay of “arlockcnt” since the satellite will only be left out of the solution as long as necessary instead of for a fixed length of time.

(4) pos2-arthres1 = x: Integer ambiguity resolution is delayed until the variance of the position state has reached this threshold. It is intended to avoid false fixes before the kalman filter has had time to converge. If you see AR ratios of zero extending too far into your solution, you may need to increase this value. The “arthres1” option exists in the release code config file but is not used for anything.

(5) pos2-minfixsats = n: Minimum number of sats necessary to get a fix. Used to avoid false fixes from a very small number of satellites, especially during periods of frequent cycle-slips.

(6) pos2-minholdsats = n: Minimum number of sats necessary to hold an integer ambiguity result. Used to avoid false holds from a very small number of satellites, especially during periods of frequent cycle-slips.

 

2 Conversion from raw data to RINEX (RTKCONV, CONVBIN, RTKNAVI)

2.1 Significant Functional Differences

(1) The M8T raw output to cycle-slip translation algorithm has been modified to more closely match that of the M8N. This insures that a cycle-slip is flagged after every loss-of-lock and is not flagged until the carrier phase measurement quality is sufficient for resetting the phase-bias estimate.

(2) The half-cycle invalid bit is set for the SBAS satellites based on lock-time since the half-cycle invalid bit from the receiver is not functional for these satellites. This change has been made for both the M8N and M8T in the demo5 code but has only been ported back to the 2.4.3 code for the M8N receiver.

(3) The receiver measurement quality metrics for each sample are recorded in the RINEX observation files. The single character SNR field in the pseudorange and carrier-phase measurements are used for this purpose. The M8T reports quality metrics for both pseudorange and carrier-phase, the M8N reports quality metrics only for the carrier-phase. This is for information purposes only, RTKLIB does not use these fields.

2.2 Receiver Specific Options (U-blox)

(1) -STD_SLIP = x: Carrier phase measurements are flagged as cycle-slips if the standard deviation of the carrier phase measurement (as reported by the receiver) is greater or equal to x (scale=0.04 meters/count). This feature now exists in both  the 2.4.3 and the demo5 codes but is not listed in the 2.4.3 documentation. It is only used for the M8T receiver. If this option is not set, then the same fixed threshold will be used for cycle-slips as for valid carrier-phase measurements, which in the release code can cause cycle-slips to fail to be flagged after the phase-bias estimate is valid.

Issue with u-blox USB drivers

 

I ran into an issue with the u-blox USB drivers on Windows yesterday that ended up costing me a fair bit of time.  I thought I’d share it here in the hope it may help others that may be running into similar problems.

U-blox has recently switched from using a COM port driver to using a “sensor device driver” on Windows.  This seems to have caused some problems and does not appear to be fully functional yet.   They have published a flowchart on their website to help users decide whether to use the new drivers or not and how to rollback to the standard windows drivers if necessary.  It is not so easy to find it by going directly to their website, at least it wasn’t for me.  I only found this document through a Google search while looking for other people who had also run into this problem.

Here is a copy of the document but it may be too small to read here and may be out of date by the time you read this so I suggest you click on this link to take you to the original document.

ubloxdriver

I don’t understand all the implications of this change but I can explain what happened to me and what I had to do to fix it.

I first ran into the problem when working with two CSG M8T receivers, both with USB interfaces.  I had previously connected one of them to my computer but not the other one.  I wanted to be able to communicate with both receivers using the u-center eval software and RTKNAVI.   After plugging in USB cables from both receivers into the computer, the receiver that had been previously connected appeared as it usually does as a COM port but I was unable to see the new receiver with either program.

[Update 11/29/16:  u-center actually does see the receiver but it is listed under “Sensor API” instead of “Ports” in the Receiver menu]

I am using Windows 10, and it appears that it had automatically downloaded the new sensor device driver for the new receiver but continued to use the old COM port driver for the receiver that had been previously connected.   Neither RTKNAVI or u-center seemed to be able to see the new receiver since it had not been assigned a COM port.

To access the new receiver I had to follow a process similar to what is described in the blue circle above.  First disconnect from the internet so Windows can’t find the new driver.  Then plug in the GPS receiver to the USB port.  If it hasn’t been plugged in before Windows will probably assign the standard COM port driver to it.  If it has been plugged in before but only recently, the new driver has probably already been downloaded and it will use the new driver.  If so, open Windows Device Manager.  The receiver will appear under “Sensors” instead of under “Ports” as it used to do.  Uninstall the driver using Device Manager, being sure to click the box that deletes the driver files.  Windows will then revert to the standard COM port driver and the receiver will appear in the Device Manager list under “Ports”.

This is what we want but if we leave it like it is, Windows will download the new driver as soon as you connect back to the internet again.  To prevent this from happening we need to tell Window not to do this.   Do this by connecting to the internet, waiting for the new driver to download and the receiver to appear back under “Sensors”.  Then use Device Manager to “Rollback” the driver to the previous version.  This option is in the “Driver” tab in the Device Manager.

After doing this, both receivers appeared as COM ports and I was able to communicate with them with RTKNAVI but I still had trouble with u-center.  Unfortunately I am a little less clear about what I had to do to get this working again.  I suspect rebooting may have been enough but I ended up also downloading the u-blox Virtual COM Port driver and installing that (as describe in a different step in the flowchart), so it’s possible that is also necessary.

If anybody else has a more complete understanding of what’s going on, maybe they can add some insight in the comments section.

[Update 11/29/16:  After going through this procedure again, I understand it a little better. Rebooting after modifying the drivers does appear to be enough to get u-center to see the receiver again under “Ports”.  Installing the u-blox Virtual COM Port driver is also another option instead of using the Windows COM port driver. However that option works with only one receiver at at time.  If you want to hook up two receivers simultaneously you will need the Windows COM port driver.]

Another Raspberry Pi RTKLIB project

After describing my simple Pi based data logger in my last post, I stumbled across this Raspberry Pi based GPS project on diydrones.com.  It uses an M8T receiver and includes a touchscreen GUI to manage RTKLIB.  It has downloadable files for 3D printing the case as well as an image file with all the code for the SD card (something I should probably provide with mine).

I haven’t looked at in great detail but it seems very intriguing and could be a good alternative to what I described in my last post if you are looking for something with greater capability.

Here’s a photo of the completed project.

rtkbase3