Showing posts with label circuit boards. Show all posts
Showing posts with label circuit boards. Show all posts

20130206

DIY TinyMarquee: an Attiny24 based scrolling marquee

This project uses charlieplexing and software serial to push the capabilities of the AtTiny24. The source code and design files are up on a github repository.

Other DIY LED marquee projects may be of interest, including a large one hand-routed on protoboard, one made from Christmas lights, a network enabled display, one using ping-pong balls, and one implemented in the rear window of a car.



A terminal stock ticker

The python module ystockquote pulls stock prices and other information from Yahoo finance, "get_price(stockname)". Here is a short python script that downloads and formats stock prices and writes them to a local file.

Bitmap fonts 

We need to translate text into a format that we can send to a scrolling marquee. We send raw pixels, so that we can adjust fonts and graphics without re-loading the firmware. Columns of pixel data are sent as 5-bit integers over serial. I used Gimp to draw a font and this Jython script to convert it into bit-packed integers representing columns of pixels for each letter.*


To test converting text to the bitmap font, the script "scroll" takes the scraped data and scrolls it across a simulated marquee in the terminal ( there is also the short "terminal_marquee" script which scrolls indefinitely, but updates intermittently in the background )

Hardware

The hardware consists of 90 3mm LEDs arranged in a 5x18 grid. These are driven by 10 IO lines of an AtTiny24. The remaining free IO line is used to poll and listen for serial data.

There is also a 10K pull-up resistor on the AtTiny's reset pin, and a 0.1μF decoupling capacitor near the power pins. The surface mount AtTiny bridges one row of the LED pins, a bit unusual but this allows a compact layout with through-hole LEDs. The marquee gets power and data from a USB to TTL serial adapter.


Charlieplexing

Charlieplexing is a way to drive tons of LEDs form only a few pins. Since LEDs only light up when current is passed in one direction, you can place two LEDs for every unique pair of IO lines at your disposal. This lets you drive N*(N-1) LEDs from N IO pins.**

PCB design

While it is possible to wire up the grid of LEDs by hand, I would not recommend it. Instead of going through this tedium, you can design a custom board and get it professionally fabricated. I use the free version of Eagle Cad to design and prepare boards for manufacture. A full Eagle tutorial is beyond the scope of this writeup, but numerous tutorials can be found elsewhere online. The Eagle design files for this project can be found here.




Exporting gerber files for board fabrication

One you have finalized a board, you need to prepare design files for fabrication. PCB designs get exported to so called "Gerber" files, which are like the PDFs of circuit board design. Once you have these files you can send them off to a fab house for production. My favorite tutorial for this is on Hackaday.

For one-off boards, BatchPCB is the go-to place. For small runs, consider Advanced Circuits or Seeed studio's Fusion PCB service. For larger runs (more than 30), depending on board size, Goldphoenix is the place to go. Depending on which service you choose, you should get boards in a few days to five weeks. I used Seeed because it is relatively cheap, and it took about a month to ship to the US.

Part sourcing 

For cheap LEDs I use Ebay. For all other components ( especially the AVR microcontollers ), I source from Mouser or Digikey. For a low cost USB to Serial adaptor, look for "USB To RS232 TTL PL2303HX" on Ebay . These are cheaper than, say, an FTDI cable from Sparkfun, and have worked great for me. I'd hoped to save a few bucks by using charlieplexing and the AtTiny14 in the design -- the total cost of each board, shipping and USB-TTL converter included, from a lot of 10, is about $7.50:
10   boards     $30   
1000 LEDs       $10   
10   AtTiny     $14   
50   Resistors  $ 1   
10   Capacitors $ 1   
10   Headers    $ 1   
10   USB-TTL    $18   
-------------------   
                $75   
       /10      $ 7.50

Cleaning the boards 

After you're finished soldering, remove any solder flux adhered to the board. Apart from being unsightly, flux can be conductive and corrosive and damage the board over time. Hackaday has a good tutorial on this. We filled an old jar with 90% Isopropanol, dunked the boards in there, and shook them around for a while -- it worked wonderfully.

Software serial 

The Attiny24 does not have hardware support for serial ( UART ), so we'll have to make a software implementation. For information about the RS-232 communication protocol, see the wiki. I used polling at twice the serial rate (4800Hz) to monitor incoming serial data, which is works for transmitting five bit packets. Further details about the firmware can be found in the C source file.

Compiling with avr-gcc 

I never remember the commands to compile and upload firmware, so here are the commands for future reference.

#compile source to a file a.o targeting the AtTiny24
avr-gcc -Os -mmcu=attiny24 ./display_serial.c -o a.o 

#extract the text and data sections to make a binary for the AVR
avr-objcopy -j .text -j .data -O binary a.o a.bin 

# check the size ( this should be smaller than the amount of available flash )
du -b ./a.bin

# upload the binary to ( in this case ) the AtTiny24 
avrdude -c avrispmkII -p t24 -B4 -P /dev/ttyUSB1 -U flash:w:a.bin 


_____________________________

*If you don't have Jython or a working JVM installed, it may be easier for you to re-enter the font as text data and write a short conversion routine in python.

**If you're familiar with multiplexing there's a simple way to conceptualize board layout for charlieplexing. When you multiplex an NxN grid of LEDs, you use N IO lines to control power to the (-) ends of the LEDs, and N IO lines to control power to the (+) ends of the LEDs.  To go from multiplexing to charlieplexing, note that microcontroller pins can take on three sates : Low (-), High (+), and Off ("high impedence"). Each IO line can serve as both a (+) line and a (-) line. What happens if we use the same N pins to drive both the (-) and the (+) a multiplexed display? Everything works fine, as long as we use the "off" state to stop current. One problem: there some LEDs along the diagonal of the matrix that have their (+) and (-) driven by the same IO pin -- there is no way to make these light up. But, no worries, since we are laying out our own board, we can just delete these LEDs, or connect their (+) terminals to a reserved IO pin to regain control of them! Charlieplexed PCB design can be relatively simple: lay out a grid of LEDs as if you were to multiplex them, but connect the N anodes to the N cathodes, and either delete the N LEDs that end up being connected to the same IO line at both ends, or wire these up to a separate IO pin to finish things off.


20100817

Mill PCBs using Adobe Illustrator

I elected to design a couple circuit boards using a vector graphics editor rather than Eagle cad. This allows for smooth organic traces and arbitrary graphics, but can make fabricating the boards difficult. I would recommend Eagle cad or some other program that can output gerber files if you are designing a board that you might some day want to mass produce. These instructions and scripts pertain specifically to the "Modela 3D plotter" devices. These instructions are absurd and more of a satire of actual PCB milling.

Quick preview
0 - sketch it up
1 - rasterize
2 - screw around in Gimp
3 - convert to mill file using python
4 - adjust and mill board
5 - export to SVG & use python to turn SVG into drill file
7 - manually adjust and drill board


Software links
cad.py (for generating mill code, from here)
circle.py (for extracting circles form .svg and converting them to modela drill file)
modela-move.py (for manually positioning the mill)
modela-send.py (for sending a .rml to the mill with buffering)
realign.py (for applying affine transformations to .rml files)
stats.py (for getting .rml plotting bounds for sanity check)
- files not guaranteed for correctness, may generate commands that break mill, be careful
- realign hates negative numbers
- note to self : hosting on dropbox, move later
- requires python serial libraries and BeautifulSoup packages to run

0 - Draw the board. I set up a 0.25" grid which is good for 0.1" pitch components. Use circles only for component pads, and put a circle at the center of each pad. This makes it possible to strip out the circle positions with a script to generate a drill file. I connect pads with smooth splines and add custom artwork. Routing and positioning is all done by hand.

1 - Export your file and process through "cad.py" script from fab-lab to generate code for your milling machines. In fact, "cad.py" crashed when I tried to process SVG directly. Instead, rasterize the SVG at 600 DPI and process it as a .PNG. A few things to watch out for : Adobe Illustrator uses a default 72 DPI, while Inkscape uses 90 dpi. That is, units in the exported SVG file will be in 1/72nds of an inch from Ilustrator, and 1/90ths of an inch from Inkscape. Hence, opening a SVG at a DPI other than what it was created at may cause problems.


2 - I never thought I'd be using The Gimp for circuit board design. Open the 600DPI rasterized file. First, make the background is opaque, and invert the file such that traces are white and the background is black. Then apply gaussian blur followed by threshold to round out the traces, and manually corrected close traces with the paintbrush. Gaussian blus+threshold can also be used to shrink or grow the size of board features if you are having trouble with traces being too thin or too close together, but watch out for accidentally merging traces. This is absolutely absurd, but it works, and cad.py liked .PNG more than .SVG.


3 - We wrote a collection of utility scripts for the Modela milling device. These include

realign.py for apply arbitrary affine transformations to a mill file (works on standard in/out, redirect files to/from these IO streams to read/write from files). This is useful for moving the file co-ordinates to just the right spot in mill co-ordinates. This is also useful for manually aligning drill files or two sided circuit boards, since they seem to be a bit off sometimes. It can't handle negative coordinates at the moment.

The file stats.py simply prints out the number of plotting commands (redirect files to standard in), followed by the minimum and maximum x and y coordinates of the milling file. This is good for a sanity check to make sure your file is in the right location. It can't handle negative coordinates at the moment.

The file modela-move.py accepts x,y,z coordinates and moves the mill to that position.

The file models-send.py accepts a .rml file piped from standard in and sends it to the milling machine. This script is necessary to avoid overflowing the command buffer on the mill.

4 - Use realign.py to move the output of cad.py to the correct position for milling. Use stats.py to double check that your board is where you think it is. Calibrate and position the mill. You probably want to make sure the x,y,z speeds are set slow. I have been using the slowest speed of "1" because I broke way to many bits going faster. Read up on the Modela mill or ask the mill owner to train you in its operation. TODO : collect some useful links here ?

5 - Prepare the drill file. To do this, redirect a SVG of the board to the "circles.py" script. This script will extract the centers of all circles, remove duplicate circles, and create a semi-sane set of drilling commands. However, it does not use exactly the same coordinate transforms as cad.py, hence drill files are off anywhere from 5 to 40 mils ( the machine uses 'mil' as the basic unit, which is 1/1000" ). Whatever transform you applied with realign.py to the board file, do this also to the drill file.

6 - Manually adjust your pen down height to be 50 mils above the board. Run a test run to see how far off the drill file is, and use realign to move it to the correct position. I really wish I had a better procedure here. When the first hole looks aligned, set pen down to -80 mils and drill. Make sure there is something underneath the board so you don't dril through the bottom of your milling bed.

This actually works. I milled nine boards the the past couple days. Designing circuit boards in drawing programs, and using gaussian blur and paintbrush aren't generally part of the workflow for circuit board production. You can also just print off the board and use the toner transfer method, then drill by hand.

The results look nice, though 0.1" pitch is as small as it can go for through-hole work. SMT probably has a higher resolution since you don't have to worry about the holes.

p.s. : I dislike how google sends the blog post out to the RSS feed when its first created, such that subsequent grammar corrections are not reflected in people who read this blog via RSS reader. I guess this just means I should proof-read better.