<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.7west.org/index.php?action=history&amp;feed=atom&amp;title=Project_Quartz</id>
	<title>Project Quartz - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.7west.org/index.php?action=history&amp;feed=atom&amp;title=Project_Quartz"/>
	<link rel="alternate" type="text/html" href="https://wiki.7west.org/index.php?title=Project_Quartz&amp;action=history"/>
	<updated>2026-06-20T10:15:00Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>https://wiki.7west.org/index.php?title=Project_Quartz&amp;diff=3&amp;oldid=prev</id>
		<title>Animationb: Created page with &quot;&#039;&#039;&#039;Project Quartz&#039;&#039;&#039; consists of two major components: # Wristwatch - small, comfortable, no wireless capabilities, and decent battery life # Base - connects to the watch to charge it and sync it&#039;s clock with GPS   ===Project Metrics=== {| class=&quot;wikitable&quot; |- | State Date:|| December 2017 |- | Completion Date:|| January 2021 |- | Cost:|| $1,000,000 |}  ==Hardware== ===Base=== The base is made up of two stacked 60x160 mm circuit boards housed in a 3D printed case. The Ba...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.7west.org/index.php?title=Project_Quartz&amp;diff=3&amp;oldid=prev"/>
		<updated>2025-06-27T15:34:01Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;#039;&amp;#039;&amp;#039;Project Quartz&amp;#039;&amp;#039;&amp;#039; consists of two major components: # Wristwatch - small, comfortable, no wireless capabilities, and decent battery life # Base - connects to the watch to charge it and sync it&amp;#039;s clock with GPS   ===Project Metrics=== {| class=&amp;quot;wikitable&amp;quot; |- | State Date:|| December 2017 |- | Completion Date:|| January 2021 |- | Cost:|| $1,000,000 |}  ==Hardware== ===Base=== The base is made up of two stacked 60x160 mm circuit boards housed in a 3D printed case. The Ba...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;Project Quartz&amp;#039;&amp;#039;&amp;#039; consists of two major components:&lt;br /&gt;
# Wristwatch - small, comfortable, no wireless capabilities, and decent battery life&lt;br /&gt;
# Base - connects to the watch to charge it and sync it&amp;#039;s clock with GPS&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Project Metrics===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| State Date:|| December 2017&lt;br /&gt;
|-&lt;br /&gt;
| Completion Date:|| January 2021&lt;br /&gt;
|-&lt;br /&gt;
| Cost:|| $1,000,000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Hardware==&lt;br /&gt;
===Base===&lt;br /&gt;
The base is made up of two stacked 60x160 mm circuit boards housed in a 3D printed case. The Base features three buttons and one 7-segment display. Two buttons are for changing the time zone and the third interacts with the syncing process. The display shows relevant information, depending on what is happening. &lt;br /&gt;
&lt;br /&gt;
The Base is rather large probably a bit over-engineered. If I had to do it again, I would have found a way to make it all smaller.&lt;br /&gt;
====Microcontroller====&lt;br /&gt;
An &amp;#039;&amp;#039;&amp;#039;ESP32&amp;#039;&amp;#039;&amp;#039; controls all the Base operations. An &amp;#039;&amp;#039;&amp;#039;ESP32 DevKitC&amp;#039;&amp;#039;&amp;#039; is plugged into female headers on the Base. From there is controls the powering up and running of the &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039;, the setting of time zones, the 7-segment display, and the time message that is sent to the Watch. The &amp;#039;&amp;#039;&amp;#039;ESP32&amp;#039;&amp;#039;&amp;#039; is in Deep Sleep most of the time and only wakes up when syncing the Watch.&lt;br /&gt;
&lt;br /&gt;
Originally, I went with the &amp;#039;&amp;#039;&amp;#039;ESP32&amp;#039;&amp;#039;&amp;#039; because I had never worked with it before and I had the intention of using NTP time over WiFi as a backup to GPS, but that was more work that it was worth. I should have gone with the &amp;#039;&amp;#039;&amp;#039;ATSAMD21G18&amp;#039;&amp;#039;&amp;#039; or a variant with more pins.&lt;br /&gt;
&lt;br /&gt;
====Power====&lt;br /&gt;
The power system is intricate but robust. The base is charged via a Micro USB port (USB-C is still out of my scope), which charges two 18650 Li-Ion batteries. The batteries are boosted to the necessary 5V for the ESP32 and 7-segment display. Also part of the Base&amp;#039;s power system is a second Lithium battery charger for the Watch&amp;#039;s battery (to save space on the Watch). The Base draws 6mA when sleeping, giving it a battery life of over 30 days while sleeping.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Lithium Chargers&amp;#039;&amp;#039;&amp;#039; - MCP73871 - Great lithium battery charger (lipo and li-ion), I have used it many times and always been happy with it&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Voltage Booster&amp;#039;&amp;#039;&amp;#039; - TPS61020 - &lt;br /&gt;
====Miscellaneous====&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;7-Segment Display&amp;#039;&amp;#039;&amp;#039; is just a 3 digit display that says gives time sync status and shows the time zone.&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039; locks onto GPS satellites and sends an NMEA message to the &amp;#039;&amp;#039;&amp;#039;ESP32&amp;#039;&amp;#039;&amp;#039;, of which the time is parsed.&lt;br /&gt;
====Models====&lt;br /&gt;
Base Eagle files (schematics and boards): [[:File:BaseEagle.zip]]&lt;br /&gt;
&lt;br /&gt;
Base 3D files (.stl): [[:File:BaseSTL.zip]]&lt;br /&gt;
===Watch===&lt;br /&gt;
The Watch&amp;#039;s main component is a 28x25 mm L-shaped circuit board that hosts the microcontroller, Real Time Clock (&amp;#039;&amp;#039;&amp;#039;RTC&amp;#039;&amp;#039;&amp;#039;), and the Liquid Crystal Display (&amp;#039;&amp;#039;&amp;#039;LCD&amp;#039;&amp;#039;&amp;#039;). It is contained in a 3D printed case with wrist-straps salvaged from another watch.&lt;br /&gt;
&lt;br /&gt;
====Microcontroller====&lt;br /&gt;
An &amp;#039;&amp;#039;&amp;#039;ATMega328P&amp;#039;&amp;#039;&amp;#039; controls the Watch&amp;#039;s functions: reading the time, updating the &amp;#039;&amp;#039;&amp;#039;LCD&amp;#039;&amp;#039;&amp;#039;, and parsing the time message from the Base. The &amp;#039;&amp;#039;&amp;#039;ATMega328P&amp;#039;&amp;#039;&amp;#039; was selected due to its small package (4x4 mm) and low power consumption.&lt;br /&gt;
&lt;br /&gt;
====Power====&lt;br /&gt;
A 60mAh Lithium Polymer battery powers the Watch. The Watch easily lasts longer than a week on a single charge. The battery is charged via a pin when connected to the Base. The charge controller sits on the Base, not the Watch.&lt;br /&gt;
&lt;br /&gt;
====Miscellaneous====&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;LCD&amp;#039;&amp;#039;&amp;#039; is an ERC12864-10 LCD. It is a black and white LCD with a built in backlight. It&amp;#039;s resolution is 128x64 pixels.&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;RTC&amp;#039;&amp;#039;&amp;#039; is an RV-3028, chosen for its extremely low power requirements and small size. It is smaller than a grain of rice!&lt;br /&gt;
&lt;br /&gt;
====Models====&lt;br /&gt;
Watch Eagle files (schematics and boards): [[:File:WatchEagle.zip]]&lt;br /&gt;
&lt;br /&gt;
Watch 3D files (.stl): [[:File:WatchSTL.zip]]&lt;br /&gt;
&lt;br /&gt;
==Software==&lt;br /&gt;
===GPS and NMEA Sentences===&lt;br /&gt;
The first step in getting the time is receiving it from the &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039;. GPS is normally used to calculate one&amp;#039;s location on Earth, however, essential to calculating that, the &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039; needs to know exactly what time it is, which the GPS Satellites help achieve. I simply take this time from the module. The &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039; outputs National Marine Electronics Association (NMEA) sentences. They are standard across many GPS Modules and each sentence gives slightly different information. Project Quartz uses the GPRMC sentence, because it has the time, along with other basic GPS info (latitude, longitude, altitude, other-udes). Parsing of the NMEA sentence is done by a library I made, included at the end of this section. From the parsed time, the Base converts it into the bytes to be written to the Watch&amp;#039;s &amp;#039;&amp;#039;&amp;#039;RTC&amp;#039;&amp;#039;&amp;#039;. Part of the conversion process relies on Andreas Spiess&amp;#039; [https://github.com/SensorsIot/NTPtimeESP NTP Library], not for NTP, but for its Unix-to-Normal time conversion and calculation of Leap Years and Day Light Saving Time. I did make some small changes to the library to make it not use WiFi.&lt;br /&gt;
&lt;br /&gt;
The only flaw in this process, is that while the Base is sleeping, the GPS Module is turned off (it draws 200mA). So when the Watch is placed on the Base, the &amp;#039;&amp;#039;&amp;#039;ESP32&amp;#039;&amp;#039;&amp;#039; wakes up the &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039; and waits for a lock on the GPS&amp;#039;s location and time, which can take up to 5 minutes. I&amp;#039;ve also found a weird bug where the time generated from my recently locked &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039; is exactly 3 seconds fast. However, after letting the GPS stay locked for about 20 minutes, the time becomes correct. I&amp;#039;m not sure what the source of this bug is, but I suspect the &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039; is getting old, because it didn&amp;#039;t used to do this.&lt;br /&gt;
&lt;br /&gt;
[[:File:NMEAsentenceParser.zip]]&lt;br /&gt;
&lt;br /&gt;
===ERC LCD Driver===&lt;br /&gt;
Writing to displays has always been a fun challenge with the &amp;#039;&amp;#039;&amp;#039;ATMega328P&amp;#039;&amp;#039;&amp;#039;. Due to it&amp;#039;s 2KB of SRAM, it cannot hold a buffer for all 128x64 pixels. Therefore, on each screen update, the microcontroller must calculate what pixels are black or white based on the current time. The &amp;#039;&amp;#039;&amp;#039;LCD&amp;#039;&amp;#039;&amp;#039; is updated in 8-bit tall pages that run the length of the display; therefore, most updates do not include the date. Stored in Program Memory (so it takes up Flash, not SRAM) is a table of the bits needed for numbers 0-9 for their large and small forms. There is also a table for the few letters used. When updating the display, the code uses the current time and the location in the page to determine what bits to pull from the tables and push to the &amp;#039;&amp;#039;&amp;#039;LCD&amp;#039;&amp;#039;&amp;#039;. Lastly, there are two types of display updates: one that only updates the time, which occurs every second, and the other which updates the time and date, which occurs every hour.&lt;br /&gt;
&lt;br /&gt;
This method saves SRAM, but does cost time in the form of CPU cycles. At the end of the day, the shorter screen update only takes a dozen milliseconds and is barely noticeable. However, designing this code did take a lot more effort. I&amp;#039;ve found that is always the trade off with microcontrollers, you can either have speed or RAM. If you need more speed you need more RAM, if you don&amp;#039;t have enough RAM your speed takes a hit.&lt;br /&gt;
&lt;br /&gt;
===Watch-to-Base Interface===&lt;br /&gt;
The interface between the Watch and Base is a complicated and time sensitive handshake, because it sets the time on the Watch. There are 5 pins that are used for this interface, wired differently on each component (Watch vs Base):&lt;br /&gt;
* PLACE_W&lt;br /&gt;
** Watch - This pin is tied to Ground&lt;br /&gt;
** Base - This pin is pulled up, but when it is set Low by plugging in the Watch, the &amp;#039;&amp;#039;&amp;#039;ESP32&amp;#039;&amp;#039;&amp;#039; wakes up and begins the syncing process&lt;br /&gt;
* INT1&lt;br /&gt;
** Watch - This pin is pulled down to Ground, but when set High the Watch stops everything and waits for the time message&lt;br /&gt;
** Base - This pin is controlled by the &amp;#039;&amp;#039;&amp;#039;ESP32&amp;#039;&amp;#039;&amp;#039; and let&amp;#039;s it tell the Watch to get ready for the time message&lt;br /&gt;
* RX/TX&lt;br /&gt;
** Watch - Using UART, the &amp;#039;&amp;#039;&amp;#039;ATMega328P&amp;#039;&amp;#039;&amp;#039; receives the time message and sets the &amp;#039;&amp;#039;&amp;#039;RTC&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
** Base - Sends the time message via UART.&lt;br /&gt;
* The other two pins are used for GND and VBAT to charge the Watch&amp;#039;s battery&lt;br /&gt;
&lt;br /&gt;
The process is mostly described by the pins above, but here it is more clearly. The Watch is placed on the Base, pulling the Base&amp;#039;s PLACE_W pin Low. This wakes up the ESP32, which turns on the &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039; (if it is asleep) and begins requesting the time. Once the &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039; gives the time to the &amp;#039;&amp;#039;&amp;#039;ESP32&amp;#039;&amp;#039;&amp;#039;, it tells the Watch to prepare for the time message and converts the GPS time into a the proper time message. Before sending the time, the &amp;#039;&amp;#039;&amp;#039;ESP32&amp;#039;&amp;#039;&amp;#039; inserts a delay and adds 2 seconds to the GPS time. This is done to compensate for the time it takes to receive and process the GPS time. Finally the &amp;#039;&amp;#039;&amp;#039;ESP32&amp;#039;&amp;#039;&amp;#039; sends the time message to the &amp;#039;&amp;#039;&amp;#039;ATMega328P&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The time message is exactly the bytes that need to be written to the &amp;#039;&amp;#039;&amp;#039;RTC&amp;#039;&amp;#039;&amp;#039; on the Watch. The time message also includes a multi-function byte at the end. This last byte will tell the Watch how many days until the next &amp;quot;Day Light Savings Event&amp;quot; and on that day, depending on what month it is, the Watch automatically adjusts the hour. The last byte&amp;#039;s other function occurs if the time syncing process is cancelled before &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039; acquires the time. In this case, the Base only sends the time change if the Watch, Base, and user have changed time zones.&lt;br /&gt;
&lt;br /&gt;
The time message is pretty cool and compact, however by far the hardest part of all of this was working with the &amp;#039;&amp;#039;&amp;#039;GPS Module&amp;#039;&amp;#039;&amp;#039;. There seemed to me a dozen edge cases where the GPS would get a lock but not the time, or it would have the time but send it a half a second off from what was expected. The code for the Base has a lot of waiting for the GPS to &amp;quot;get its crap together&amp;quot; and produce a reliable NMEA sentence. That is why 2 seconds are added to the time, as mentioned above.&lt;br /&gt;
&lt;br /&gt;
===The Code===&lt;br /&gt;
Base Code: [[:File:BaseCode.zip]]&lt;br /&gt;
&lt;br /&gt;
Watch Code: [[:File:WatchCode.zip]]&lt;/div&gt;</summary>
		<author><name>Animationb</name></author>
	</entry>
</feed>