Stratum 1 NTP via RPi and GPS Hat: Indoor Antenna?

This will be a question for the ages, but in my case right now I live in an apartment - and I don’t have permission to mount a GPS antenna on the roof, even temporarily. (In fact, I asked, they said no)

I do, however, have a window that has a view to the skies on the front of the apartment that I live in. It’d have to sit on my network’s wifi to operate, but should still be ‘functional’. Is there any known complications trying to set this up with an indoor antenna? Asking because this is a ‘learning project’ for me, not an actual Stratum 1 NTP server I’m going to deploy widely, but still looking for some advice.

And for those who have had to set up indoor antennas, do you have any you would suggest with SMA connectors that would work for what I need? (I can feed external power to the uputronics board as well to make sure there’s sufficient power in it which I’d planned to do anyways)

I am not you or near where you are. Should work if you’re’nt useless. I heard the serial port on raspberry pis lacks dual edge detection. Almost all GPS mice lack PPS, USB or not.

I had some USB GPS mice that stuck to a piece of tape holding tape wrapped case scrap. The Navisys GR701-W worked reasonably well, the Quescan Q1064, and the GlobalSat BU-353 less so. The Beitian mouse is apparently incompatible with the case bling port I attached it to, and the DIY boards were too annoying to set up.

1 Like

I think the best resource for GPS / RPi is Building a Raspberry-Pi Stratum-1 NTP Server

Maybe it’s worth to take a look

I have two GPS Boards with PPS on my bench ready to build something once day-job leaves me alone for a bit (never?!). Initial testing indoors was that it will get 3d fix but of course be quite inacurrate and flaky. I am shopping for a good mini SMA puck.

A GPS doesn’t need to be mounted on the roof.
If you have a window with a clear view (no metal in the glass, many HQ-windows have gold in them!) then you should see a lot of sat’s that offer you signals.

Mine shows 15 in gpsmon and 6 in cpgs and PPS shows 0.00000xxx numbers.

If you see such numbers, that will mean your GPS behind the window works fine.

It will give you very high accuracy, however when weather will go bad, it means your accuracy can drop faster then a reciever on the roof.

On my roof there is often water when it rains, then I see accuracy drop.
But it’s not that bad.

I would not worry too much if you have plenty sat-signals that provide good PPS.

so oddly enough I have a “What the heck?” case with my pihat, possibly a config issue on my side.

I have no data from gpsmon and cgps, because for whatever reason the GPS data packets are not feeding into gpsd. EXCEPT, it is feeding PPS data in, and ppstest on the device shows a lot of 'clear 0.0000000000, sequence: 0numbers in the data from PPS directly. It is feeding straight intochrony` on my test bed (before I deploy this as a server of course) and is receiving the timepulse and PPS data.

No idea why gpsmon and cgps are not able to read the GPS data, I have a question open on the RPi stackexchange site, but I do at least have the PPA data coming in without issue, and getting timepulse still clearly.

So, I guess this works? I want to make sure the rest of the GPS hat functions work, but at least the PPS data works.

Given that the building I’m in is a 2 story apartment building with standard residential grade glass that probably is still from the building being made originally (building is dated to the 50s for the last major reno, building was built in the 20s), I’d say it doesn’t have gold in it. However, as I said i’m not getting any sat data but consistent PPS data, so it’s a headscratcher there.

Looks to me you made a config mistake, not reading all ‘servers’ correctly.

As PPS needs far more signal then NMEA-GPS, it seems to me your other /dev/xxxxxx isn’t being used.

Did you install GPSD and is it running? As the normal GPS signal is normal handled by GPSD and it can also PPS.
However PPS can also be handled by the kernel.

A typcal /etc/default/gpsd file looks like this, but you need to tell it what the GPS-device is.

# Default settings for the gpsd init script and the hotplug wrapper.

# Start the gpsd daemon automatically at boot time
START_DAEMON="true"

# Use USB hotplugging to add new USB devices automatically to the daemon
USBAUTO="true"

# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
DEVICES="/dev/ttyUSB0"

# Other options you want to pass to gpsd
GPSD_OPTIONS="-n"

It could be /dev/gps* or /dev/ama* or /dev/ttyUSB* you have to figure out what the GPS device is.
Then you tell GPSD that and it will start feeding GPS info.

More info here:

BTW, it looks to me your device is located at /dev/ttyS0 (serial-port 1), you may want to try gpsmon /dev/ttyS0 and see if anything happens.

Looks like this is a dual problem, part of it is the serial console being chaos.

Guides said to use /dev/ttyAMA0 but that’s Bluetooth, so I am using serial0 now and it’s working. gpsmon and cgps are all seeing data now. So that’s a plus. So now I’m seeing NMEA and PPS data.

I’ll have to run some Ethernet cable to make sure the thing isn’t stuck using wifi (wifi is evil and latency-prone) to make it usable. But it’s working now, so yay, I guess!

Thanks for your guidance @Bas - this got me in the right way to make the system parse the data properly. I DID however have to pass in -s 115200 into the GPSD_OPTIONS because the system couldn’t autoconfigure the baud rate (which is 115200 on the uputronics hat rev 6.1, which is a LOT faster than the thing auto-attempts, but that worked fine).

chrony is pointed directly at /dev/pps0 which is populating the PPS data from the hat signal, whether it’s kernel or not it’s happily chugging away with the PPS data. And it’s working with the SHM NMEA data now, which is another source that chrony can use. I’m going to probably set up a Stratum 2 on my network that populates directly from the Stratum 1 and then make that web-facing for NTP stuff, but I have a Stratum 1 now on my network.

So I played around this weekend and tested in a high rise condo in a concrete canyon

This one works OK but the battery it has to keep GPS almanac so you don’t need to cold start every time you reboot is soldered on. She’s a cheapy but works!

These guys usually QA their stuff well. It costs 3 x more than the previous one I mentioned. You need to solder on a battery holder (comes with it) and then install a CR1220 for warm starts. Nice because the battery itself isn’t soldered on. Not nice because CR1220 are super hard to procure at this site. (No issues in the US or EU though).

Neither of them worked well enough until I added this:

This was a game changer.

As for the software part I was using raspi OS 64 bit, the one based on Debian bullseye. Manual config was fun and all - following the various tutorials we have all seen I played with ntpd and chrony but then I came across this guy:

Results in a very clean install with chrony and gives you some guidance on how to calculate your offset.

Guides I have seen told me to disable bluetooth, claiming /dev/ttyS0 or /dev/serial0 to be less accurate then /dev/ttyAMA0

No idea what they were on about but I did it and now NMEA is on /dev/ttyAMA0

in /boot/config.txt:

# Use the /dev/ttyAMA0 UART GPS instead of Bluetooth
dtoverlay=disable-bt

It’s not wise to point it directly to /dev/pps0 as it’s passing the USB-subsystem and the kernel-module.
There is no need for that.
/dev/pps0 is faster BUT only when using RS-232 or PCI cards that have faster connections then USB.

I use chrony this way to do GPS and PPS:

refclock SHM 0 refid GPS offset 0.127 precision 1e-3
refclock SHM 1 refid PPS lock GPS precision 1e-9 prefer

I found that way to be a lot faster.

and it should look something like this:

Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
GPS                        34  15   527     +1.533      4.566  -6240us  1186us
PPS                         8   4   108     +2.681     12.039    +14us   193us

and:

MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
#- GPS                           0   4   377    19  -4425us[-4727us] +/- 1002us
#* PPS                           0   4   377    20    +14us[ -286us] +/- 8808ns

and:

Stratum         : 1
Ref time (UTC)  : Tue Jan 04 16:00:32 2022
System time     : 0.000089355 seconds fast of NTP time
Last offset     : +0.000219707 seconds
RMS offset      : 0.000403229 seconds
Frequency       : 399.905 ppm fast
Residual freq   : +14.563 ppm
Skew            : 1.673 ppm
Root delay      : 0.000000 seconds
Root dispersion : 0.000273 seconds
Update interval : 16.0 seconds
Leap status     : Normal

The card I’m using is GPIO serial directly on the device, it’s not a USB subsystem that I can tell with the Uputronics GPS/RTC pi-hat. (GPIO pin 15).

I’ll prod that and see how that works with the GPS and PPS as well, but i’ve started by pointing direct at pps0 because it’s serial directly. We’ll see how it works, and once I get everything finalized I’ll make a blog post somewhere about it for how I set it all up.

SHM 1 for PPS did not function at all, suggesting GPSd is not reading the PPS data properly, or some other chaos.

Since /dev/pps0 is serially attached, I’ll keep populating GPSd PPS data from /dev/pps0 since it’s direct serial and seemed to work without issue (since this is directly read from the PPS data on the hat on the RPi 400, which is direct from GPIO pin 15)

You never told us what device it was or how it’s connected and you mentioned

That made me think you where using an USB GPS.

It helps a lot to know the hardware before asking for help :grinning:

Glad it is solved and it should be pretty precise, way below 1ms when PPS is working.

topic title mentioned rpi and gps hat, but forgot to say in the details oops.

even so, thanks for all the help to all for getting me set up!

And as for accuracy, 138 nanoseconds is pretty good so.

That is PPS working alright :slight_smile: