Kevin Reid's blog

Latest Posts


Kevin Reid
My Website


August 23rd, 2012

Software-defined radio


A couple weekends ago, I was musing that among my electronic devices there was no radio — as in AM/FM, not WiFi and Bluetooth and NFC and etc. Of course, radio is not exactly the most generally useful of information or entertainment sources, but it still has some things to be said for it, such as being independent of Internet connections.

Another thing that came to mind was my idle curiosity about software-defined radio. So, having read that Wikipedia article, it led me to an article with a neat list of radio hardware, including frequency range, sampling rate (≈ bandwidth) and price. Sort by price, and — $20, eh? Maybe I’ll play around with this.

What that price was for was RTL-SDR — not a specific product, but any of several USB digital TV receivers built around the Realtek RTL2832U chip, which happens to have a mode where it sends raw downshifted samples to the host computer — intended to be used to provide FM radio receiving without requiring additional hardware for the task. But there's plenty of room to do other things with it.

I specifically bought the “ezTV”/“ezcap” device, from this Amazon listing by seller NooElec (who also sells on eBay, I hear) (note: not actually $20). One of the complications in this story is that different (later?) models of the same device have slightly different hardware which cannot tune as wide a frequency range. (Side note: when buying from Amazon, what you actually get depends on the “seller” you choose, not just the product listing, and as far as I know, any seller can claim to sell any product. If you see a product with mixed “this is a fake!” and “no it's not!” reviews, you're probably seeing different sellers for the same product listing.)

Of course, the point of SDR is to turn hardware problems into software problems — so I then had a software problem. Specifically, my favorite source for unixy software is MacPorts, but they have an obsolete version of GNU Radio. GNU Radio is a library for building software radios, and it is what is used by the first-thing-to-try recommendation on the Osmocom RTL-SDR page (linked above), The MacPorts version of GNU Radio, 3.3.0, is too old for the RTL-SDR component, which requires 3.5.3 or later. So I ended up building it from source, which took a bit of tinkering. (I'm working on contributing an updated port for MacPorts, however.)

I've had plenty of fun just using it “scanner” style, seeing what I can pick up. A coworker and friend who is into aviation posed a problem — receive and decode VOR navigation signals — which has led to several evenings of fiddling with GNU Radio Companion, and reading up on digital signal processing while I wait for compiles and test results at work. (It sort-of works!)

This is also notable as the one time in my life where a ferrite bead on a cable actually did something — putting one on the computer end of the USB extension cord noticeably reduced the noise level. (And, of course, there remains a large, metallic hardware problem: antennas!)

(I could say more, such as the detailed fiddling to build GNU Radio, and various useful links, but it's taken me long enough to get around to writing this much. Let me know if you'd like me to expand on any particular technical details.)

February 20th, 2010

Today I first attempted to set up and program an ATtiny2313 AVR microcontroller mounted on an independent breadboard rather than the STK500’s own sockets. (I had until now only had chips which required external crystals — and all the crystals I had were well above their speed ratings!)

But I was getting extremely unreliable communication; avrdude would repeatedly fail to correctly read the device signature bytes or verify fuses. The failures were random; individual bytes were often correct, and very rarely the communication was completely successful. Sample failure:

avrdude: Device signature = 0x14910a
avrdude: Expected signature for ATtiny2313 is 1E 91 0A
         Double check chip, or use -F to override this check.

Or, when the signature read worked but the fuse-verify read failed:

avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e910a
avrdude: safemode: Verify error - unable to read hfuse properly. Programmer may not be reliable.
avrdude: safemode: To protect your AVR the programming will be aborted
That the failures are partial tells me that the chip is basically working and the programming connections are correct; there's just something marginal about the system. But what? Were my wires too long or too haywire? Did I need a closer decoupling capacitor? I got my hint while reading the ATtiny2313 datasheet's section on “Serial Downloading”:

Depending on CKSEL Fuses, a valid clock must be present. The minimum low and high periods for the serial clock (SCK) input are defined as follows:

Low:> 2 CPU clock cycles for fck < 12 MHz, 3 CPU clock cycles for fck >= 12 MHz

High:> 2 CPU clock cycles for fck < 12 MHz, 3 CPU clock cycles for fck >= 12 MHz

Hmm—what's my fck? The ATtiny2313 as shipped defaults to internal RC oscillator mode with a clock frequency of 1.0 MHz. The STK500 has a SCK period parameter, and mine’s set to: 1.1 µs. A clock frequency of 1.0 MHz (106 cycles/second) is a period of 1.0 µs (10-6 seconds), so this SCK period is way out of spec; I'm surprised it worked as well as it did.

I set the SCK period to 3 µs (the STK500 rounded it to 3.3 µs), putting it comfortably above the datasheet requirement of greater than 2 µs, and everything's working fine as far as I can tell — I haven't tried programming the chip yet, but repeated reads give no errors.

As can be found in the avrdude manual page, in order to set the SCK period, you use terminal mode (avrdude -t) and enter the command sck desired-period-in-µs. (The current period can be read with the parms command.) The tricky part is that avrdude attempts to communicate with the target chip before entering terminal mode! So you have to either keep trying until it works (-F to skip the signature check helps), or connect the STK500 to a target for which it is already correctly configured! (I haven't tried disconnecting the ISP interface entirely.)

I hope this helps the next person searching for “Programmer may not be reliable.”

February 15th, 2010

Back to electronics, at least for a weekend...

After making sure to have fresh or cleaned parts, and using fresh (rather than two and a half decades old) solder, I have managed to solder several joints reasonably successfully. I completed two tiny projects:

  • I assembled a WiiChuck Adapter (it imitates a Nintendo Wii controller accessory socket and plugs into a breadboard; the accessory protocol is just I²C).
  • I soldered wires onto a rotary encoder which is part of rev. 2 of my timer project (which I should post about), which was designed for PCB mounting and doesn't fit firmly into a breadboard due to the mounting clips. (It fits, loosely, into a wide DIP socket.) Having these wires, terminated with header pin sockets, I can now mount the encoder in a box. So, I now have a nice box with a knob on it. (The rest of the project hasn't fit into the box yet.)
WiiChuck adapter
WiiChuck joints slant view
WiiChuck joints side view
Encoder joints image #1
Encoder joints image #2
Encoder joints image #3
Encoder joints image #4
Encoder joints image #5
Encoder joints image #6
Encoder joints image #7

As you can see from the pictures, the WiiChuck Adapter went together nearly perfectly. The header and board were held in position by a standard two-alligator-clip helping hands. The one ugly-looking solder joint on the “–” pin is the way it is because it was the first joint I made, and I fed too much solder into it when it started melting. I removed most of the excess, but didn't attempt to fiddle it into looking perfect.

The rotary encoder turned out considerably uglier, but then, it was a harder problem: instead of joining PCB through-holes to pins designed to fit them, I was joining wires to pins. I had the helping hands to hold the wire against the pin, but it still shifted around a bit while I was working. Overall, I'm considering the results non-disastrous and a reasonable first try. The joint on the top in the first image (with lots of copper visible) might be a bit “cold” though. I did make one mistake I recognized afterward: I did not tin either of the surfaces before soldering them, which probably would have resulted in cleaner, quicker joins and less melted insulation.

January 21st, 2010

I used to wonder why color LCD displays always have backlights (and when the light is off they're very dark). I haven't actually researched the matter, but I recently thought of a highly plausible explanation:

A LCD per se is just a device which either blocks or transmits light under electrical control. A simple monochrome LCD (as in a digital watch) just has a reflective back panel; so the opaque segments are dark and the transparent ones pass the ambient light in both directions. If there's a backlight, then the light from it goes through the LCD in one direction.

A color LCD simply adds red, green, and blue filters aligned with the LCD elements, filtering the white backlight.

So, an ambient-light color LCD will be throwing away at least 2/3 of the light hitting it, because for any given red element, the filter is throwing away all the green/blue light, and similarly for the other colors. Therefore a reflective LCD displaying pure "white" can only achieve dark gray (compared to ordinary white objects which reflect nearly all of the light hitting them). Furthermore, the ambient light is not going to be coming in perfectly perpendicular, but from all directions — so it won't necessarily arrive through the same color filter as it departs through, leading to further losses.

November 24th, 2009

You probably already know about this if you're interested, but SparkFun Electronics will be having, on January 7, a “Free Day” on which you can order up to $100 and pay only shipping (plus any amount over $100). Shipping, to my location by the cheap options, was shown as ~$10 (thus “91% off”, not considering tax).

(I have no affiliation with, and have not ordered anything from, SparkFun Electronics; this is just some info that showed up in my feed reader. As far as I’ve heard they’re good folks.)

SparkFun’s product line is somewhat oriented towards the hip electronics hobbyist, the sort of stuff that Make talks about: Arduino, text and graphic LCDs, blinky light kits, wireless stuff (serial links, GPS, Bluetooth), robots, sensors, breakout boards/modules for surface mount components. Many of these items are high priced, but they have notable cheap stuff too; when I heard about this sale yesterday my first-cut list of 11 interesting items only totaled $62.

October 1st, 2008

This is not a complete tutorial; it is intended to collect the information that I needed to get started and didn't find obvious, particularly explaining the operations needed to compile a program, and the most basic of syntax, operators, and IO operations to use microcontroller-specific operations from C/avr-gcc/avr-libc. It does not cover designing circuits or choosing a programmer.

Needed software

Get avr-gcc, avr-binutils, avr-libc, and avrdude. If you're on Mac OS X, all three are available through MacPorts.


Create ~/.avrduderc to specify what kind of programmer you have and where it's connected. Mine looks like this:

  default_serial = "/dev/cu.KeySerial1";
  default_programmer = "stk500v1";

default_serial is the device for the serial port the programmer is attached to; default_programmer is the type of programmer; see the manual section on command line options for programmer type names. You can also specify these on the command line, but I figure since these are specific to your computer it's better to leave them unspecified in makefiles.

Writing code

  • char is 8 bits and int is 16.
  • The entry point is the normal int main(void); you don't have to do any special initialization.
  • Special registers are exposed as variables — e.g. PORTD = 0 to do output.
  • All normal variables take up scarce RAM — for constant data, use the facilities in <avr/pgmspace.h> to store it in program space.
  • Basic IO: Each port has three registers. For some port x, DDRx specifies direction: a 1 bit makes the corresponding pin an output, whereas 0 makes it an input. Reading PINx takes input from the pins; writing PORTx sets output. If DDRx has a 1 bit, then PORTx controls internal pullups on those pins.
  • For further info on the functions of the chip, read the datasheet for it; the translation into C is mostly straightforward.
  • The avr-libc manual contains info on its avr-specific features.
  • The avr-libc demo projects are informative and well-explained.


  avr-gcc -mmcu=at90s8515 -Werror foo.c bar.c -o foo.elf

Substitute the part number of your target chip for at90s8515. I use -Werror to reduce the chances I'll run broken code on real hardware.

  avr-objcopy -O ihex foo.elf foo.hex

This step discards the metadata the .elf file contains, leaving just the code, suitable for programming.

Programming (downloading)

avrdude -p 8515 -U flash:w:foo.hex

Substitute the part number of your target chip for 8515.

December 8th, 2007

The Electronic Goldmine


I recently purchased some items from The Electronic Goldmine. I placed the order on December 2 (Sunday); it arrived at my post office box December 7 (Friday). The box was large and the contents were well-padded; I think it could safely have been smaller.

Quality and details of the contentsCollapse )

October 7th, 2007

One of the requirements for the timer project is that the alarm sound be not too unpleasant.

So: What can I do with the current prototype hardware, a piezo element taken from a watch connected directly to a (digital) output pin on the PIC?

Trivially, fixed-volume square waves, by either toggling the output pin in software or setting up the PIC's PWM feature to drive it automatically. (Note that the PWM produces a minimum frequency of 1/16384 of the main oscillator.)

(I've moved the piezo output on the prototype to the RC2/CCP1 pin. This change is not yet reflected in the published circuit and program.)

However, I want software volume control, so I tried something more elaborate. I set the PWM to a very high frequency, and produce the audio-frequency signal by varying the PWM's duty cycle parameter. The characteristics of the piezo crystal filter out the high frequency, producing an effectively analog output.

After much twiddling getting this to work (CCPR1L is not the least-significant bits of the duty cycle), I found that square waves work well, sine waves are very quiet, and changing the amplitude has the expected effect. So while it won't sound great, I can at least program it to increase the volume gradually.

I haven't yet integrated this into the main timer program, so I don't know whether I'll be able to produce decent tones despite (or making use of) the timer program's counting interrupt.

August 6th, 2007

The Evolved Radio…

Having repeatedly heard the “they tried to evolve an oscillator in a FPGA, but got a radio instead” story, I was glad to encounter (via Making Light) a link to the original paper, “The Evolved Radio and its Implications for Modelling the Evolution of Novel Sensors”.

July 22nd, 2007

Timer project


This is my first nontrivial electronics project. The goal is to create a better kitchen timer; over the years I’ve had many break, and the model I’m currently using has an annoying UI and is usually too loud.

Ben Jackson sent me a PIC16F877 microcontroller and a bunch of parts, and I've finally gotten around to doing something with them. (Some of the parts in the photo I already had.)

I've written a separate page with more details on the timer prototype and my plans.

Steps to get to this point:Collapse )

The big things remaining are a multi-digit LCD display, calibration to real time, better input devices, and building it into a case.

(Please let me know if you'd like more information about some part.)

Powered by