Cheap 1-2cm (scale) accuracy for your surveys

3689647403?profile=originalImage: Topcon RTK collecting survey points

High precision GPS systems are getting more known and used and RTK is already becoming a familiar acronym. This post is about the use of RTK for collecting ground control points to be used in high quality survey results, not about RTK for navigation use (that's a lot harder). What I was looking for is a method to collect about 5 control points for surveys in a way that is cost effective, but also doesn't cost me a lot of time. I'm working in the tropics, so standing 30 minutes in the sun and dust is a real chore and not very comfortable. Here I describe how I do this using low-cost L1 GPS modules that cost ~$50 each with an additional ~$150 for a recording device and a good antenna.

If I were to use the above RTK station, I would get really good accuracy (L1+L2), but I would also spend > $20k that I'd have to recover from business income and I'd have to spend 5-10 minutes per point to get an accurate fix, since I only had one station. With many modules you also depend on a proprietary radio link, so you'd eventually have to buy two if you need to set up your own reference station somewhere.

First, let's consider there are two kinds of accuracy:

1 Absolute accuracy; the difference between measured and actual coordinates of the point in world space.
2 Relative accuracy; the difference between measured and actual offset of one point and a reference point in the survey area.

The second characteristic by itself is already extremely useful for high precision volume and distance measurements. All professional surveys have this characteristic, which is essentially the characteristic of correct scale. Absolute precision is only really needed when you want to exchange this data with other systems and/or use different data sets together (now and in the future). The absolute accuracy of a data set can always be improved after the fact by simply applying a unique global offset to all the data or control points in 3D coordinates (meters, inch, whatever).

In this approach, we're going to store the raw observations in a file to be processed together at a later point in time. RTK GPS has a plethora of online discussions and examples where you require some kind of radio or wifi link between modules, but this is not actually a prerequisite of the technology. Having files is much better, because you can work out the exact configuration and settings in the office and so you won't make any configuration mistakes in the field. Also, a radio/wifi link is extra interference for your uav and not to forget the GPS module itself and if those links drop out for a reason, you lose all the data and have to come back again.

What you record is raw GPS output data, straight from the module, so there's little that can go wrong. You get the best results if the frequency for all modules is equal, because sometimes the tools get confused if there's an output frequency mismatch. Since modules are set up as static, I just set this frequency to 1Hz for all modules. I myself purchased some ~$50 modules (NEO-6T from emlid), put them in the field with any device that can read the modules (uart/usb) and record the data to an HD, SD, etc. If all modules were recording in the same time period, you can post-process the raw GPS logs from the comfort of your office.

I use RTKLIB to do all that:

The process is:
1. select the dataset to be used as reference, call it REF
2. convert that to RINEX. Make sure to use the correct data source format.

To get high accuracy absolute positions from the field if you do not have an accurate reference yet, you can use PPP to derive it's position. This will give a higher absolute accuracy than a cellphone:
3. download the "SP3" file from the IGS data repository (available 3hrs-24hrs after the survey): ; (available 3-24hrs later).
4. post-process the reference point REF using "PPP static", "Precise" solution, "Iono estimate" and "ZTD estimate" and select the SP3 file together with the NAV and SBS file using rtkpost.exe. You can also use the CLK file, but in my case it actually hurt results. Some more research there is needed.
5. if you have ~30 mins of data, the processed solution should be accurate to about 70cm (absolute) and probably is better than a meter. If you need better accuracy, the only way to get this better with PPP is to keep the module longer in the field (6-24 hours). After that, it's very much a black art which gives best results, but some people report you should expect ~10cm. That's not 1-2cm for the relative accuracy.

6. Use either the calculated position or the one from your cellphone. Let's call that REF.
7. select the dataset (one of the other modules) to be used as "rover", let's call this ROVER here.
8. convert ROVER dataset to "RINEX" data format using the rtkconv.exe program. Make sure to set the right source data format (of the source file).
9. then use rtkpost.exe to post-process both files, applying the settings you'd use in rtknavi.exe and process away. You should insert the position from REF in the "antenna position" now in the settings dialog and use "static" as the mechanism for post-processing, probably with "continuous" instead of "fix and hold".
10. Eventually there should be a fix for a long period of time. You can then average that out or see how much the variation is and not bother further. It should be 1-2cm when modules were not far apart.
11. Repeat from 2 for the other modules.

This method is cost- and time-effective. With 5 modules, you'd spend $1000 (raspi+GPS+good antenna ~= $200) to be able to measure 5 control points at the same time without waiting 5-10 minutes for each one. You can drop them in the field prior to a mission, turn them on, walk back and execute the uav flight. If that took about 30 minutes to complete, you can already retrieve the modules and go back to the office for post-processing.

Here's a nice tutorial about PPP with rtklib, but some options only make sense when you have L1+L2 data:

I tested the above processing using a couple of well known reference positions of the local university, so the numbers of 1-2cm precision for RTK, 70cm PPP static are from such tests, however all tests were executed in one afternoon, so this doesn't give a lot of variance given the weather, ionosphere and solar activity. Actual results in the field will therefore vary, and vary per day too.

E-mail me when people leave their comments –

You need to be a member of diydrones to add comments!

Join diydrones


  • @Sobido, I thought the M8N didn't record raw?  I thought you would need the M8T to record raw.  If you are getting raw files from M8N can you please share how you do it.  Thanks,

  • I've used these Duinopeak NEO-M8N GPS Shield for Arduino with Antenna mashed together with STM32 Nucleo and Discovery boards to record hourly RINEX observation files directly to a Micro SD card.

    The TCXO's in the M8N series parts offer much better clock drift numbers over the crystal based NEO-6M, and the LEA-M8F parts the VCTCXO get tuned so the clock drift approaches 0 ns/s, according to the NAV-CLOCK messages, give super clean measurements.

  • @sobido

    Could you provide a little more info about your setup above for static post-processing? Id love to try building one of these. Thanks!

  • @Brandon


    If I understand your idea , you want to avoid Sd card and using 2 set of radios to send and stock raw signal directly on your computer.

    I don't think that it will be so good because you will necessary have trouble via radio and you will lose information.

    Also the RTK option seems to be a bit tricky on RTKLIB. I haven't test it perfectly ( I don't need it to take CGP, as Post treatment is fine for me) but it seems to be long to fix. Also I am disappointed with the range of the 3DR radio between a potential external Base and the tablet ( or the computer ) . I found just about 100m on a ground-ground relation. I should test with another type of radio like RF900+ , Jdrone (



    As far I am concern, for the CGP, I use a post treatment (on static mode on RTKLIB) with several  M8NGPS mount with a simple 3xAAA battery + Regulator+- 3.3V + Sd card datalogger + a ON/off switch ,  that I position on each CGP, before the flights .

    Here is a example of this mount:


    I also put an extra and independent M8N and a datalogger on the plane to be in the position to save the raw signal during the flight. ( + the 3DR gps in charge of the regulation of the flight, as usual). My experiment is that even if I have another source of track ( in addition of the traditional Logs ) , I have sometime some "holes" in the recording. I post treat ( with Internet RTCM)  also this signal to note something like +-5m of difference compare with 3DR Logs. But I can't know what is the best signal.

    When I put the two option on a photogrammetric software however, I noted that if I use the M8N track to geotag my photos then the error ( without using GCP ) is closer than after , with the GCP. ( I found once a difference of about 2 m with 3DR flog and about 30 cm when I use the M8N ) .  SO maybe the M8N help a bit , but I can't give any warranty.




    The result on a post treatment (with RTCM) should be better that 20cm. You should do better. When I test on a geodetic marker with a 30km RCTM, on a static solution,  I achieve less than 5cm in XYZ with about 20min or 30min in static position.


    jD-RF868Plus Longrange
    Long range telemetry set for all your UAV and UAS needs
  • Hi Brandon,

    Nice setup and thanks for sharing. I have not tested using kinetic between drone and ground station but would like to test it myself once I get some time. So, please keep us posted.

    Here is my setup. Something very simple to test the post-processing capabilities of the M8N and RTKlib. I have it all powered by a little USB battery (2600mAh - item in blue in photos). I have some little switches on the side to first toggle on power to the M8N and let it get a fix before I flip the other switch to supply power and begin logging to the SD logger. 

    I am amazed by this GPS and RTKlib. I set it up on a local monument and let it collect for 15 minutes or so. After post-processing using a nearby CORS station I was within 20 cm of the monuments published location. All for under a $100. Build several of them, put them out on some targets and let them collect data while you fly.



  • Well Gents (@Sobido @Carl @Gerard):

    I built five little M8N+SD Shield+Arduino data loggers. It was a bit tricky to get the raw data to log to the SD card correctly due to the small amount of memory on the Uno, but I eventually figured that out. The little buggers work like a charm. Except that the little patch antennas aren't great and writing to an SD card uses up batteries rather quickly. Have them wired up to a button to initiate logging and a few LEDs to indicate logging error or success.

    Then I got to experimentating with the kinematic idea....I know I should have stopped while I was ahead....The thought is that I should be able to use two sets of 3DR radios (I saw Sobido post about this elsewhere) to transmit data to and from the base station and rover to the laptop running RTKLib. This way I connect the base station and rover up in RTKNavi and see the status of the solution in real time rather than just hoping I'm getting good data. Also, I can use the log in RTKNAVI to record the raw data rather than using the SD card option. Instead of using five units, each with a SD card logger, Arduino, etc....I can just have two units with a few sets of 3DR radios and spend the extra money on better antennas. The result is below.

    3702095016?profile=originalI plan on reconfiguring the PVC to allow a plumb line to hang directly down from the antenna.

    Using these better antennas (Tallysman 3400), I'm getting way better SNRs than I did with the patch antennas that came with the M8N chips. I'm getting great results in static mode, but kinematic mode is not behaving. I don't maintain the fix long enough. Testing to continue, including testing some new M8T boards that should be coming in soon.

    Thanks for the inspiration again.


  • @brandon

    I have successfully used this tiny micro SD card logger from sparkfun that uses OpenLog:

    All I did was wire it up to the M8N eval board from CGS shop

    And she was logging away after getting the M8N all setup and configured for RAW output. I built a simple tuperware container to house it all along with a couple of switches to first power on the GPS and wait a minute for sat lock before flipping another switch to begin datalogging. I have it all powered off a small USB rechargeable battery that you might use to gain another hour for your cell phone. Works amazingly well.


  • @brandon


    I confirm you that I a using the 2.4.3 Rtklib to save M8N raw information.

    I don’t know about your solution with Arduino Uno and a Virtuabotix SD card reader/writer.

    The solution I used is different. I was using initially a Ardulog data logger + openlog V33 as software. I was almost correct but I found finally that the stability of the signal was not correct enough and I couldn’t save for more than 30min for instance. I finally used now the initial solution that I have explore with Ardulog Logomatic V2 ( This is a bit more expensive but it is work very well and very stable . It is also more plug and play than with the ardulog.

    SparkFun Logomatic v2 - Serial SD Datalogger (FAT32)
    The SparkFun Logomatic v2 takes everything we learned with logging analog or serial data from your projects over the years and boils it down to an ea…
  • @Gerard Toonstra


    I have managed to get raw data out of a M8N. I was able to use RTKNavi to record the raw data to a log from the M8N connected via a serial port. Then, using RTKConv I can get the raw data converted to .OBS, .NAV, and .SBS files. One very important note here...I spent FOREVER trying to get RTKLib v. 2.4.2 RTKNAVI to recognize the data to no avail. As soon as I switched over to the beta version (2.4.3) it worked. Hope that helps somebody.

    Now I am having some problems getting the raw data to record to an SD card and was wondering if you all had any suggestions. I'm using an Arduino Uno and a Virtuabotix SD card reader/writer. I'm able to see some gibberish inside the Arduino IDE serial monitor that looks very much like the gibberish in the previously mentioned log file that was produced by RTKNavi. Unfortunately, when try to record to a file on the SD card I don't get the same type of gibberish (still gibberish, but not exactly the same as what was in the Log and/or serial monitor).

    At first I was trying to use SoftwareSerial to read the GPS. I thought there might be a buffer issue or something so I switched over to the hardware serial pins, but that didn't seem to solve the problem. Any suggestions? If you wouldn't mind sharing the bit of code you used to log the data to the SD card that would be amazing.




  • Brandon,

    The image is a real RTK used to get ground truth for the positions. It depends on the environment whether antennas need to be slightly elevated. Any type of vegetation or trees can obscure the signals or decay them, which decreases results, so high grass is already problematic.

    So what you're describing is already a good procedure to deal with vegetation in certain environments. If you find slightly elevated structures of sufficient width and length, those can also be used, but obviously the photogrammetric calculations should be stable enough to plot points there, or the point will still be off. I wouldn't put any antenna on a 5-10cm wide wall for example, because the calculated points there aren't all that stable, but a concrete plate of 50x50 is good enough.

    In areas without vegetation or trees, you can just put the antennas on the ground.

This reply was deleted.