Lately I've been attempting to ignore the fact that I have a sleep disorder and just do whatever the hell I want, as constantly worrying about a sleep disorder probably isn't helping my sleep. So, I've been looking for something else to do instead, something that's just fun.
I realized I hadn't worked on an electronics project in quite some time. When I moved in last year, I set up my electronics desk, and other than getting used to build that EEG over the summer, it's otherwise all just sort of sat there unused.
So I've been trying to decide what sort of electronics project I would like to work on.
One idea is that I've always wanted to create a video output circuit for my Z80 computer. I decided long ago that video output on a Z80 computer is unnecessary. I only ever wanted it because I wanted a Z80 computer that I could use like a PC, but eventually I decided I should just write code and compile programs on a PC, and use the Z80 for things it is good at, like accessing hardware I've built, and doing timing-sensitive things with that hardware. So the simple LCD displays I already have for it are ideal in my opinion, but regardless, building a video output device kind of seems like fun.
Last time I worked on this, I used some simple timing ICs and some logic gates to generate an approximation of the sync signals, and a bit more of the same to generate a simple white square in the middle of the screen. It worked, but only when attached to a CRT television. Apparently the signals were too unstable for an LCD to consider it valid. So I decided I needed digital timing.
The problem with that is that the horizontal signal is 910 clocks long, then there are 262.5 lines per frame, and neither of those are numbers chosen to make building an digital counter easier. The same is true of the number of clocks between various parts of the signal, like how many clocks wide the sync signal is, how many clocks between the sync signal and when the visible signal begins, how many blank scan lines there are after vertical sync before data begins, etc. So not only do I have to chain together multiple 4-bit counter ICs to count the horizontal clocks, and multiple more to count the vertical lines, but I also need piles of ICs to build circuits to recognize each of the odd numbers when they come up on each counter. My desire to have such a thing doesn't stretch that far.
So, at that time, I ordered a bunch of Intel 8254 "Programmable Interval Timer" chips. These are the same chips originally used in PCs for the timer interrupt and also for the PC speaker output. Each chip has 3 independant circuits, each of which features a 16-bit counter and an 16-bit compare register to stop the counter when it reaches a certain value. Thus, each one of these chips can replace three piles of chips. I ordered five of them, which gives me 15 timers. With that, I planned to just program one to count the horizontal retrace interval, another to count the time until the sync pulse begins, another to count until it ends, another to count until the image output begins, another until that ends, and a whole other set like those, but for vertical counts instead of horizontal ones.
I never got around to trying that, and I still don't want to. It's certainly a better solution than what I was looking at before, but it's still a pile of chips. I would need not only all the timer chips, but some SR latches so that the timer chips can activate/deactivate the various signals. ...and those pointless parts of the NTSC standard I was talking about, well, they're still left out of the design.
So now I have a new idea:
That's an ATtiny13A. It's an 8 bit CPU that runs at 9.6 MHz, and which has 512 words of program memory, 64 bytes of RAM, and 32 CPU registers. ...and 64-bytes of EEPROM, and an ADC, and some other stuff...
I first heard about little microcontrollers such as these ages ago, but never liked the idea of them much. It seemed pointless to put so much into a little chip which, by nature of having so few pins, and so little memory, was so limited in what it could hope to accomplish. Many such things were only one-time programmable, required some special programmer that was part of an expensive development kit, and were a complete mystery as to what sort of bullshit would be involved in whatever programming language they used as the language wasn't documented outside the development kit.
However, a few years ago when I discovered the Amtel AT89S52, I found it to be quite well documented. The datasheet explained the programming algorithm and another datasheet explained the CPU instructions and I/O ports. ...and they were reprogrammable! So I bought some, and then I bought some more. They've been quite useful, to the point that I rarely use my Z80 computer for anything.
So, in wanting to create my NTSC video generator, I've often thought of just programming one of those microcontrollers to count out all of the various delays between sync signals and just output the signals at the correct time. However, the AT89S52 is a bit slow for this. Despite running at up to 20 MHz, it requires 12 clock cycles to accomplish anything at all, and many instructions require more than that. So it's just a bit too slow.
The ATtiny13A, pictured above, is faster. It will run up to 20 MHz as well, though the internal oscillator only runs at 9.6 MHz. It also executes many instructions in only one clock cycle, and the remaining instructions require 2, 3 or 4. This means I can toggle bits with ~0.1 µs accuracy, which matches the precision of the numbers in the NTSC documentation I have. So a short string of NOP and an I/O instruction can change a bit exactly when I need it to change, and a loop using a counter can suck up delays too long for a series of NOPs.
Also, the small size is actually an advantage. If I fail to generate all of the signals I need with one chip, I can just generate half with one chip, half with another, and put the two next to each other and still have the problem solved in a very small space.
I received the chips on Friday, and took them with me when I went to visit my family at my mother's house over the weekend. While there, I reprogrammed one of my AT89S52 programmers to program these chips as well, then wrote the worst assembler ever, then wrote a little program to play a song.
The final circuit looks like this:
Yes, it works with just one battery. ...and I'm just ecstatic that I don't even have to connect a clock crystal, or buffer the outputs with transistors, or provide a power-on reset, or anything else. Even the reset pin doesn't seem to care that is is disconnected. (and you can disable the reset, and use that pin for general I/O, but doing so makes reprogramming it more difficult) It's so nice. I give it power and it gives me music. It couldn't be simpler.
I also love the battery-friendly nature of it. I'm so used to shit that won't run on anything but 5 volts, which is difficult to achieve with batteries. You need enough batteries to get to 6.5 volts to account for the 1.5 volt drop of a voltage regulator, and so you need, at a minimum, 5 batteries, or 6 if they're 1.2 volt rechargeables. ...but this damn thing will run on anything from 1.8 to 5.5 volts according to the documentation, and in reality seems fine with only 1.5 volts, but won't run on 1.2 volts from a rechargeable battery.
Honestly, at $0.60 a piece, these things are awesome. On countless occasions I've wished I could find a cheap chip to simply supply a power-on reset to my Z80 computers. These things have built-in power-on reset, and built-in brown-out detection with a configurable voltage threshold. If nothing else, I could just program one to keep its I/O pin low for a few milliseconds, then go high and do nothing else, and have a power-on reset chip for only 60 cents, which is far cheaper than any dedicated reset chips I've found in the past.
The only downside is that they aren't as fast as logic chips. For example, I can't program one to act as a NAND gate and substitute it for 74HC00 chips, since those chips are incredibly fast, responding to changes in input in less than 10 nanoseconds, whereas a 10 MHz CPU requires 100 nanoseconds for a single clock cycle, nevermind the time it takes to note that an input has changed, calculate a response, and output the response. However, despite their relatively slow response time, I'm sure I'll find plenty of applications for them.
For example, I'm also thinking I'll try to use these things for a MIDI synthesizer at some point. For some time I've wanted to build a MIDI synth that just outputs square waves, since they're my favorite synth sound and really simple. MIDI note on/off events aren't hard to decode, and generating a square wave at an arbitrary frequency is as simple as repeatedly adding an arbitrary number to a 16-bit counter and toggling an output bit every time it overflows. With 300 clock cycles between MIDI bits, it should be able to pull that off, and even if it can only do so for a single note, I can put ten of them together to get ten notes, and it would only cost $6 for all ten chips.
There are also slightly more expensive models with more pins, more memory, and more features. I recall seeing one with a hardware SPI I/O interface, which would allow me to output data to an SPI DAC without consuming too many CPU cycles, which would allow me to do waveforms other than square waves, and also implement attack/decay slopes, which tend to make square waves sound really nice.
Another project idea (though one requiring a chip with more I/O pins) is that, last year I bought this nice-looking remote control to use with MythTV, but despite the awesome design and multitude of buttons, I found that not one of the programming codes for it caused it to emit a unique code for each and every button on the remote, which just annoyed me to no end. I tried them all (and there were hundreds), but every single one of them either had a button which would do nothing at all, or a button which sent exactly the same code as some other button. It has occurred to me that the battery-friendly nature of these things means I could simply program one to scan the button matrix and emit whatever codes I want for each button. I already took the remote apart and sanded out the epoxied-in-place microcontroller, and scanned the circuit board and traced out all the traces. Looks like the hard part will be figuring out where to solder on wires without getting in the way of the keypad that has to fit on top of the circuit board. The remote kindly has lots of empty space inside where I can fit the microcontroller.
Also, I feel the need to comment on Digikey's $2.95 USPS shipping option. It isn't priority mail, which is why it's so cheap, and it only covers eight ounces. However, it's a hell of a money saver. I ordered 25 of the chips above, which weighed about an ounce and came in five ounces of packaging. So you can't order much, but even if the weight goes too high, I'm sure they'd just bump you up to the priority mail rate, which is the second-cheapest of them all. It's also usually the fastest. UPS and FedEx tends to take a week to ship anything to Ohio since they're usually shipping from California and if it takes 5 days to ship then that means you have to wait 2 more days for the weekend. USPS takes only two or three days from anywhere, and (until recently) would even deliver on saturday.