… you revisit an earlier project to cook up some real-time display software.

Screenshot of the ECG application software

Screenshot of the ECG application software (click for full resolution)

The software is a simple add-on to the old byte-data-to-CSV-data converter mentioned previously.  Now the application renders samples as they arrive using a rather basic graphing library I’d written in the past.  The library uses SDL so, in theory at least, the application should be easily portable to Windows. The software also includes an IIR digital filter for mains hum suppression but, as yet, no facility for going “beep… beep… beep…”.

… you can’t find quite the AVR development kit you need, so you make your own.

Completed "Timeserver" development board

The board was designed as a first foray into embedded Internet and is intended, ultimately, to act as an NTP server using an external MSF radio receiver as a time and frequency reference.  It features:

  • A principally through-hole approach, for neatness, IC socketability and ease of routing.
  • A 1 Amp dual linear power supply (5V, 3.3V) with over-voltage protection (once T1 arrives from the supplier…) and a logic-level mains frequency output for use as a timing reference.
  • An ATMega128A 16 MHz microcontroller — chosen for its simplicity and the availability of a cheap (£10) programmer/debugger.  The ATMega128A is well supported by the GNU toolchain so no expensive proprietary compiler is needed.
  • 64kB SRAM to expand the ATMega128A’s on-chip 4kB, which would be a little restrictive for TCP/IP and Ethernet.  A 74573 latch, used for address expansion, hides underneath this chip.  The SRAM is actually 128kB, wired as a 64kB part.  A future tweak might be to make the whole memory available to the AVR by using the (currently grounded) excess address line as a software-driven page select line.
  • 128kB FLASH (IC1) for holding static data such as web pages and images.
  • An Ethernet interface provided by a Microchip ENC28J60 together with an RJ45 socket featuring integrated magnetics.
  • Frequency/Data input and output interfaces (two BNC connectors).
  • A 34-pin IDC header for connection to a back-lit LCD (16×2 line text display, not shown).

Here is the schematic.

I have much work to do on the software, insofar as it does not yet exist.  The board does, however, produce stable 5V and 3.3V supplies and doesn’t consume an unexpected amount of current (always a good sign).  My JTAGICE Mk.1 (clone) also finds and identifies the microcontroller, which must therefore be happy.

… you notice you have a slightly irregular heartbeat so (as well as obtain a doctor’s assurance that the condition is harmless) you design and build an electrocardiograph to see what’s going on.

ECG in operation

Building an ECG is such a common electronic hobby project that there are dozens of examples available, removing the need to reinvent the wheel.  I went for a three-lead reference design from Texas Instruments’ INA333 instrumentation amplifier datasheet and coupled this to my own digital interface.  The probes are standard ECG adhesive “dots” (thanks, eBay) with crocodile-clipped connections.  The probe leads have driven shields to reduce electrical pick-up — ECG signals are in the region of a few millivolts, from a source impedance of around a megohm, so care must be taken to shield interference.

The following picture shows the ECG trace obtained from the acquisition hardware, displayed on a digital storage oscilloscope before the digital side was populated.  It should be noted that using a mains-powered oscilloscope to probe the “patient side” of an ECG is dangerous because an electrical fault in the oscilloscope could connect the patient to a high voltage.  This risk is mitigated by the in-line ECG probe resistors and thorough pre-use checks of the oscilloscope.

ECG trace before digitisation

For safety reasons the patient side of the implementation is powered by a 9V battery. A simple 8-bit PIC microcontroller uses its built-in 10-bit ADC, sampling the analogue signal at 400 Hz (see the source code for more information) and passing the results across an optoisolation barrier to an AVR microcontroller on the PC-side.  The AVR acts as a simple UART-to-USB converter and was chosen for its simple USB connectivity.  PC Software translates the two-byte-per-sample frames into millivolt samples for analysis using any CSV-format friendly application, such as GNU Octave or Openoffice Calc.  In principle it would be fairly simple to write a real-time ECG graphical display but this was not considered a priority.

ECG data - Click for full resolution

The data could probably do with mains frequency filtering but does show a clear PQRST sinus rhythm.  For some reason the T peak seems somewhat exaggerated is actually what you’d expect for a 3-lead ECG (see comments).   The uneven spacing to the left of the trace shows my heart beating erratically.

The following is a photo of PCB with the 9V battery removed.  Note the isolation between the PC- and Patient- side ground planes, spanned by optoisolators in each direction.

ECG - PCB

The schematic is here: page 1 is the acquisition hardware, page 2 shows the micros and power supplies and the following are links to the PCB’s Top layer, Bottom layer and Assembly Guide.

… you custom-build a 1U Network Accessible Storage box that is quiet, versatile and reliable (but an EMC atrocity).

Liberace - Closed

This is an old project that has been serving me well for years, but after a remote distribution upgrade stopped it booting (caused by a missing depedency between udev and the custom kernel) I had to pop it (“Liberace”) open up to dig out the root drive so I could tend to it on another machine.  Hence I had a chance to take a few poor quality photos and document the build.

Liberace - Open

Basically it’s a simple PC build with a 1.5TB HDD but there are a few fun intricacies…

Liberace has a Flex-ATX Socket 370 (i.e. Pentium III era) motherboard and a 1.2 GHz Via C3-Nehemia CPU.  The motherboard is an industrial model, designed for long-term reliability (but this didn’t stop me having to replace electrolytic capacitors that had developed horrible leaks).  The CPU is a low power device, chosen to reduce electricity costs and fan noise.  In benchmarks it can’t really outperform a 800 MHz Pentium III for number crunching but it’s fit for the purpose and its built-in cryptographic functions provide virtually overhead-free full-disk encryption.

Liberace - Non-leaking capacitors, CPU and Flash

The operating system (originally Slackware, then various versions of Ubuntu, now Ubuntu 10.04 LTS), occupies most of a 1GB compact flash card connected as an ATA device.  The card also contains various services and software intended to make Liberace more useful than your run-of-the-mill NAS — as well as serving files over NFS and SMB, Liberace undertakes various housekeeping, update and backup tasks autonomously and can provide a Fluxbox desktop over an entirely virtual X session for running GUI-only software like JDownloader within java.

Liberace - PSU and RAM

Power is provided from an external 12V DC brick and a PicoPSU ATX DC/DC supply.  You may notice one stick of PC133 RAM is marked “BAD” — this is because it fails memory tests and would result in an unstable system if it were not for the BadRAM kernel patch, which allows the (tiny) faulty regions to be avoided.  This isn’t something I’d do on an important system but it has proven to be remarkably stable here.

The system uses 40 watts under full load and, since it uses only one fan (drawing external air directly onto the CPU heatsink and out across the motherboard and HDD), makes a quiet and unobtrusive always-on Linux box.

… you grow so tired of shoddy, plastic LED-based bike lights which break (or fall) off, get pinched if you forget to take them into the supermarket with you and fail on contact with rainwater that you over-engineer a lighting system for a bike which is itself not mechanically sound.

Principles:

  • Bright enough to see by, not just be seen
  • No chassis return
  • Weatherproof
  • Permanently secured
  • Hard-wired connections
  • Rechargeable in-situ
  • Scope for expansion, like dynamo top-up, but otherwise kept simple

Front Lamp

This ‘retro’ type parabolic lamp was bought as a 6V 2.4W part (for connection to a conventional dynamo) but fitted with a 12V 5W bulb and confirmed to operate at a sensible temperature.  It’s clamped to the (pre-existing) lamp holder using a bolt through a plastic sleeve and nylon washers to preserve isolation from the frame.

Rear Lamp

This pannier-mounted 200mW LED lamp was originally powered by 2 AA batteries.  PCB modification allows operation from 5V which is provided from the 12V supply through a 1 Watt monolithic DC/DC converter.  In total this is 63% efficient (electrically speaking) — not great but about as efficient as the original 3V design and far better than keeping the original LED configuration and using a larger shunt resistor (which would be 17.5% efficient).  The efficiency is academic, however, compared to the incandescent front lamp.

Battery Box (which seems wonky in this photo for some reason)

An IP54-rated die-cast aluminium box is U-bolted to the frame and houses the batteries, fuse, connections, switch and charger socket.  Initially I’d planned to use a “4.8 AH” (2.4 AH in tests) 12V lithium ion battery but ditched it when found ailing and imminently doomed components inside the atrociously designed charger.

Instead I’m using ten “3 AH” NiMH AA cells which in practice only provide one hour of lighting at 500 mA.  I suspect the deficit is a combination of false advertising (the cells were from eBay) and high load de-rating.  I’m currently considering alternatives.

Three core, 3 A mains cable may seem excessive compared to the flimsy wires typical of bike lights but it’s robust, weatherproof, has negligible voltage drop at 500 mA and the extra core provides future expandability.  Strain relief grommets are used throughout for fatigue reduction and weatherproofing at cable entry points.

The whole project was an exercise in simple, robust engineering.  A more electronically-complicated project is in the pipeline.  Stay tuned for more boredom.

… annoyed by fan noise on an (unnecessarily large) Ethernet switch, you knock together a variable speed fan controller using a microcontroller, a temperature sensor, a MOSFET and a slightly drunken, post-pub, late night assembly coding session.

Fan controller installed in case

Fan controller installed in case, between the fans and the power supply (ensuring a comfortable gap from the latter).

The controller reads the temperature using its 8-bit ADC and modulates fan speed linearly from a minimum at a case temperature of 30°C or below up to full speed at 61°C or higher using run-of-the-mill pulse width modulation.  It also runs the fans at full speed if it detects that the sensor may have failed (if it reads less than 0°C) and for a few seconds at power-up to ensure the fans start properly.

Here’s the schematic, here’s the board plan and here’s the source code.  Given the potential electrical noise from the fans, I thought it wise to run the microcontroller and sensor from an R/C filtered supply.  A pull-up on the gate of the MOSFET will run the fans at full speed if the microcontroller control pin fails open, or if the microcontroller is missing from its socket.  C1 is a surface mount ceramic capacitor mounted on the rear of the board, between the microcontroller’s supply pins.  The board is mounted on two self-adhesive plastic stand-offs.

There is no provision for fan speed sensing and it’s not worth designing a PID controller for this application ;) .

The Microchip TC650 would be a (slightly) cheaper and more elegant solution but it’s not economical to obtain in the UK.

FPGA Mandelbrot progress

September 20, 2010

My FPGA Mandelbrot set generator is now much faster. I’ve reduced each slave processor’s hardware requirements and the length of each processing stage using an FSMD architecture. It now renders about 3 million points per second (from its 62.5 MHz clock) and the buggy regions have been removed.

Now running at 512×384 (upscaled to 1024×768 before analogue XGA output) means that the internal block RAM (1.5Mbits of it) can be used as 7-bit-per-pixel video memory (rather than 1bpp). Combined with a 127-colour palette, set non-members can be coloured using their respective escape times:

1bpp Mandelbrot at 1024x768

Before: Note dodgy regions due to numerical bug.

7-bit palletised 512x384 Mandelbrot

After: Ooooh. It's also faster.

I’d wanted to use the on-board 128 MBytes of DDR2 for this but it turns out that driving dynamic memory is an enormous pain — for one thing you have to stop using it every 8 microseconds to let it refresh, which is rather tricky if you’re using it to generate video signals.  To use the DDR2 I would have to use a few video lines’ worth of block RAM as a buffer, continually bursting data to and from the DRAM.  There is no need for full 1024x768x12bpp at this stage but finding a simple way to use the DDR2 will become important when the board is to be used for statistical DSP tasks.

… you need a low-profile PCI MIDI interface but none exists (at least not cheaply) and so rather than buying a USB MIDI interface you trim your full-height PCI sound card to fit using a hacksaw.

Trimmed card in PCI slot.

Trimmed card in PCI slot.

The fitted card.

The fitted card.

Well it certainly looks the part.  Here’s the bit I didn’t need:

Line- and mic- inputs.

Line- and mic- inputs.

Of course I would have used a PCB guillotine if I had one.

My only concern when lopping off the two inputs (which are in a sparse, analogue-only area of the two-sided PCB) was being careful not to leave possible supply tracks connected to the ground plane via stray torn bits of copper.  Fine sandpaper was helpful here.  This is all quite safe but don’t try it unless you think you know what you’re doing.

It works.  Specifically it does now that I’ve replaced the unconventionally conductor-free DB15 connector with one from a sacrificial sound card.

The irony is the "Q.C. Passed" sticker on the other side...

No conductors!

It took me a fair while to spot that this connector was dodgy…

Nonvolatile storage

September 7, 2010

My opinion of Xilinx continues to diminish.

I have a Spartan-3A DSP 1800A starter board. Until recently I have been downloading firmware to the FPGA via JTAG for on-line program testing. To make things more permanent requires converting the configuration bitstream into a ROM image and programming it into either the BPI (parallel) or SPI (serial) flash chips available on the board.

These are programmed is via a technique called “indirect programming”, basically the programming software turns the FPGA into a flash programmer temporarily, then presents it (via the same JTAG interface) with the data to go into flash device. Nifty.

… Except the BPI flash programming process silently segfaults.

… And the SPI flash chip (Intel S33 family) included on the board is not supported for indirect programming. Instead, you must connect the JTAG programmer, via flying leads, to the SPI bus and use proprietary Windows-only software written, it seems, as a workaround.

Fortunately a pin-compatible chip (Numonyx M25P family) is supported for indirect programming (and fitted on later versions of the board). £11 and a little soldering later and my board can now do useful things without a computer hanging off it.

Another month passes…

August 4, 2010

… and nothing in particular has been all that notable. Bulleted, then:

  • FPGA work is progressing. To this end I got a Spartan 3A-DSP using its DSP slices to compute a Mandelbrot set in parallel. It ain’t efficient (it could, with a couple of tweaks, go 16 times faster than its current 1.5 million pixels per second) but that’s not quite the point — it has been a first foray in to parallel fixed-point maths on reconfigurable hardware. I’m waiting to find out, from my supervisor(s), what maths they want accelerated.
  • Xilinx have some funny ideas about standards compliance. Apparently, casting signeds to std_logic_vectors (and back again) in port maps is achievable in perfectly valid VHDL93, and supported by Xilinx’s simulation suite, but it’s not supported by their synthesiser, despite the types in question having identical underlying structures (arrays of std_logic) and therefore not inherently being a problem of synthesis complexity. I’m having to write wrappers and work-arounds to deal with this broken behaviour, all whilst becoming increasingly frustrated with vague, unhelpful and sometimes completely absent error messages produced by the tools. I’d like to have a word with the chap who thought “Syntax Error near line 423″ is useful. Forums and newsgroups tell me this is normal for Xilinx…
  • As well as the usual slew of duties, including a weekend at an air show, a 10k run (cycle responding) and some very quiet nightclub shifts, I recently spent four concurrent 0000-0800 night shifts on duty at the Cambridge Folk Festival. We had practically no casualties, so I was grateful for some decent company. We did, however, wash a spider out of somebody’s ear.
  • I have learned never to top up my bicycle tyres anywhere but at home. Apparently if your bike pump fails in a certain way it becomes a tyre deflater, necessitating a 4 mile walk home to the spare pump.
  • I’m off to a weekend juggling convention on Friday evening. It’s been too long since I’ve been to one of these.
  • Follow

    Get every new post delivered to your Inbox.