Wednesday 24 May 2017

Clock build log #2 - time module

Build

Build for the time module started with the bus connectors that would connect to the analogue board and further in to the stack. The connector for the analogue board is a small 8 way pin header, while the connector for the rest of the stack is a 40 pin socket - but not one with extended pins. Positioning of this board within the stack is somewhat limited, as it connects to the analogue board and in doing so it bridges power and the MCLR, AC_CLK/ and 1PPS_CLK/ signals through to the larger bus. That means this board pretty much has to sit adjacent to the analogue board for the bus connectors to line up properly between the two. It all started off looking so simple:


Then I started what would become a (part time) month and a half long process of soldering in transistors, resistors and jumper wires to create the gates that would form the logic.

While putting the seconds counters together I had an idea - what if I was to use the 1PPM clock signal that it creates to collect some statistics about how much the AC frequency drifts? I thought it would be kind of interesting to see just how wild the AC frequency was, and how often and for how long it drifts around. As part of this I thought it would give a nice insight in to how quickly things might degrade and how long it takes to recover.

So after soldering in the first 56 gates worth of transistors that make up the seconds counters and their reset logic (which generates the 1PPM_CLK/ signal) I branched off in to a small software project.

I had a Raspberry Pi sitting idle that I thought would be perfect for the task, since it has GPIO pins that I could interface to my clock. I knocked together a small program in C that, upon start, takes the current UNIX timestamp when the first 1PPM clock pulse occurrs, and for every subsequent 1PPM clock pulse it records the UNIX timestamp again, substracts the difference, and outputs the timestamp and difference. I piped that information in to a file and then left it to run for about 2 weeks until something started going funny and it started missing pulses and producing erroneous results.

I tried applying some manual fixes to some of the data, and restarted the script a couple of times before it started getting too out of hand and I gave up, sticking with about 11 days worth of solid data, or about 15,700 records. From that I was able to produce the following graph by loading all of the data in to a spreadsheet:


Since I don't know when "zero" is for the AC mains frequency, "zero" for me and my exercise was at UNIX timestamp of 1491865936, which for the non-techies means April 10th 2017 at 23:12:16 UTC (basically it's the number of seconds since January 1st 1970 00:00:00).

This answered two questions:
  1. How much the clock may end up drifting - over my sample of data as much as +22 and -35 seconds
  2. How quickly or slowly it drifts and recovers - could be as quick as a single day to a couple of days
Re #2, April 17th was a "bad day" where it slowed right down to the slowest it ever got, while we see that over the 13th and 14th we caught up 20 seconds and went 10 seconds faster still.

The most important thing I learned from this was that the clock would probably eventually come back to zero offset. So some of my worries about how reliable the AC frequency was going to be ended up being addressed through that little exercise. At least it wasnt going to be constantly getting slower and slower or faster and faster and never return, though long term results are yet to be seen...

Here are a couple of photos/images showing the setup I used to collect the data for the above graph, and also the schematic for what's happening on the breadboard (a MOSFET level translator, since the Raspberry Pi GPIOs are 3.3V and my clock is 9V):


Funnily enough, this is the first time I have ever used a Raspberry Pi for the thing that I guess it was intended to be used for - tinkering with electronics. My other Raspberry Pi's are running FreeBSD or Linux and acting as servers more or less. :-)

Back to the task at hand... it pretty much just sounds like a broken record from here. Solder, test, repeat. So theres not really much more to say about the build. And it seems I didn't take many more photos during the construction process, so theres a distinct lack of more things to say or show right now. So perhaps the more interesting and juicy bits are in the testing of what I have built.

Testing

Learning from the build of the analogue board, I built each counter stage individually and tested that it worked as expected before moving on to building the next. This meant that solder joints weren't buried under so many wires and hard to get at. It also gave confidence that as I was going along and things were working, if anything happened to stop working further on during the build it might likely be what I was just working on rather than something earlier on. At least then it would be a process of test the most recently built circuit and then start moving backwards if that was checking out OK.

With the seconds counters working just fine, the first major problem I came across was with the minutes counter. When I started building it one of the first things I did was to hook up the button with its debounce circuit so that I could advance that counter manually, instead of having to wait for the 1PPM_CLK/ signal to fire, although testing that the counter advanced on that clock pulse was also important.

Advancing of the units counter was fine, but I noticed an issue when it came to the reset event. The counter would advance, and at 10 count the output of the gate hooked up to the outputs of the 2nd and 4th stages would go high, inverting an SR latch to reset the counter back to 0. But after doing that, the SR latch wouldn't release that reset, so the counter could no longer advance (well, it would have if I had actually hooked up the reset inputs of the counter stages, but I hadn't at that point in time). I traced out all of the wiring I had soldered and realised the issue was not with the design or build of the time module circuitry, but with how the AC_CLK/ signal was handled back on the analogue board.

On the analogue board is a switch that allows you to isolate AC_CLK/ from the clock to stop it advancing the mains frequency prescaler, thus allowing you to reset the clock to all zeros and then set it manually without it carrying on, then set it running once you were ready. But that switch isolated the AC_CLK/ signal from the entire clock, and while it did what I had originally intended it to do, it was breaking another piece of functionality - when an SR latch it set by a connected "AND" gate to cause a reset, it needs the AC_CLK/ signal to release that reset! Ooops. So a quick re-design of the AC_CLK/ circuitry such that the switch only isolates AC_CLK/ from the input of the first counter stage mains frequency prescaler was in order, and luckily that was pretty simple, and required minimal re-work. The revised schematic will be linked below.

Here are some scope traces that show the incorrect (left) vs correct (right) behaviour:


Some explanation of what you're seeing ... the yellow trace is the inverted output of the SR latch on the minutes units counter (i.e. the one that would generate the 1PPH_CLK/ signal in this case). That output clocks the input to the minutes tens counter, hence it has gone from high to low in the left hand image. But you see that, while D4 has gone high (being the first stage of the minutes tens counter), D1 and D3 have not gone low, and the yellow trace remained low.

At the time I took that trace, the switch isolating the AC_CLK/ signal from the clock was set to the "stop" position. If I had set that to "run" things would reset correctly. But it's a bit silly to need the clock to be in "run" mode for this to work correctly, its kind of the complete opposite of what I was aiming for.

After modifying the circuitry around that switch, I took a second capture which is the right hand image you see above. As you can see things are a bit different here. As D1 goes high towards the right hand side of the trace, it remains high only for a very brief period of time, hence you just see a "glitch" in the trace for that signal. When it does go high, and with D1 and D3 representing 2+8, that generates the reset condition for that counter, so D4 goes high. You also see a very brief glitch in the yellow trace - thats the SR latch being set by the "AND" gate of the minutes unit counter and then being reset by the AC_CLK/ signal, and all with the switch being set to "stop". So that was now sorted and working correctly.

For interest sake, here's an even closer look at whats happening when the reset of the minutes unit counter occurrs, which pretty well matches the description that I gave in design notes #5 - it's nice to know that my theory turned in to reality 😎 :


At the bottom you see that I have grouped the digital channels in to some busses, B0 (D0-D3) and B1 (D4-D6), and they are displaying what you'd see on the display if the decoders were built. As we lead in from the left, we're at 09, and at the next button press D0 goes low (and for a very brief period of time we go backwards to 08) until D1 goes high and we get to a value of "A" in base 16 (aka hexadecimal) which equals 10 in our every day base 10/decimal system. At that point the reset condition is created and after 20 odd uS D1 and D3 go low while D4 goes high, and now we see that the value on the display would be 10.

Fortunately there were no more surprises that needed fixing in the build from here on, and things went smoothly. All counters worked as expected, and all clock pulses were generated fine and dandy. Somewhat boring, but also somewhat relieveing since ...

End result

... heres what I ended up with!



That was quite a bit of work!

But most importantly it works, much much much to my relief. Along with producing the 1PPD_CLK/ signal when rolling over from 23:59:59 to 00:00:00, it also produces 1PPM_CLK/ and 1PPH_CLK/ signals, although at the moment there is nothing planned that uses these, except perhaps 1PPH_CLK/ which might be used by another module to do display dimming/blanking.

Luckily I think this will be one of, if not the busiest board in the clock - it's certainly going to be one of the most densely populated. I anticipate that the calendar decoder board might be pretty complex/dense too, but we'll have to wait and see what that one brings (designs still pending at this stage...)

In closing, along with the revised analogue board schematic, I've uploaded the C source for the program I wrote to capture data for the graph, and I have also uploaded an updated schematic for the analogue board with the fix for the AC_CLK/ generator. C is not my every day programming language, so please be gentle (and you'll need wiringPi to make it work).

No comments:

Post a Comment