Sunday, August 25, 2013

Gracieplexing - a new method for LED multiplexing

Controlling LEDs is one common use for small microcontrollers.  Multiplexing techniques can be to control the maximum number of LEDs with the minimum number of MCU pins.  One popular technique is Charlieplexing, which is an improvement over basic multiplexing which allows you to control (1/2 n)^2 LEDs with n pins. With basic multiplexing 6 pins would allow you to control a 3x3 matrix for a total of 9 LEDs.  With Charlieplexing you can control 6 x (6-1) = 30 LEDs, but that is far from optimal.  With a technique I'll call Gracieplexing, you could theoretically control 728 LEDs with 6 pins, or n^3 - 1 LEDs with n pins.  So starting with 1 pin you can control 2 LEDs:

So how does this work? Well basic math tells us when we have n binary bits we can represent 2^n states.  If our output pin could only be in the high or low state, with one pin we would only have 2 states (1 LED that is on or off).  With tri-state MCU outputs we can represent 3^n states with n pins.  In the circuit diagram above when the pin output is high, the bottom LED will light up.  When it is low, the top LED will light up, and when it is high-Z, both LEDs will be off.  Vcc is less than 2x the forward voltage of the LEDs, so they don't light up for high-Z.

Below is a video demonstrating the technique on a breadboard.  Gracieplexing starts getting complicated when you have more than one pin, and so far I haven't figured a way to control 7 LEDs with 2 pins without adding a couple transistors to the circuit.  Even without using transistors, you can still control more LEDs than with Charlieplexing, and I'll go over the details of Gracieplexing with more pins in part 2.

Saturday, August 17, 2013

tiny programmer for the ATtiny85

The ATtiny85 MCUs I ordered from tayda arrived earlier this week, and I wanted to start programming them.  I had considered using my recently-acquired pro mini board as a programmer for the ATtiny, but I had fried it by accidentally connecting 12v instead of 5v to it.  So I decided to build my own programmer.

My linux machine has a parallel port on-board, in the form of a 25-pin header.  I didn't have a 26-wire ribbon cable to match, but I have some old 34-wire floppy ribbon cables that would fit.  I plugged it onto the motherboard parallel port header, got out a breadboard, and scanned the AVRdude documentation.  I used a 5mm 3v white LED for testing the data lines (the two leads fit nicely into the .1" spacing of the ribbon cable).  After some time I got it working (see video above).

A couple things I found while experimenting with AVRdude.  The first is to stick with parallel port pin 10 (or one of the other 4 input lines) for the connection to pin 6 (miso) on the ATtiny85.  The parallel port input lines have pullup resistors on them(which seems to be needed on miso), while the 8 data lines do not.  The other thing I figured out is that the resistors between the chip being programmed and the parallel port aren't absolutely necessary.  On the sck and mosi lines the resistors don't hurt (I used 1.2KOhm since I had a handful lying around).  On the miso, 1.2K didn't work - it was probably too large to pull the line down to a 0 level.  A 330Ohm resistor on the miso line worked fine.  I also found that reset line control is not necessary; just connect pins 1 & 4 permanently to ground (or one of the data lines that is low).

I wanted a permanent solution for a programmer, but was to lazy to solder up a circuit on a prototyping board to plug into parallel port.  I thought I could plug one side of a regular dip socket into the ribbon cable header, but the pins are to short to make a connection.  Then I remembered I have some old wire-wrap sockets from days gone by.  I dug them up, and after one failed attempt, I made a tiny programmer for 4-pin ATtiny devices out of a 14-pin wire wrap socket:

I broke off pins 1-7, and soldered one of the broken off pins to connect pins 1-4.  I soldered another broken leg between pins 4 & 9, broke off pin 12, and soldered a wire connecting pin 12 & pin 8.  Pins 1-4 of the tiny85 plug into pins 1-4 of the socket, and pins 5-8 go into pins 11-14.  I plugged the socket into the parallel port connector so pin 8 of the socket plugs into pin 10 of the parallel port, and pin 14 plugs into pin 4 of the parallel port.  Finally, I needed to add my dipsocket programmer to /etc/avrdude.conf:
# wire wrap socket programmer
# reset line is dummy - parallel pin 6 unconnected
# reset line permanantly wired to ground
  id    = "dipsocket";
  desc  = "Wire Wrap socket STK200";
  type  = par;
  pgmled = 3;
#  buff  = 4;
  sck   = 5;
  reset = 6;
  mosi  = 7;
  miso  = 10;

The buff (power) line is commented out because it works just fine with parasitic power of the sck and mosi lines!  The avrdude command line options are as follows:
avrdude -p t85 -c dipsocket -U flash:w:firmware.hex

Since they have the same pinout, this will work for ATtiny25 and ATtiny85 MCUs.

Wednesday, August 7, 2013

Getting started with Arduino & AVR

It seems projects using embedded micro-controllers are quite popular, with many references to them on Hack a Day and instructables.  I decided to take the plunge.

I'm cheap, so spending $25 for an Arduino UNO was out of the question.  For that price, my money would be better spent on a Raspberry Pi.  A UNO clone for ~$10, or a DigiSpark ($11.95 shipped) was looking more attractive.  I decided to order a variant of Sparkfun's Pro Mini from Fasttech for $5.25.
I could have gone for an even cheaper option of a bare ATtiny85 (and did order a couple of these as well), but wanted a more complete functioning Arduino-compatible board to start off with.  The AVR CPUs on the Arduino boards have bootloader firmware pre-installed, making programming a bit simpler.  LadyAda has a tutorial on AVR programming, so I won't duplicate it.  The bootloader uses serial TTL (0-5V) to communicate with the development host - both for downloading code and for your code to write to the host.  Comm ports on a computer (RS232) typically use -12 to +12V, so I'll either need to build a simple serial port adapter, or buy a USB to TTL serial adapter.  Since most new computers don't have serial ports, I'll probably go the USB route.

I'm planning to do my development in C under Linux.  That requires installing avr-gcc and binutils.  The package I installed are cross-avr-gcc, cross-avr-binutils, and avrdude.  The Arduino IDE is available for Linux, however I'm comfortable with vi and a shell prompt.  The Arduino libraries are in C++, and given the limited code space I'll be dealing with (8K in the ATtiny85), I want the code size efficiency of C.  Arduino Lite provides the basic functions of the Arduino library in less than half the code size.

Thursday, August 1, 2013

Home phone service over cellular

My wife had considered getting rid of her home phone service and go with just cellular, but prefers the ergonomics of a portable handset for long phone calls.  When I recently was switching her mobile service from Telus to Roger/Fido, the fido agent offered their wireless home phone service for $10/mth.  He also offered $50 in credits after two months to offset the $30 one-time cost of the adapter.  We decided to go for it.

Before the phone line adapter arrived, we received a shipping confirmation from fido which indicated the adapter is a ZTE WF720 which AT&T wireless has been using for their service in the US for the past year.

The adapter arrived by UPS, and included a fido 3G LTE sim.  I tried the sim in my unlocked phone, but it is pin locked (until I figure out how to crack it!).  So I installed it in the phone adapter (in the battery slot compartment), plugged in the battery & power, plugged in a phone, and got dialtone.  The sim was pre-programed with a temporary number to use while we wait to port the land line.

The sound quality is typical of a gsm codec - adequate but not as good as a land line.  For the heck of it I tried sending a fax, and it negotiated with the receiving side but failed on page 1.  So it's fine for voice, but not for data.  For the price, I can't complain.