Tag Archive for electronics

FPGA Project: Graphical LCD

First success with a new project: a simple frame buffer and controller for the graphical LCD display I’d previously used with an AVR.

The red board is a Papilio One with a Spartan 3E FPGA, power supply, SPI dataflash for the FPGA configuration, and a FTDI USB-serial IC for communications and programming. The white protoboard houses buffers to drive the 5V LCD from the 3.3V FPGA I/O and a MAX232 used to provide the awkward negative LCD drive voltage. To the left on the green protoboard is a 4-character dot matrix LED display.

A block RAM is just the right size to perform as a frame buffer, and they are dual-ported, so one port can be set aside for outside access. The frame buffer continuously cycles through the contents of that RAM with a simple state machine, occasionally wiggling control signals and delaying for a short period between each line to let the display react. The code will appear on GitHub when it’s cleaned up a bit.

edit: The code for the LCD controller/framebuffer is here.

AVR XMegaA4 breakout

Here at last is the breakout board I designed for the Atmel XMegaA4 a while back. It’s a simple thing, just headers, a crystal, a ISP programming connector, and various power supply and analog voltage reference filters. The board is sized to fit within Seeed Studio’s lowest cost bracket for their PCB service. The board:

Mostly surface mount parts…don’t let that scare you away, they’re not that hard to deal with…easier than through hole parts, in some ways. You don’t need to go buy solder paste, you do need some flux. The procedure:

  1. Apply flux to the surface mount pads with toothpick.
  2. Bead solder on the pads. If it gets sticky and forms peaks, use more flux. Get too much solder on, wipe it off with the soldering iron. You don’t need much, just enough to form a solder joint, and too much will make things difficult.
  3. Apply more flux…it will not only help solder flow, it’ll hold your parts in place (like solder paste does, but cheaper). Don’t apply too much…it’ll liquefy and pull your parts off their pads before the solder melts. You want the solder beads sticky, you don’t want your parts swimming in flux. Use toothpicks to remove excess flux.
  4. Tack the parts down on the fluxed solder-beaded pads, nudging them into place with toothpicks. Too large/round of a solder bead will make this difficult. Some troublesome parts are the inductor and the crystal load capacitors, which have a tendency to get pulled off their pads.
  5. Reflow the board. You want to heat the whole thing up so the solder melts. You’ll see parts shift into place when this happens. Electric skillets and toaster ovens are popular approaches to this, I’ve used a cheap hot air gun for my first two and a skillet for the third, and recommend the skillet (with a bent piece of aluminum sheet metal under the board to help spread heat and help with placement and removal). This board’s small enough to easily heat evenly with this approach. If using the hot air gun, approach the board slowly with the airstream to get the flux melted…this will help hold the parts in place better, and keep them from blowing away.

You’ll want to omit or remove the capacitors on PA0 (C10 and C11) and PB0 (C9 and C12) if you need to use those pins for digital signals of any significant speed, they are filters for external analog references. L1 can be replaced with a short wire if you don’t need the extra filtering on the analog supply.

The parts list:

Part Value Device Package
C1 100nF 0805
C2 15pF 0805
C3 15pF 0805
C4 100nF 0805
C5 100nF 0805
C6 10uF 0805
C7 100nF 0805
C8 10uF 0805
C9 100nF 0805
C10 100nF 0805
C11 4.7uF 0805
C12 4.7uF 0805
IC1 XMEGA32A4A TQFP44
JP1 PINHD-1X19 1X19
JP2 PINHD-1X19 1X19
JP3 PINHD-2X3 2X03
L1 27nH IMC0805ER27NJ01 L2012C
Q1 4MHz ABL-4.000MHZ-B2 HC49/S
R1 10k 0805

Most of the parts were available from Mouser, though I went to Avnet for the XMega32A4. The board should work fine for others of that series, of course.

And finally, the Gerber files:
xmegagerbs.zip

Remote shutter release adapter for Lumix G1

I’ve got a growing list of camera-related things I’d like to try, and the lack of a way to trigger the shutter for my Panasonic Lumix G1 has become a real annoyance. Unfortunately, Panasonic only offers one option, a wired remote shutter release that costs $80, though you can get it some places for a mere $50.

Fortunately, there’s another option, detailed in this blog post:
http://ranger9.net/?p=906

It’s a simple multi-resistance control, connecting various resistances across one circuit and allowing multiple functions to be controlled with one pair of wires…the second “ring” contact and the “sleeve” contact of the 4-contact 2.5 mm TRRS (“phone” or “phono”) plug. I’m not sure the high resistance has any use, it may allow the camera to detect that an external shutter release is plugged in. Closing the circuit with a 5 kohm resistance signals a half press of the shutter button, and a 2 kohm resistance signals a full press. A few resistors is all that is required to convert it to switch closure control. The second ring contact (connected to the 30-40 kohm resistor) appears to be the ground…this is unimportant if using relays or pushbutton switches, but needs to be accounted for if using transistors or optoisolators.

The main problem is the 2.5 mm TRRS plug used. I was unable to find one of the corded adapters he used, but found a cheap $20 Rocketfish headset that included an adapter. On opening, it proved to be a one-piece plug adapter, but I was able to cut it apart into a separate 3.5 mm jack and 2.5 mm plug. The wires connecting the two were potted in a thermoplastic compound…softening it with heat let me strip much of the bulk off with pliers, prying and cutting with a razor knife did the rest. Given how much trouble it was to get ahold of the 2.5 mm plug, I made a single general-purpose adapter that I would be able to use with a variety of external triggers. I free-formed the adapter onto the plug using 4 resistors (a 15 kohm and 22 kohm in series for 37 kohm total, and a 3.3 kohm and 2.2 kohm) and a header socket, and encapsulated the whole thing in hot glue for a compact and solid adapter.

There’s easier ways to get the plugs, I was unlucky and in a hurry. To my surprise, Mouser does not seem to have these 2.5 mm plugs. DigiKey doesn’t seem to have them either, but does have cords with the required plugs:
http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&name=CP-254S-M/M-ND

Chop one of those in half, and for $6.09 you get two plugs with cords attached. Or you may just want to buy the jacks and use the cords whole…for some reason I’ve found the jacks much easier to find than the plugs.

Newark was the only place I found that actually has the plugs:

http://www.newark.com/pro-signal/psg01501/connector-rca-phono-plug-4way/dp/26M2022

http://www.newark.com/pro-signal/psg01491/plug-2-5mm-jack-4pole/dp/24M6363

Pictures:

WiFi Christmas Lights

While looking for something to do with my 3.5″ Insignia Infocast, I came across this post about some controllable RGB Christmas lights: http://www.deepdarc.com/2010/11/27/hacking-christmas-lights/

WiFi-enabled Christmas lights seemed like a good way to test out a variety of things, and hopefully something to show to family members who don’t quite get what I do for work and play (while I’m not sure that WiFi Christmas lights is the best example for this, it fit the season). The result didn’t see any use during Christmas, unfortunately…setting up a Linux machine on a wireless network via the command line is not as straightforward as I’d hoped, so it never got hooked up at my family’s place. I never got around to coding any lighting programs, so only the most basic functionality is actually implemented and tested. But those basics are there: a CGI program that runs on the Infocast (which is essentially a Chumby One, with a 454 MHz ARM processor, 64 MB of RAM, and a WiFi dongle), displaying a web page and sending I2C commands to an AVR Xmega board, which itself is loaded with firmware that communicates with the LED string. A hex inverter is used as a 5V driver for the LED string communications line, and to provide some measure of protection should mishaps occur while wiring things up.

The Infocast main board plugs neatly into a solderless breadboard with the addition of a couple right angle headers to the “mod port”. I used single-row headers on both sides of the board, the header on one side soldered in “backwards” and extended with a straight header to get the needed length and spacing. The result worked quite well:

The lights themselves have simply been modified to remove the original remote control receiver, replacing it with a bit of ribbon cable and a header connector for plugging into a solderless breadboard. This is not ideal…if the connector pulls out of the breadboard, I’ve got exposed pins with 5VDC and fairly high maximum current flailing around near my largely-3.3V Infocast and AVR. It’s far more secure than the first approach, which had the connectors attached straight to the thick, unwieldy light string cables, though:

The long green jumpers are the I2C lines, the small DIP IC is a hex inverter powered off the 5.6 V from the lights and driving the LED comm line. There’s a FTDI USB-serial module that takes up entirely too much board space, but gives a serial console into the Infocast/Chumby One board. The black box underneath is the case and power supply for a dead Ethernet switch, adapted as a base for the protoboards. (someday, I’ll stuff one of the USB-serial modules into that box as well and free up some board space)

The Xmega32A4 board is one of my own design, made with Eagle, boards done by Seeed Studio, and put together with a Home Depot heat gun. A good part of the goal with this project was simply to get an Xmega talking with the embedded Linux devices via I2C, as a general purpose controller/data acquisition peripheral. This turned out to be quite trouble-free, once I figured out that my I2C addresses needed to be shifted by one bit on the Linux side (for those unfamiliar with I2C, some things consider I2C addresses to be 8 bits with the LSB a read/write flag, others consider them to simply be 7-bit addresses with the flag considered separately).

Due to various delays with the toolchain (do not run Bingo’s toolchain build scripts from avrfreaks.net, they have an entertaining failure mode in which they crawl up your directory tree executing “rm -fr *” as they go, and the script maintainers refuse to recognize this as a significant problem…fortunately I was able to restore from a recent Time Machine backup, and am now using an old toolchain until I can build a newer one that works), wireless configuration, and general lack of time, the code is nowhere near a finished product, but here it is in all its hodge-podge, undocumented glory:
xmegaxmas.tgz

Fort Wayne Hamfest 2010

http://www.acarts.com/hfmain.htm

November 13-14 (Saturday 9AM-4PM, Sunday 9AM-3PM)

I just barely missed the 2009 Hamfest…happened to check the calendar for it the following Monday. Going to try to get to this one.

Controllerless Graphical LCDs, part 2

It is useful! As expected, RAM and CPU consumption are major issues. Saving RAM by computing the data to send to the LCD line by line proved to only be possible for text and extremely simple graphics, even with overclocking. The timing requirements are far looser than those involved in generating video signals, but the refresh rate needed to avoid flicker is actually quite high, the LCDs are intended to be driven at 60 Hz. This leaves 260 microseconds to compute each line. Another annoyance is the LCD drive voltage, which is a negative supply rated to be as much as -20 volts…I’m now using the charge pump from a MAX232 level converter for the LCD supply.

I switched to frame buffers in RAM and upgraded to an ATmega32 I had lying around. It’s still not light on the CPU: even with text and frame buffer graphics, it consumes roughly 30% of the CPU time of a ATmega32 running at 16 MHz, varying depending on refresh rate and the specifics of what is being drawn, and on display size…graphics is somewhat faster than text, and displays much larger than mine probably can’t be used without blanking the display while other operations are being performed. Worse, gray pixels are indicated by setting pixels in one of two buffers, full black by setting pixels in both buffers, and displaying each buffer for two frames before switching to the other, to avoid odd effects due to the LCD responding faster in one direction. This requires two frame buffers, doubling SRAM consumption, and also requires a higher refresh rate to avoid flicker, which means even fewer cycles free for other things. I ended up using nested interrupts to allow timely LCD updates while without bringing everything else to a halt, an approach which seems to work well.

There’s not enough RAM on the ATmega32 for a full-screen frame buffer, but mixing text and graphics is fairly trivial. You could of course store larger static bitmaps in flash, this isn’t something that interested me. It is quite straightforward to split the display into quarters based on the column controllers, though, and I’ve mostly been using it as a 7×24 character text display (with 8×8 pixel characters and 1 pixel line spacing), and a 64×64 graphics area with gray support. This takes a 168 byte character buffer and two 512 byte frame buffers, 1192 bytes in total. The ATmega32 has 2048 bytes of SRAM, leaving 856 bytes of SRAM free for other uses. I could just barely do a 7×20 + 64×96 mode (1676 B), or I could drop the grays and devote up to 3/4 of the display to graphics. Since there are 2048*8 pixels on the display, you can also simply draw all RAM onto the display, with some interesting results:

The gray pixels are a bonus, the display was never intended to support them. On my display, they flicker badly at less than 80 Hz, but this likely depends a great deal on display and driving voltage. Flicker in gray shades can be reduced by setting alternating pixels in each buffer. Eliminating gray pixel support halves frame buffer RAM usage, or doubles screen area that can be used for graphics, and considerably reduces the redraw rate required to avoid flicker, reducing CPU consumption. It should also be possible to do gray values in the text area, at the cost of higher flash usage…a full 256-character set of 8×8 pixel font bitmaps takes up 2 KB, gray values would double that. Large SRAM sizes typically come along with large flash sizes though, and I am planning to investigate the possibilities of crude antialiasing for improving legibility of text.

As mentioned, the display seems to respond differently in when driven in different directions. This could be exploited to gain two different gray levels by only displaying each buffer once, but I did not find the resulting gray levels to be of much use in my display…I got “medium gray” and “almost invisible”. The possibility merits further exploration, though…different LCDs might behave differently, and other drive voltages or tweaks to the refresh timing might help.

Source code: https://github.com/cjameshuff/glcd

Driving controller-less graphical LCD

Digging around through some old parts recently, I came across an old Epson graphical LCD display that had on-board drivers, but no controller. The LCD is an Epson EG2401, reflective, no backlight, 256×64 pixels. It has drivers…one SED1190 driving the rows and four SED1180s driving the columns…but no on-board controller. The LCD is *supposed* to be hooked up to a SED1330 controller and SRAM, but since I didn’t have such a thing, this LCD sat around in a junk box for years.

I still don’t have a SED1330 controller to hook up to the LCD, but I found more information this time around, including datasheets on the drivers. These things are essentially just serial load/parallel output shift registers, with output electronics for driving the LCD. Row select is performed by shifting a 1 in and clocking it along to each row in turn, the SED1190 can handle up to 64 rows. 4 adjacent columns are written at a time: each SED1180 has 4 16-bit shift registers with their outputs interleaved. Simple in theory, but the process of clocking data in is more complicated than you’d expect to be necessary, and rather poorly documented. There doesn’t seem to be anyone else foolish enough to try to hook these LCDs up without a controller, but after some trial and error I did finally succeed:


Caveats: you’ll need a fairly fast microcontroller. The display needs to be continually refreshed, or the image will fade to nothing, and if the frame clock is not kept changing while power is applied to the LCD, the LCD screen itself may be damaged. This will consume a notable amount of processor cycles, and if the display isn’t updated fast enough, there’s visible flicker. If the line refresh rate is not constant across the display, there will be visible glitches and artifacts, essentially varying contrast from differences in the periods the LCD is driven. If the display refresh rate is too slow, the display lifetime may also be reduced. You’ll also need lots of SRAM, bitmaps read from program memory, or graphics simple enough to rasterize on the fly (sprites/bitmap characters should be possible). Representing a 256x64x1 bit bitmap takes 2048 bytes, and the ATmega16 I used only has 1024 bytes of SRAM, so I wasn’t able to simply display from a frame buffer. It’s really a job far better suited to a FPGA, or at least a faster microcontroller with more memory (like a ATmega644 or an ARM).

On the other hand, you have relatively direct control over the LCD, and can do things unsupported by the controllers. By rapidly switching pixel states, the EG2401 can be made to display gray levels surprisingly well, though large areas of gray tend to flicker visibly, and the plot display with one half-gray trace flickered badly at 16 MHz. Overclocking the AVR helped a great deal, and with it running at 26 MHz(!), the dual sine wave plot was nice and smooth. Many of the ATmega16′s peripherals are probably non-functional at this speed, but all I need to drive the LCD was GPIO.

Source code will come in a later post, I hope to optimize it further and develop it into something of actual use.

Character LCDs over SPI

Character LCDs with HD44780/KS0066U-compatible controllers are a widespread standard in electronics equipment, and are readily available and accessible to the hobbyist. However, microcontroller I/O pins are a scarce resource, and these LCDs use a parallel interface that requires 11 pins for a full implementation of the 8-bit interface. These controllers do have a 4-bit mode that reduces the requirement by 4 pins, and one pin can be saved by hard wiring the display in write mode, but 6 I/O pins must still be dedicated to the display, or at least shared with things that tolerate having the display connected. The big 4×40 displays are worse…these controllers are rather archaic, and each can only handle 2×40 lines. These “4×40″ displays thus actually have two controllers, sharing data and control lines but with separate enable lines, and so require 7 IO pins at minimum.

One common solution: the 74595 shift register. This device consists of an 8 bit long shift register with separate output latches…you shift data in, and then latch it into the output registers to update all outputs simultaneously. This is essentially the same hardware used for SPI, and conveniently, the ’595 can be wired to take input directly from a SPI bus, serving as a primitive port expander. For some reason many people bit-bang the shift register, manually toggling GPIO pins to clock data into it, but the ’595 is perfectly capable of being driven faster and more efficiently by an AVR’s SPI hardware. 8 outputs is enough to talk to a dual-controller 4×40 LCD with one pin free for a smaller LCD or backlight control, or up to 3 separate LCDs, while only using the SPI bus and one slave select. An example for a single-controller LCD:

The shift register data is transferred to the output latches on the positive going edge of the store clock input. That input thus behaves much like a slave select, the only difference being the behavior when less than 8 bits are clocked in before the rising “deselect” edge…the chip has no “selected” state and will output whatever the last 8 bits on the bus were on the “deselect” rising edge, so make sure not to select it if you don’t intend to write to it. The output enable and shift register clear inputs are active low: the first is tied to ground so that the outputs are always enabled, and the shift register clear input is tied to VCC .

This does come at some cost. An additional part is required, obviously: the shift register itself. The 4-bit protocol is a little more complicated to initialize and use, and takes two SPI transfers for every command to the LCD. Perhaps the biggest drawback is that the shift register is incapable of reading from the LCD. Data can not be stored in the LCD DDRAM, and it is not possible to poll the LCD state, so control is purely open-loop: you must wait for the LCD to process each operation before proceeding to the next. The cost of the ’595 is a small fraction of that of the LCD though, and readback from the display is generally not needed. And as a side benefit to all this, if the VHC logic family is used, the shift register will handle 3.3V or 5V inputs regardless of the LCD/shift register power supply…no additional translation of logic levels is necessary. With the increasing use of 3.3V parts and the high availability of old but cheap 5V LCD modules, this can be particularly useful.

When prototyping, it also takes up breadboard space, which is nearly as precious a resource as GPIO pins. I made an adaptor board for my 4×40 character module that allows it to be connected via a 5-pin connector (never mind the “screensaver”):

Some people do clever things with RC networks to automatically latch the data in the shift register after a transfer is done, which can save the slave select pin, but I’ve gone for SPI compatibility instead. With the separate slave select, the LCD can share the bus with other SPI devices.

Source code for AVR microcontrollers with SPI ports, using AVR-GCC:
http://github.com/cjameshuff/shiftlcd

More information:
http://en.wikipedia.org/wiki/HD44780_Character_LCD
http://www.fairchildsemi.com/ms/MS/MS-512.pdf
http://www.fairchildsemi.com/ds/74/74VHC595.pdf