Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repository file and dirs reorgniazation / OLED fix and improvements #4

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 82 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,94 @@
[![License: GPL v3](https://img.shields.io/github/license/AndrewBCN/STM32-GPSDO)](https://www.gnu.org/licenses/gpl-3.0) [![License: CC BY-SA 3.0](https://img.shields.io/badge/License-CC_BY--SA_3.0-lightgrey.svg)](https://creativecommons.org/licenses/by-sa/3.0/)

# An STM32 GPSDO
Designing, assembling, programming and testing an ultra-low-cost GPS-disciplined oven controlled crystal oscillator / lab clock based on an STM32 32-bit ARM microcontroller

Keywords: STM32, GPS, GPSDO, crystal oscillator, frequency standard, atomic clock
Designing, assembling, programming and testing an ultra-low-cost GPS-disciplined oven controlled crystal oscillator / lab clock based on an 100 MHz STM32 32-bit ARM microcontroller

**Keywords**: STM32, GPS, GPSDO, OCXO, 10MHz, crystal oscillator, frequency standard, atomic clock

## Introduction

I have been following the thread by the late Lars about his inspirational DIY Arduino GPSDO project. And I checked the dozen or so GPSDO projects published on the net.
Then I decided to join the party and design and build my own.

I didn't quite know what I was getting into, but after a couple of months waiting for the parts to come from China, and then another couple of months writing the firmware, I have a working, blinking, timekeeping and happily and precisely oscillating GPSDO.

Like with Lars' design, any OCXO, DOCXO or even rubidium source can be used, but the recommended oscillator is an inexpensive used square wave 10MHz 5V OCXO, which is what I am using in the breadboard prototype. These OCXOs are available from various sources on the net, recycled from decommissioned telecom equipment and sometimes still soldered onto a piece of PCB, for around 10€ or less (< US $12). The OCXO is the most expensive part in this GPSDO.

André Balsa, April 2021
For Lars' design check following links:
- Original Lars' EEVBlog forum thread: https://www.eevblog.com/forum/projects/lars-diy-gpsdo-with-arduino-and-1ns-resolution-tic/
- GitHub project combaning all information in one place: https://github.com/AndrewBCN/Lars-DIY-GPSDO

The Project
===========
The second most expensive part is the GPS receiver module. I strongly recommend a u-blox Neo-M8 GPS module with an SMA antenna connector. With a u-blox Neo-M8, I am still getting 5~9 satellites even indoors in my basement lab. The much cheaper Neo-M6 struggles to get a fix in the same conditions.

I decided to build my own version of a 10MHz GPSDO with the following features:
- Very low cost i.e. < 30 euros ($35), short and easily purchased BOM.
- Acceptable performance (+/- 1ppb) "out of the box", can be fine tuned over time.
- Uses an STM32F411CEU6 "Black Pill" microcontroller module, programmed in C/C++ using the Arduino IDE (STM32duino).
- Requires only a 5V @ 1A power supply, supplied through a USB C cable.
## Features

I have decided to build my own version of a **10MHz GPSDO** with the following features:
- **Very low cost i.e**. < 30 EUR ($35), short and easily purchased BOM.
- **Acceptable performance (+/- 1ppb)** "out of the box", can be fine tuned over time.
- Uses an **100 MHz STM32F411CEU6 "Black Pill"** microcontroller module, programmed in C/C++ using the Arduino IDE ([STM32duino](https://github.com/stm32duino/Arduino_Core_STM32)).
- Requires only a **5V @ 1A** power supply, supplied through a USB C cable.
- Compact and portable.
- Optionally battery powered (allows taking it outdoors for optimal satellite signal reception).
- An optional suite of environmental sensors (temperature, humidity, air pressure, voltages, OCXO current/power consumption).
- An optional Bluetooth serial interface for wireless communication with a PC.
- **Optional modules**
- **BMP280** for atmospheric pressure and temperature monitoring,
- **AHT10** for temperature and humidity monitoring,
- **INA219** for OCXO power consumption monitoring,
- **HC-06** for wireless communication with a PC/mobile using Bluetooth UART.
- Extensive logging of various operating parameters to allow further software tuning.
- An optional small OLED displaying room temperature, UTC time, uptime, operating status, measured frequency.
- **New!** Optional UTC-aligned 1PPS output using a **picDIV**.
- It uses a digital **FLL (Frequency Locked Loop)**,
- **New!** It can also use a **PLL (Phase Locked Loop)**.
- **OXCO Voltage control** using a **16-bit DAC** provided by a **2kHz PWM** output pin on the STM32F411CEU6
- [A quick discussion of noise, DAC resolution and OCXO frequency control](docs/DAC_resolution_discussion.md)
- [Notes on using a software 16-bit PWM DAC instead of an external 12-bit I2C DAC](docs/DAC_STM32_16bit_PWM_notes.md)

## Resolution of 10MHz

| 10 MHz | | | 1 ppm (10^-6) | | 1 ppb (10^-9) |
|---------:|----|-------:|---------------|------:|---------------|
| 10000000 | Hz | 1E+06 | ppm | 1E+09 | ppb |
| 10 | Hz | **1** | **ppm** | 1000 | ppb |
| 1 | Hz | 0,1 | ppm | 100 | ppb |
| 0,1 | Hz | 0,01 | ppm | 10 | ppb |
| 0,01 | Hz | 0,001 | ppm | **1** | **ppb** |
| 0,001 | Hz | 0,0001 | ppm | 0,1 | ppb |

## Schematics

Latest (0.6.2 revision) schematics are available here: [EDA/Schematics-STM32-GPSDO-0.6.2.pdf](EDA/Schematics-STM32-GPSDO-0.6.2.pdf)

## The first breadboard prototype

The first breadboard prototype:
<img src="https://github.com/AndrewBCN/STM32-GPSDO/raw/main/GPSDO_breadboarda.jpg">
![GPSDO Breadboard Prototype](img/Prototype_GPSDO_breadboard.jpg)

![GPSDO Two Breadboard Prototypes](img/Prototype_TwoGPSDOs.jpg)

In normal operation this is displayed on the small OLED:
<img src="https://github.com/AndrewBCN/STM32-GPSDO/raw/main/OLEDv002i_expl.jpg">
![OLED display](img/Prototype_OLEDv002i_expl.jpg)

![Oscilloscope 10MHz Square Wave](img/Prototype_10MHz_cleantrace1a.jpg)

You can see it in action on YouTube video (click image below):

https://www.youtube.com/watch?v=mgoK4KuVDhw

[![A $35 DIY GPSDO - with an STM32F411CEU6 MCU](https://img.youtube.com/vi/mgoK4KuVDhw/0.jpg)](https://www.youtube.com/watch?v=mgoK4KuVDhw)

## Links

- GPS
- [Timing and Location Performance of Recent u-blox GNSS Receiver Modules by John Ackermann N8UR](https://hamsci.org/sites/default/files/publications/2020_TAPR_DCC/N8UR_GPS_Evaluation_August2020.pdf)

## License

- Software: **GPL-3.0**
- [![License: GPL v3](https://img.shields.io/github/license/AndrewBCN/STM32-GPSDO)](https://www.gnu.org/licenses/gpl-3.0)
- Hardware: **CC BY-SA 3.0**
- [![License: CC BY-SA 3.0](https://img.shields.io/badge/License-CC_BY--SA_3.0-lightgrey.svg)](https://creativecommons.org/licenses/by-sa/3.0/)


## Authors

- André Balsa, April 2021
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
Notes on using a software 16-bit PWM DAC instead of an external 12-bit I2C DAC
==============================================================================
# Notes on using a software 16-bit PWM DAC instead of an external 12-bit I2C DAC

To generate Vctl, the analog voltage that control the OCXO frequency, the STM32 GPSDO
uses either a $0.50 MCP4725 I2C 12-bit DAC module or a pair of rc filters (2 x r=20k,
2 x c=10uF) connected to a 16-bit, 2kHz PWM output pin on the STM32F411CEU6.

Only 4 lines of C are required to generate this 2kHz PWM signal:

```c
// generate a test 2kHz square wave on PB9 PWM pin, using Timer 4 channel 4
// PB9 is Timer 4 Channel 4 from Arduino_Core_STM32/variants/STM32F4xx/F411C(C-E)(U-Y)/PeripheralPins_BLACKPILL_F411CE.c
analogWrite(PB9, 127); // configures PB9 as PWM output pin at default frequency (1kHz) and resolution (8 bits), 50% duty cycle
analogWriteFrequency(2000); // default PWM frequency is 1kHz, change it to 2kHz
analogWriteResolution(16); // set PWM resolution to 16 bits, default is 8 bits
analogWrite(PB9, 32767); // 32767 for 16 bits -> 50% duty cycle so a square wave
```

Initially I was worried that the software 16-bit PWM DAC would not provide a clean Vctl to
precisely control the OCXO frequency, but after extensive testing I now believe it is a better
solution than the external MCP4725 12-bit I2C DAC module.

With the MCP4725 12-bit DAC the STM32 GPSDO stabilizes the OCXO frequency within +/- 1ppb
(that is +/- 0.01Hz).
But with the 16-bit PWM software DAC, the STM32 GPSDO manages to stabilize the OCXO frequency
within +/- 0.1ppb (a stable and accurate 10MHz +/- 0.001Hz), which is an order of magnitude
**But with the 16-bit PWM software DAC, the STM32 GPSDO manages to stabilize the OCXO frequency
within +/- 0.1ppb (a stable and accurate 10MHz +/- 0.001Hz)**, which is an order of magnitude
better and rather good performance considering the cost and simplicity of the hardware.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
A quick discussion of noise, DAC resolution and OCXO frequency control
======================================================================
# A quick discussion of noise, DAC resolution and OCXO frequency control

The STM32 GPSDO can use either an inexpensive 12-bit I2C DAC (MCP4725) module, or a couple of rc filters on one of the PWM pins of the STM32 MCU, to generate Vctl - the voltage used to control the frequency of the OCXO over a narrow range of 10MHz +/- a few Hz. The exact OCXO frequency provided by varying Vctl over a 0V - 4.4V range depends on the OCXO used as well as a number of different factors, but roughly speaking the precision of the OCXO frequency relative to a precise 10MHz is directly proportional to the precision with which we can set Vctl.

Expand All @@ -10,8 +9,7 @@ Back to the theory, the GPS receiver when locked with a good fix provides a 1PPS

So in theory if we measure the OCXO frequency based on the 1PPS pulse over 1000 seconds (1000 sequential measurements), the maximum measurement error should be < 0.001Hz, or 10E-10 or 0.1ppb. That's exactly an order of magnitude better than what our 12-bit DAC is capable of.

Using a 16-bit DAC provided by a PWM signal
===========================================
## Using a 16-bit DAC provided by a PWM signal

The above reasoning led me to test a 16-bit DAC built by connecting a pair of rc filters to the PWM output of the STM32 MCU. Because the STM32 timers are 16-bit timers, we can with four lines of C obtain a 2kHz 16-bit PWM signal from the MCU, which is converted to a DC value (plus a ton of noise) and hence provides us with a 16-bit DAC, which we can use to control the OCXO Vctl. That's 16x more resolution than our 12-bit DAC can provide, at least in theory.

Expand All @@ -21,8 +19,7 @@ The anecdotal data I have collected so far seems to indicate that yes, we do. Th

Of course I would need an even better clock to confirm to which degree these readings are correct, and I don't have access to such expensive equipment right now.

Can we do even better?
======================
## Can we do even better?

The question here is whether we could use a measurement period of 10,000 seconds and target a precision of 10E-11 or 0.01ppb for our STM32 GPSDO breadboard prototype, by either "dithering" the 16-bit PWM signal or mixing two 16-bit PWM signals with different amplitudes to increase the resolution of our software-based DAC by another 4 bits or so.

Expand All @@ -32,13 +29,13 @@ As already mentioned, my initial precision target for the STM32 GPSDO project wa

For a DIY home project following the time-proven K.I.S.S. principle, costing less than $40 and assembled on a breadboard, these are more than good enough results.

An anecdotal data point
=======================
## An anecdotal data point

This is what the STM32 GPSDO reports either on USB serial or Bluetooth serial (but not both), once per second:

Wait for GPS fix max. 1 second

```text
$GNGSA,A,3,31,25,12,18,02,29,20,,,,,,2.23,1.37,1.76*1E
$GNGSA1,,86,49,215,*6B
$GNGLL,4833.64512,N,00746.91322,E,092423.00,A,A*7F
Expand Down Expand Up @@ -72,6 +69,4 @@ Pressure = 1021.0 hPa
Approx altitude = 48.9 m
AHT10 Temperature: 22.15 *C
Humidity: 77.75% rH



```
Binary file added img/Prototype_10MHz_cleantrace1a.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
Binary file added img/Prototype_TwoGPSDOs.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added schematics/Schematics-STM32-GPSDO-0.6.2.pdf
Binary file not shown.
Loading