06/27/2020 at 19:09 •
The 1.0 boards are being built now, but I've already had an idea for a 1.1 improvement.
With 1.0, one pin of the controller is connected to the piezo element and the other lead of the element is grounded. This means that the piezo will see a 3 volt square wave.
Instead, v1.1 hooks one pin of the controller to each side of the element and it is fed with two square waves 180º out of phase. In this manner the piezo element effectively sees a square wave with a peak-to-peak amplitude of 6 volts.
Previously, I was careful to use pin B2, which is the only pin not involved in TPI on the chip. By using two pins, it forces us to use one of those TPI pins. But B2 will be high impedance during programming, so this isn't as big a deal as it might seem - the piezo will effectively have one side disconnected and the other won't therefore load the programming pin.
The code doesn't have to change much. There are already instructions to set up the DDR register, toggle the pin and clear it when the beeping is done. In principle these instructions simply need to have the constants changed to have two bits set instead of one. The one extra instruction needed is to set one (but not both) pins to 1 at the start of the beeping. From then on, toggling both will result in the out-of-phase square waves we want. At the end, both outputs are set low. As before, the remaining (non !RESET) pin is set to be an input with the pull-up turned on. This will minimize power consumption.
06/26/2020 at 22:36 •
Well, I had an opportunity to to put the prototype on my µCurrent and it came back at something like 90 µA, which seemed quite high to me.
The challenge is that you want to have a relatively fast clock while beeping so that you can run lots of instructions between pin toggles (yes, I could have used the timer PWM output instead of toggling a pin by hand, but those pins are shared with the programming interface, and it's just a whole lot easier to put low impedance or capacitive loads on the unshared B2).
Well, since you can switch clock sources and prescaling on the fly, I decided to use differential clocking. So we use the 8 MHz oscillator pre-scaled by 8 for beeping (1 MHz), and use the 128 kHz oscillator pre-scaled by 1 for the long wait periods. During the wait, we set up the timer with a divide-by-1024 prescale itself, and wait 1250 counts - 10 seconds - between interrupts. With this, the long term current draw seems to be approximately 7 µA - astonishingly low. In principle, the battery could last almost a year, except that the actual beeping is going to cost something. Still, if we assume a draw of 5 mA during beeping, and we beep for 1/4 second, that's about 350 nAH per beep, or well over 100,000 beeps on one battery (since the active current required by the Tiny9 at 1 MHz and 3 volts is around 300 µA, most of the assumed power is for the speaker).
06/26/2020 at 20:14 •
The boards aren't back from OSHPark yet, but I decided to take an old AC Timer board board and just use it to hold an ATTiny to test out the firmware.
I'm happy to report that that done the firmware works perfectly. It does take up almost all of the available flash space of an ATTiny9, but that's more or less because you have to trade flash for RAM by having every function be always-inline and save the stack for the ISR call and return. Most of the space, however, is taken up by the PRNG. It's the same one used for the Crazy Clock and uses 32 bit operations, which necessitates adding the 32 bit math. Using 16 bit values would probably reduce the size by 25%, but at least at the moment there's no driving need.
I haven't verified the low current draw just yet, but I anticipate that won't result in any surprises.