I've discovered a design flaw in the Crazy Clock. The result of this flaw is that the clock fairly consistently gains time at a rate of ~120 ppm. That's around ten seconds fast per day. The clock is supposed to stay within 10 ppm - more than an order of magnitude better than that.
Fortunately, the error is consistent in the samples I've taken, and can be corrected in software.
If you've got an affected clock, there are two ways to fix it:
1. If you're very confident in your surface mount soldering skills, you can add a 12 pF capacitor between each lead of the crystal and ground. I do not recommend attempting this, as there's very little room on the board, and almost no margin for error. If you ruin your board attempting this, I won't replace it.
2. The new SW_TRIM facility can be used to trim the clock frequency to compensate for the error. To do this yourself, fetch the firmware from github, compile it with -DSW_TRIM and reflash the controller. After doing that, you'll also want to set the trim factor in EEPROM. It's located at address 4 and is a two byte, two's compliment, little endian integer representing the amount of adjustment in tenths-of-a-ppm. Positive values slow the clock. The standard correction factor for this error is 0x490, or 116.8 ppm slower. The avrdude argument to achieve this is "-U eeprom:w:0xff,0xff,0xff,0xff,0x90,0x04:m". If you do this, you'll wipe out the PRNG seed at locations 0-4, so if your clock has random behavior, you should replace each of the '0xff' in that command with four random numbers from 0-255. There's no harm in not doing this, really, but your random number generator will wind up starting from a "standard" state, resulting in repeated behavior the first time you power the clock up. Don't forget that the system clock speed is 32.768 kHz, so your programming SPI clock must be no faster than 4 kHz. Achieve this by adding either -i 125 or -B 250, depending on your programmer.
If you have an affected clock, you may ship it back to me and I will apply the fix and return the clock to you for free (including shipping to get the clock back to you). If you bought a complete movement, return just the movement - keep the hands and face and stuff. If you bought a controller only, then please return just the controller. In both cases, you'll get a replacement, not necessarily the same one you send. Please be sure to indicate which firmware style you wish. To proceed, contact me with the contact form and I'll send you the address to ship your movement or controller.
Wednesday, June 24, 2015
Friday, June 19, 2015
Sidereal clock movements
The Crazy Clock has been out there for a while, and one of the firmware options for it for almost as long has been the Sidereal clock. In looking around the Internet, I've found sort of a background rumble of interest in Sidereal movements for astronomers.
For those who aren't aware, the 86,400 second long "day" we know is more precisely a "tropical" day. It's the amount of time (roughly) it takes for the sun to go from the local meridian (the north-south line passing through the zenith - the highest point it reaches) on one day to return to the meridian on the next day. A sidereal day, on the other hand, is the amount of time it takes a star to go from the meridian on one day to the meridian the next day. The two are not the same amount of time, because at the same time that the earth is rotating on its axis, it is revolving around the sun. Over the course of a tropical year (the time it takes for the Earth to return to the same point in its orbit), the revolution adds an extra rotation. So a sidereal day is 1/365.2425(ish) shorter than a tropical day. That works out to 3 minutes, 56 seconds (that's not exact, but it gets us to inside of the 10ppm tolerance of the clock movement, which is enough).
If you combine a 24 hour clock movement with a sidereal controller, you wind up with a very special clock for astronomers. If you superimpose a star chart for your hemisphere, centered on the pole, the hour hand will always point to the star or constellation passing through the meridian (as long as you set the clock to local apparent sidereal time). It's this property that makes 24 hour sidereal movements valuable for building things like automatic astrolabes.
So for those looking, pre-built, ready-to-use 24 hour sidereal clock movements are available from my Tindie store. Just select the pre-built 24 hour movement with the sidereal firmware. They're in stock now!
For those who aren't aware, the 86,400 second long "day" we know is more precisely a "tropical" day. It's the amount of time (roughly) it takes for the sun to go from the local meridian (the north-south line passing through the zenith - the highest point it reaches) on one day to return to the meridian on the next day. A sidereal day, on the other hand, is the amount of time it takes a star to go from the meridian on one day to the meridian the next day. The two are not the same amount of time, because at the same time that the earth is rotating on its axis, it is revolving around the sun. Over the course of a tropical year (the time it takes for the Earth to return to the same point in its orbit), the revolution adds an extra rotation. So a sidereal day is 1/365.2425(ish) shorter than a tropical day. That works out to 3 minutes, 56 seconds (that's not exact, but it gets us to inside of the 10ppm tolerance of the clock movement, which is enough).
If you combine a 24 hour clock movement with a sidereal controller, you wind up with a very special clock for astronomers. If you superimpose a star chart for your hemisphere, centered on the pole, the hour hand will always point to the star or constellation passing through the meridian (as long as you set the clock to local apparent sidereal time). It's this property that makes 24 hour sidereal movements valuable for building things like automatic astrolabes.
So for those looking, pre-built, ready-to-use 24 hour sidereal clock movements are available from my Tindie store. Just select the pre-built 24 hour movement with the sidereal firmware. They're in stock now!
Wednesday, June 10, 2015
AVRDUDE with linuxgpio and least privilege: don't sudo
The principle of "least privilege" is a valuable practice. Far too many people just put "sudo" in front of everything when they're using *nix - particularly on the Raspberry Pi, which is often thought of as a sort of throw-away computer.
Fortunately, the Raspberry Pi folks were thinking ahead a bit and created the "gpio" group and rules in devd to set the ownership of the GPIO nodes in /sys so that you don't have to be root to use them - you just have to belong to the correct group.
There is one "gotcha" to this, however. To understand it, we need to look at how GPIO functions on the Raspberry Pi.
In /sys, there is a GPIO class - that is, a directory - at /sys/class/gpio (that's not actually where it is, but there's a symlink there, so for our purposes, we'll just say it's there). Inside that directory, there are two nodes "export" and "unexport". To take control of a GPIO pin, you open "export" and write the pin number there. When you do, a new directory will show up named "/sys/class/gpio/gpioX/" where X is the GPIO number. Inside that directory will appear a bunch of nodes that will allow you to take control of the pin.
The gotcha, however, is that the kernel driver doesn't know anything about the "gpio" group. It sets the ownership of all GPIO nodes to "root:root" and "rw-r--r--" (0644). devd comes along at some time after the nodes are created and resets the permissions so that the nodes are writable by the gpio group. Normally this isn't a big deal because most of the nodes in /sys are created when the driver is probed, usually at boot. But in this case, avrdude attempts to export the GPIO pins, and then immediately set their direction. If it does so too quickly, it will get EACCESS attempting to open /sys/class/gpio/gpioX/direction.
People have so far worked around this by simply running avrdude as root - either by prefacing it with "sudo" every time or by making the binary suid as root. These are bad ideas. If for no other reason, if you ask avrdude to read from the chip and write to a new file, that file will be owned by root, rather than by the user running avrdude.
One quick and dirty solution to the problem is to introduce a short delay between the export operation and the rest of the initialization. But more to the point, the delay must also yield the CPU so that devd gets a chance to run. To that effect, my patch just uses "sleep(1)". It's probably too long a delay, but it works consistently.
Another way to go is to remove the export and unexport operations from avrdude and instead leave the pins permanently exported, exporting them from some sort of script possibly run at boot. This is safe to do, since the linuxgpio driver in avrdude is careful to set all the pins as input before exiting, which will return them to high impedance state. I haven't implemented this change, but it would allow avrdude to run faster since there would not be a 1 second delay every time.
To proceed, download AVRDUDE 6.1 and apply this patch. Then build as usual. Having done so, you can now either make avrdude sgid and set its group to gpio, or - probably better - add yourself to the gpio group. No more sudo!
Fortunately, the Raspberry Pi folks were thinking ahead a bit and created the "gpio" group and rules in devd to set the ownership of the GPIO nodes in /sys so that you don't have to be root to use them - you just have to belong to the correct group.
There is one "gotcha" to this, however. To understand it, we need to look at how GPIO functions on the Raspberry Pi.
In /sys, there is a GPIO class - that is, a directory - at /sys/class/gpio (that's not actually where it is, but there's a symlink there, so for our purposes, we'll just say it's there). Inside that directory, there are two nodes "export" and "unexport". To take control of a GPIO pin, you open "export" and write the pin number there. When you do, a new directory will show up named "/sys/class/gpio/gpioX/" where X is the GPIO number. Inside that directory will appear a bunch of nodes that will allow you to take control of the pin.
The gotcha, however, is that the kernel driver doesn't know anything about the "gpio" group. It sets the ownership of all GPIO nodes to "root:root" and "rw-r--r--" (0644). devd comes along at some time after the nodes are created and resets the permissions so that the nodes are writable by the gpio group. Normally this isn't a big deal because most of the nodes in /sys are created when the driver is probed, usually at boot. But in this case, avrdude attempts to export the GPIO pins, and then immediately set their direction. If it does so too quickly, it will get EACCESS attempting to open /sys/class/gpio/gpioX/direction.
People have so far worked around this by simply running avrdude as root - either by prefacing it with "sudo" every time or by making the binary suid as root. These are bad ideas. If for no other reason, if you ask avrdude to read from the chip and write to a new file, that file will be owned by root, rather than by the user running avrdude.
One quick and dirty solution to the problem is to introduce a short delay between the export operation and the rest of the initialization. But more to the point, the delay must also yield the CPU so that devd gets a chance to run. To that effect, my patch just uses "sleep(1)". It's probably too long a delay, but it works consistently.
Another way to go is to remove the export and unexport operations from avrdude and instead leave the pins permanently exported, exporting them from some sort of script possibly run at boot. This is safe to do, since the linuxgpio driver in avrdude is careful to set all the pins as input before exiting, which will return them to high impedance state. I haven't implemented this change, but it would allow avrdude to run faster since there would not be a 1 second delay every time.
To proceed, download AVRDUDE 6.1 and apply this patch. Then build as usual. Having done so, you can now either make avrdude sgid and set its group to gpio, or - probably better - add yourself to the gpio group. No more sudo!
Sunday, June 7, 2015
Crazy Clock contest!
Have you built a clock with the Geppetto Electronics Crazy Clock movement? Then here's your chance to win a free $25 gift code to OSHPark! Just tweet a picture or video of your creation to @nwsayer #CrazyClock any time before July 1st, 2015 (midnight, Pacific Daylight Time). To be eligible, the clock movement must contain a Crazy Clock controller, and you must live somewhere where it's not illegal for you to participate in the contest. Entries will be judged on creativity and humor, and the winner will be announced on July 4th, 2015. The gift code will be presented to the winner via Twitter DM.
Monday, June 1, 2015
AVR ISP Pi Cap user guide
This is the permanent home for the user guide for the AVR ISP Pi Cap.
This board provides level shifting and voltage protection (including hot-plugging) for AVR programming via the GPIO pins on a Raspberry Pi. It allows you to select the target power supplied to the target as either 3.3 volts, 5 volts or no power (meaning that the target is self-powered). The programming pins for the target will be level-shifted to whatever voltage is supplied to or by the target when programming is taking place, and will be high impedance otherwise. The buffer chip protects the Pi's GPIO pins from any invalid excursions. An AP2331 hot-plug protection chip protects the Pi from shorts and hot-plugging voltage sags.
The board comes with the stacking header (for the Pi) and the shrouded DIP header (for the target) uninstalled. It is strongly recommended that you install the stacking header first so that the shrouded DIP header doesn't get in the way of your soldering iron.
The GPIO pins selected are the MOSI/MISO/SCK pins for SPI port 0, however !RESET is connected to GPIO pin 25 rather than using one of the SPI CE pins. This allows !RESET to be asserted in a separate operation rather than being asserted and deasserted with every SPI operation performed during a single programming session. With this configuration, you have a choice of using the "linuxgpio" driver built-in to avrdude version 6.1, or the higher performance native SPI driver.
To use bit-banged GPIO, configure AVRDUDE for the "linuxgpio" programmer. Add this section to your avrdude.conf file:
programmer
id = "pihat";
desc = "Use the Linux sysfs interface to bitbang GPIO lines";
type = "linuxgpio";
reset = 25;
miso = 9;
mosi = 10;
sck = 11;
;
Having done that, you should be able to use the -c pihat argument to avrdude to program a target. If it doesn't work, make sure you have an avrdude binary compiled to include the "linuxgpio" programming driver. AdaFruit has a guide that shows how to build avrdude 6.1 to include that driver. The LED will light when the !RESET gpio pin is brought low, and the bus buffer chip will bring the target !RESET pin low and assert the ISP signals on their relative pins.
Note that as of 6.1, there is an issue with the linuxgpio driver in avrdude. There is a race condition between avrdude writing to the GPIO "export" node to export the GPIO pins, and udev setting the permissions properly on the newly created nodes. The only workaround (at present) is to patch avrdude to add a delay between the export and the rest of the operations. Here's a patch.
If you are used to using -B to slow down the SPI clock, you can still do so, but the correct argument is -i instead (with the same numeric value).
To instead use the SPI driver, you'll need to apply a patch to avrdude to add the "linuxspi" driver (TBD).
Note that as of 6.1, there is an issue with the linuxgpio driver in avrdude. There is a race condition between avrdude writing to the GPIO "export" node to export the GPIO pins, and udev setting the permissions properly on the newly created nodes. The only workaround (at present) is to patch avrdude to add a delay between the export and the rest of the operations. Here's a patch.
If you are used to using -B to slow down the SPI clock, you can still do so, but the correct argument is -i instead (with the same numeric value).
To instead use the SPI driver, you'll need to apply a patch to avrdude to add the "linuxspi" driver (TBD).