Saturday, 3 December 2011

Flashing LED Christmas Card Project

This is a DIY project to create a flashing christmas card based on a 555 timer. I did a project like this many moons ago at school, and when my local hackspace, Build Brighton, were thinking of seasonal electronics projects we could offer in workshops I decided to try to recreate this idea.

The circuit is a basic "astable" circuit (which simply means it oscillates between states). In this case we use the venerable 555 timer integrated circuit to make a square wave oscillator with a frequency of a second or two.

The output of the oscillator circuit goes to 0V, stays there a while, then flips up to 9V, stays there a while then flips back to 0V and repeats again. When the output is 9V it lights up a set of LEDs. The "clever" bit is that when the output is 0V a second set of LEDs light up, because those LEDs are already connected to 9V (i.e. "positive") on their other side, and get connected to 0V (i.e. "negative") when the output of the oscillator goes down to 0V. The end result is that the two sets of LEDs flash alternately.

I found a small current flows even between the "high" output of the 555 and the 9V supply, so the LEDs are never completely off but flash from dim to bright (but in some ways that looks even nicer :o)

The parts needed for this project are

8 x identical "standard" LEDs
1 x "standard" LED for top of tree (can be same type as above, but you might want a different colour)
9 x 220 ohm resistors for the LEDs (typically 220 ohms but you might want to experiment with higher or slightly lower values to get the brightness levels you want. I used 100 ohm resistors on my red LEDs and a 470 ohm on the blue led)
1 x 555 timer IC (e.g NE555)
1 x 10M (10 mega-ohm) resistor
1 x 470k (470 kilo-ohm) resistor
1 x 10nF (0.01uF) ceramic capacitor
1 x 100nF (0.1uF) ceramic capacitor
1 x PP3 battery snap connector
1 x PP3 battery
Some connecting wire (e.g. 1 meter or less of thin equipment wire)

You can build this by poking the component legs through holes punched in the card, then soldering them on the back. This is kind of fiddly but it wouldn't be quite the same end result to build it on a board.

The following diagram shows the connections from the INSIDE of the card (i.e. the side you see when soldering). Click to enlarge
When putting the 555 IC on the card make sure that you insert it through the front of the card with pin 1 at the top (the end of the chip with pin 1 will be marked with a notch or dimple).

The LEDs must be inserted the right way round for this project to work. The anode (+) side of the LED is marked by a longer leg and the cathode (-) has a flattened edge to the lens. Use the + symbols next to the LEDs in the diagram above to make sure you put them in the right way round and remember the diagram shows the BACK of the circuit!

The resistors and capacitors have no specific polarity and can be soldered either way round.

Don't heat components for too long when soldering. LEDs are particularly sensitive to overheating and it probably won't do the 555 a lot of good either. It helps to bend leads together (so they stay joined by themselves) before soldering so you can be quick with the heat.

My card was particularly utilitarian, but I'm sure you can make it look much nicer :) sticking a sheet of card over the wiring hides the mess and strengthens it all. It would be good to see other peoples results!





Saturday, 5 November 2011

Lost in Maths! (2D Sound location with 4 sensors)

This post is about my ongoing project to do fast 2D sound location on a ping pong table, this is some ideas I've been having and wanted to share - since I need some help!

Ok here's the problem... we have a rectangular area ABCD and somewhere in that area (point X) there is an event that produces a sound (e.g. a ping pong ball strikes the surface). This results in sound waves travelling outwards to the corners where they are picked up by sound detectors.

The first sound to be picked up at each sensor arrives at a time that obviously depends on that sensor's distance from the original sound. Lets call the times tA, tB, tC, tD. (Each sensor will pick up reverberations and echoes after the original sound, but its the first "edge" of the sound we're interested in)


Now since we don't know when the original sound happens (we only detect it when it got to the closest sensor) we don't actually know the real values of tA, tB, tC, tD but we get relative times from the first sensor. In this case X is closest to D,  the sound reached D first. The time we read at each sensor A,B,C is relative to tD. Graphically this can be shown like this (each red line is reduced by distance XD)


Now we can use these reduced distances to define circles based on the points A,B,C and D (radius at D is initially zero)

As pointer out by Arduino forum member Necromancer on http://arduino.cc/forum/index.php?topic=52583.0 we can find X  geometrically by progressively increasing the radii of the circles at A,B,C and D by the same amounts until all the circles intersect at a single point. At this point we have added back the unknown distance XD and the circles intersect at point X as shown below.


The problem is that this iterative calculation of circle intersections is processing-heavy and would probably take too long to solve on a microcontroller to be responsive enough for my application. However I started thinking about getting a "head start" by doing some simple calculation to get the initial increment where all the circles intersect for the first time, and go forward from there.

Here's what I mean.... point Q is a point on the line AC which is equal distances from the points where the initial circles around A and C cross AC.


The actual coordinates of Q aren't needed, we just need to know how much to increase the radii of the circles around A and C so that they intersect at the first time (which will happen at Q)


The calculation is simply the length of AC minus the radii of the two circles, all divided by two. If we calculate this value and add it to the radii of the circles they will meet at Q.

If we do the same calculation for lines AB, BC, CD, AD, AC, BD we'll get 6 different values that we should increase circle radii by make them intersect. We can just take the largest of all the 6 values and apply that as the base value by which the radii of all the circles should be increased to get to the initial point where all the circles intersect.

This will not neccessarily be  point X... we might need to interatively expand the circles a bit more to make them all intersect at the same point. However we got a big head start and so far we've just done simple arithmetic.

I made a simple program where I could click with the mouse to simulate the values arriving at the 4 sensors., then applied the above calculations... in many cases the results are very close to the final point X. For example:



In other places the accuracy is not so spot-on, but it looks like some kind of simple averaging of the points of intersection might give a position good enough for what I want, and without having to iteratively apply complex calculations (like square roots), so it should be pretty fast.





Only three sensors are strictly required for multilateration, however I found that adding the fourth sensor made a massive difference to the accuracy of the above calculation.

The next step is to calculate the points of intersection and give it a try with some averaging, to see if I can avoid the iterative method. However I'm not a mathemetician, so if anyone has a better idea, please let me know!

Update: OK, I gave the averaging thing a try. This clip shows my test program using these calculations to track the mouse pointer. The tracking is not perfect and there are a couple of places (vertical midpoint of the area, towards left and right side) where it is worst, but I think this is good enough (especially given that my sensors won't be perfect!). 

The program displays the fours circles calculated as above. The final calculated position is displayed by the red crosshairs

video

The process is as follows:

1. Firstly I need to simulate the sensor inputs, so I take the position of the mouse pointer, calculate distance to each corner and then subtract the minimum distance from all the others. The results (tA, tB, tC, tD) are representative of time or arrival info from real sensors.

2. For each edge, and the two diagonals I get the length of the line (area width, height or diagonal distance) and subtract the relative arrival times for the points at each end. 

offset1 = (width - tA - tB)/2
offset2 = (width - tC - tD)/2
offset3 = (height - tA - tD)/2
offset4 = (height - tB - tC)/2
offset5 = (diagonal - tA - tC)/2
offset6 = (diagonal - tB - tD)/2

Now take the maximum of these 6 values:

offset = max(offset1,offset2,offset3,offset4,offset5,offset6)

now calculate the circle radius by adding the offset to each time.

rA = tA + offset
rB = tB + offset
rC = tC + offset
rD = tD + offset

now calculate the intersection points of all pairs of circles. I used the C code example from here  http://paulbourke.net/geometry/2circle/

There are six pairs of circles, AB, AC, AD, BC, BD, CD. Not all may intersect (ignore pairs which do not intersect). Otherwise we get 2 insection points (which may be identical if circles just touch) for each pair of circles. Lets say that for each pair of circles we can get two intersection points P and P'

For each pair of points P and P', one will be closest to our target point and the other should be discarded. The way I did this was to calculate the average of all the points, then go back through the list selecting the point from each pair that was closest to the calculated average point and then averaging just these "closest points". 

ie. Take the first "rough" average of all points P and P' - lets call is (Xave, Yave), then recalculate the average position using either P or P' from each pair based on the condition:

if (Xp - Xave)^2 + (Yp - Yave)^2  > (Xp' - Xave)^2 + (Yp' - Yave)^2 
then use point P' 
else use point P

The resulting average (X , Y) is the final calculated point.

Better accuracy would be got by interatively increasing rA, rB, rC and rD and recalculating the intersection points until they are at their closest to each other. However I don't think I need this - the sensor input is unlikely to be so accurate it would benefit from this.... and I think it would be computationally expensive due to calling sqrt( ) many times and therefore slow.

Once again I'm no mathematician and I'd be grateful for any advice here!

Wednesday, 12 October 2011

Musical ping-pong tables and 2d multilateration

I'm currently trying to help out a local artist who is building an Interactive Ping-Pong Table, where each bounce of the ball generates a musical sound which depends on the position of the bounce.

I thought it should be possible to do this without drastically changing the table (i.e. without chopping the surface up) by using 3 piezo disks and an Arduino or PIC to time the arrival of the pulse at each disk and work out the position of the ball. It all sounded pretty easy, and an interesting project. Its certainly been interesting, but I'll think twice in future before deciding something is easy before I've properly thought  it through :o)

I found pretty quickly that some kind of amplification is needed.. the piezo disks are pretty sensitive to a sounds close by but not so great for something the other end of a table. First of all I tried to boost the level using 4069 inverter chips (I got that idea from Nicholas Collins' book - Handmade electronic music) since I've never really understood op amps and didn't want to get into all that dual supply rubbish. In my initial circuit I used an NPN Darlington transistor on the output of the amplifier stage to generate the logic pulse.

It kind of worked, but I was finding that the MCU would hang when an interrupt-on-change interrupt was being fired by multiple sensors. I also had a problem with the output getting stuck on (I think this might have been due to supply noise, noise picked up on a long wire to the piezo, and an overly sensitive amp stage). I  think the hang thing might have been due to noisy outputs triggering a rapid train of interrupts than the poor PIC could not handle. I have an IKA Logic analyser and using this I could see a mad train of pulses coming from sound waveform, echoes, supply noise whatever... I don't really know, but the PIC didn't like it.

Searching about for ideas online I read about running op-amps like LM358 from a single supply, which seemed to be a better way to do things than using logic chips as amps. I also saw how a 555 monostable circuit can be used to clean up a dirty pulse by keeping an output high for a timed period as soon as the first edge of the input pulse comes in, so the train of pulses from reverberations and so on get masked by a nice clean extended output pulse... nice and friendly for MCU interrupt pins.

The resulting circuit seems to work pretty well, even though it still seems a bit complicated. Maybe it is a case of over-engineering, but I learned a lot and it does at least work pretty well. Using SMDs I can also get it on a board about the same size as the piezo disk so it can sit on top.



For some reason I thought the maths behind working out a point from timing would be easy..and it is in one dimension with 2 sensors...



However working in 2 dimensions with 3 sensors seems to be a completely different kettle of fish... the technique is called Multilateration and there have been entire research papers written about it :o) The problem is that all the timing readings you're working with are relative... its more complicated than I  thought to get back to an actual position. Maybe I can simplify things, since my sensors will be arranged in the corners of a rectangular area and I can always calibrate them at the start by tapping the corners of the table. Or maybe some dirty trial and error approach will be good enough... Anway thats the next step... wish me luck..!

Here is the source code used in this clip

// SOURCEBOOST C
// PIC16F688
#include <system.h>
#pragma DATA _CONFIG, _MCLRE_OFF&_WDT_OFF&_INTRC_OSC_NOCLKOUT
#pragma CLOCK_FREQ 8000000

#define SENSEA            0b00010000
#define SENSEB            0b00100000
#define SENSE_MASK        (SENSEA|SENSEB)

typedef unsigned char byte;

// INITIALISE SERIAL PORT FOR MIDI
void init_usart()
{
    pir1.1 = 1;    //TXIF transmit enable
    pie1.1 = 0;    //TXIE no interrupts
    
    baudctl.4 = 0;        // synchronous bit polarity 
    baudctl.3 = 1;        // enable 16 bit brg
    baudctl.1 = 0;        // wake up enable off
    baudctl.0 = 0;        // disable auto baud detect
        
    txsta.6 = 0;    // 8 bit transmission
    txsta.5 = 1;    // transmit enable
    txsta.4 = 0;    // async mode
    txsta.2 = 0;    // high baudrate BRGH

    rcsta.7 = 1;    // serial port enable
    rcsta.6 = 0;    // 8 bit operation
    rcsta.4 = 0;    // enable receiver
        
    spbrgh = 0;        // brg high byte
    spbrg = 15;        // brg low byte (31250)    
}

enum {
    READY,
    LISTENING,
    TIMING,
    TIMEOUT
};

byte remaining;
long timeA;
long timeB;
byte state;

void interrupt( void )
{
    // check for interrupt on change
    if(intcon.0) // IOCA fired
    {
        // are any of the signals we're waiting
        // for now ready for us?
        byte savePortA = porta;
        byte whichSensor = savePortA & remaining;
        unsigned long thisTime;
        if(whichSensor)
        {
            if(state == LISTENING)
            {
                // start the timer
                t1con.0 = 1;
                thisTime = 0;
                state = TIMING;
            }
            else
            {
                // grab the current time
                thisTime = tmr1h << 8 | tmr1l;
            }
        
            // Grab times from sensors
            if(!!(whichSensor & SENSEA))
                timeA = thisTime;
            if(!!(whichSensor & SENSEB))
                timeB = thisTime;
                
            // clear bits for the sensors we 
            // already have
            remaining &= ~savePortA;
            if(!remaining)
            {
                intcon.3 = 0;            // ioca off
                state = READY;
            }
        }        
        
        // clear interrupt fired flag
        intcon.0 = 0;
    }    
}
        
////////////////////////////////////////////////////////////
// SEND A MIDI BYTE
void send(unsigned char c)
{
    txreg = c;
    while(!txsta.1);
}

////////////////////////////////////////////////////////////
// NOTE MESSAGE
void sendNote(byte channel, byte note, byte value)
{
    send(0x90 | channel);
    send(note&0x7f);
    send(value&0x7f);
}
void main()
{ 
    // osc control / 8MHz / internal
    osccon         = 0b01110001;
    
    
    // comparator off
    cmcon0         = 7;                      
    
    // configure io
    trisa         = SENSE_MASK;                  
    trisc         = 0b00000000;              
    ansel         = 0b00000000;
    porta        = 0b00000000;
    portc        = 0b00000000;

    // initialise MIDI comms
    init_usart();

    // 
    t1con = 0b00000000;
    
    // interrupt on change porta.4
    ioca = SENSE_MASK;
    intcon.7 = 1;
    intcon.3 = 0;
    intcon.0 = 0;

    byte note = 0;
    for(;;)
    {
        // Prepare to listen
        timeA=0xffff;
        timeB=0xffff;
        remaining = SENSE_MASK;
        state = LISTENING;
        t1con.0 = 0;            // reset the timer
        tmr1h=0;
        tmr1l=0;
        intcon.3 = 1;            // ioca on
        
        // wait to start timing
        while(LISTENING == state);
        
        // wait to complete timing
        while(TIMING == state)
        {
            unsigned long timeNow = tmr1h << 8 | tmr1l;
            if(timeNow > 0x8000)
                state = TIMEOUT;
        }
        
        if(TIMEOUT == state)
        {
            // ignore the interrupt if it does 
            // not register on all the sensors
        }
        else
        {
            long x=0;
            // i know i'm getting reading of up to 5000 'cos I printed 
            // them to serial port... you might get something different
            if(timeA > 5000) 
                timeA = 5000;
            if(timeB > 5000) 
                timeB = 5000;
            if(timeA) 
                x = 5000 + timeA;
            else if(timeB) 
                x = 5000 - timeB;
            if(x)
            {
                note = x/100; // is is in range 0-10000 so move this to MIDI range 0-100
                sendNote(0, note, 127);
            }
        }
        
        // delay (I think delay_ms function needs timer1)
        int i=1000;
        while(++i);        
        if(note)
        {
            sendNote(0, note, 0);
            note=0;
        }
    }
}

Monday, 12 September 2011

POV message fan project update


Got a bit of time this evening to test out the LED array I made yesterday for the Build Brighton message fan..

video

The thin wire-wrapping wires are soldered to a scrap  of veroboard for test connections , and the code is running on a PIC16F688. The shift regs are wired to share common clock lines, but each has its own serial data line, so all LED data can be loaded in 8 clock pulses so refresh should be nice and fast in the final thing.

Everything seemed to work first time, amazingly! These water clear RGB LEDs are nice and bright, but its possible to see the individual red/green/blue elements more than you would in a diffused LED (e.g. when you display yellow you can see the red and green elements rather than a single yellow point). I'm hopeful this won't be a problem when the thing is spinning and viewed from a distance.

My 100 ohm series resistance is rather low when the LEDs are run continuously but in the past I've found a low-ish resistance like this to be good when pulsing the LEDs quickly in a POV display. Still - I'll have to try to make sure the LEDs dont get left on 100% duty for a long time just in case they don't like the current.

I also mounted the board to the fan! With the help of some heavy duty double sided tape (for sticking carpets down) and cyanoacrylate superglue to hold the LEDs in the holes it seems to be pretty sturdy... famous last words...

Next step is to build a microcontroller board small enough to fit into the hub of the fan, then we (me and the Rev's Neil and Dave from BuildBrighton) need to get it power (via a pair of coils) and data (hopefully a modulated signal riding on the power)... and so the fun will really start!




Sunday, 11 September 2011

Home made flexible circuit boards

I got a couple of pieces of flexible copper-clad kapton sheet from ebay a few weeks back, and just got round to trying it out....

We have a new project at Build Brighton hackspace to make a POV fan to display SMS text messages sent to it. There is a long way to go, but one of the first steps is to make the LED array to be fitted to a fan blade. This needs to be as light and compact as possible, but I also wanted it to have sixteen 5mm RGB LEDs (thats a total of 48 LEDs to drive). SMD shift registers and resistors, together with a flexible (but more importantly thin and light) board seemed just the ticket.

I expected the sheets to be horrible to work with, and a nightmare for lifted traces, but actually it all went pretty well. I designed the layout for 8LEDs in EAGLE and then edited the image to double up the number of LEDS (my free version of EAGLE doesn't allow a layout big enough). I used press-n-peel blue toner-transfer film in my old HP LaserJet 1000 printer and ironed the toner onto the copper-clad film (just as I do for rigid PCBs) and etched in ferric chloride. Some gentle cleaning with fine steel wool and the result was pretty good.

I've had a bit of practice with hand-soldering SMDs.. I use a 0.4mm needle tip and a high temp (400 celsius) with 0.015" silver bearing solder. The high temp helps zap the solder without heating the part for too long, as long as you're quick. I do all the work through a 10x loupe and make a lot of use of tweezers and a flux pen, and to be honest I actually quite enjoy it!

There are 48 x 0805 resistors on the board and six 74HC595D shift registers, each with a 100nF 0805 bypass cap. The 5mm through hole RBG LEDs were surface mounted along the edge of the board and the shift regs were wired up with Kynar wire-wrap flex (I decided not to risk drilling the film). I used a wooden jig to space and hold the LEDs for soldering.

I had a handy roll of kapton tape which I used to insulate the ground track so it didn't short on the LED anodes passing right above it. Since the tape is heat resistant it behaved itself while the LEDs were soldered. This solved an otherwise tricky routing problem.

Soldering went fine, though it was obvious that things heat up much more quickly on the film than they would on a solid PCB, and solder stays molten longer since the heat has nowhere to go. I also think I should use a lower temp as the backing did seem to be getting slightly warped, but nothing serious.

However everything seemed to go OK and my first experience of making a flexible board went pretty well!

As for the POV fan project, I will keep ya posted






Monday, 4 July 2011

Solid State Tesla Coil Fun

A solid state tesla coil is one that uses transistors to switch the primary coil voltage (instead of a spark gap or mechanical contacts). Using transistors also makes it straightforward to get the coil to spark at specific frequencies (e.g. to play a specific musical note). You can also make a simple feedback loop driven by an antenna picking up the EM field, which can automatically "tune" the coil to run it at its resonant frequency.

Anyway - a few months ago I made a solid state tesla coil based on Steve Ward's design. I put it in a box made of acrylic sheets and hot glue which had a couple of flaws - namely lack of shielding of the logic ICs (like the 555-based oscillator which drives the coil) against the strong electric field - so the coil fried its own electronics! and the other flaw.. well it fell to bits basically :)

I always meant to resurrect it in a more appropriate metal case and decided to go for some cool 1.5mm aluminium treadplate (not realising how hard it is to bend that stuff with any accuracy). My recently acquired jigsaw and drill press meant I was able to put together a box made of MDF sheets and pine mouldings which actually looks mostly OK :) The secondary is magnet wire (about 800 turns) wound on a PVC drain pipe, topped with a steel sphere garden ornament.

Steve Wards circuit is designed to run at 120VAC US mains. I built mine using uprated MOSFETs, caps and bridge to run at 240VAC UK mains supply, but I'm still being a chicken and running the primary through a step down transformer at 30VAC. Once I've played with different drive circuits I will probably add cooling fans and give it a try on higher voltages via a variac. But, before I blow it all up, I'm going to play with it some more and try controlling it via MIDI.


First off I had to work out how to get the coil to play a tune. I already had a little PIC circuit that could play a dodgy version of "Captain Pugwash" on a piezo sounder. I tried Using an opto-isolator driven by the PIC's square wave output to replace the 555 timer output in Steve Ward's circuit and it worked.



Before I plug any MIDI leads into it I need to make a fibre optic connection. I think the EM field around the coil would induce a voltage in any wiring that wouldn't be too kind to a MIDI keyboard or soundcard. Working on that bit now....

Something else I had a go at was an "ion windmill"... this is simply an "S"-shaped bit of bent wire that can spin around a vertical wire stuck to the top of the coil. When the coil is on, the electrons streaming from the tips of the wire drive it round!

Thursday, 16 June 2011

FTDI's Vinculo Development Board: A Review

I was lucky enough to get involved in the Farnell/element14 'road test' programme, where individual electronic hobbyists get a chance to review (and keep) cool hardware items from Farnell.

If you don't know it already, element14 (www.element14.com) is a community/networking site for electronics professionals and hobbyists, run by the electronic components supplier Farnell...

Last year I was lucky enough to attend a really useful free Eagle (PCB Design Tool) course run by element14, and earlier this year my local hackspace, BuildBrighton, reached the final of the Great Global Hackspace Challenge which was sponsored (very generously) by element14.

While other suppliers might give out samples and freebies to industry, its refreshing that Farnell/element14 really do seem to be actively targetting and supporting the electronics hobbyist/hacker community - and so I am more than happy to sing their praises here.

Anyway, back to my road testing... I chose to review the VNCLO-START1 kit from FTDI. This kit is made up of a USB development board and a separate programmer/debugger board and the current cost on Farnell's web site is a little under £28.


The development board is branded the Vinco/Vinclo/Vinculo/Vnclo (it seems that FTDI aren't sure about the name yet, but I will call it “Vinculo”) containing the 64-pin version of FTDI's VNC2 'Vinculum' USB Host/Slave chip.

Very interestingly, FTDI have given the board the same form factor as an Arduino Uno, including pin-compatible Arduino shield header sockets and even an on-board ADC chip to provide the six analog inputs. This means that you should be able to make use of existing Arduino shields (add on boards) with the Vinculo, which is a clever move by FTDI.

The Vinculo can emulate an Arduino because it's on-board VNC2 chip is so much more than just a USB controller... its a fully fledged MCU. In fact it's a very powerful one, with a 16-bit core, 256kB of Flash, 16kB of RAM and 48Mhz clock among some other nice features... This makes it substantially more powerful that the AVR chip on the Arduino....And that’s before we get on to its USB support: Two full speed USB ports, each individually configurable as host or slave!

So, we're talking an impressive piece of silicon (and a reasonably priced one, with the 64-pin VNC2 chips selling on Farnell's site for just over £3, which is cheaper than the Atmega328).

I am planning to use VNC2 chips in two projects I have in the pipeline:

  • The first to USB-host a Novation Launchpad keypad controller and run a suite of animation/MIDI-input apps. The idea is to make a standalone version of my 'playpad' MIDI controller projects.
  • The second is as the 'brain' of my laser projector, where I need a high speed USB device to push coordinate data from a PC to a pair of DACs driving laser-projector galvos. Using a VNC2 means I can use a single chip (no need for separate USB chip and MCU) while avoiding the slowness of a polled USB stack implemented in software.

The Vinculo board seems like the perfect way to prototype these projects... so how to get started?

FTDI have a free, downloadable developer toolchain for the VNC2. This works with the VNC2 programmer/debugger to allow programming and interactive debugging of the Vinculo. And I really do mean interactive debugging... single stepping, breakpoints, watches and so on... controlled via USB to the debug board.. put that in your Arduino pipe and smoke it :)

So that's all good news, but once I got started I found a few problems with the developer tools which made me think FTDI may not be quite there yet...

First of all I was unable to use the IDE on my desktop computer (where I do all my coding) because of a strange display problem with the source code editor window - all the text becomes garbled and unreadable each time the window scrolls. I reported this to FTDI support who quickly got back with a 'That’s strange, we'll look into it' kind of response but no fix as yet. However, luckily my laptop doesn't get the same issue so I could move on.

The second issue I found was stability of the IDE, particularly during debug sessions but even some times when compiling, the IDE would stop responding and needs to be killed in task manager and restarted.

Moving on, I played a bit with some of the provided sample code. The Vinculo is not FTDI's first VNC2 evaluation board, and some of the sample code is for the older eval board, which has different pin to connector mappings, meaning that the older sample programs don't work on the Vinculo without modifications. For example the UART (used by the sample programs for debug output) has moved.

Luckily the remapping can be done in software.... a very nice feature of the VNC2 is that all the IO's go through a programmable multiplexer, so IO functions can be assigned to pins of your choosing. However the need to reassign IO's just to get the sample programs to work isn't what you want when you're first starting with a new device.

Another niggle is that while there are sample programs provided to demonstrate standard Arduino stuff (blinking LED, PWM examples and so on) what is glaringly lacking are any USB code examples that will work, without modification, on the Vinculo. Since USB is the attraction of Vinculo over vanilla Arduino I think this is something FTDI need to work on to make the board attractive to Arduino fans... I am still trying to work out how to modify the USB examples to get them running on Vinculo, and its not been straightforward.

On a more positive note, something FTDI have done is to create a simple application framework that should appeal to Arduino coders by presenting an Arduino-like syntax.... For example, when using the supplied main.c in your Vinculo project you define the Arduino standard entry points 'setup' and 'loop'.

Arduino-likey function wrappers like digitalOut() are provided, and libraries like Serial are emulated with structures containing function pointers, so familiar Arduino syntax like Serial.begin(9600); can be used.... Its just syntactic sugar, since behind the scenes the VNC2 API functions are being called, and its not 100% compatible (don't expect your Arduino code to 'just work' on Vinculo). However, it's a nice idea and will certainly appeal to Arduino developers. And you are still free to simply ignore it and work directly with the VNC2 API if you prefer.

FTDI also have a variety of documentation for online download, which I am still working my way through. I have to say the information seem to be a bit 'scattered' over many different application notes, but at least it mostly seems to be there. Its just a bit daunting and confusing when you first get started.

In conclusion, I have to say I'm very excited by this hardware. The VNC2 is a powerful and flexible chip, and the Vinculo is a great prototyping board, encompassing some innovative ideas by FTDI.

However, at the moment I think much could be improved in the accompanying development software package. For me it has been a uphill struggle, and I think that Arduino users who are not experienced coders may fall at the first hurdle with this.. that is until FTDI can iron out the IDE issues and provide a more consistent and usable set of Vinculo code samples.

This is a new product though, so I have hopes that these things will improve soon with software patches.

A couple of other things that would be nice are
  • That Arduino staple - The always-useful pin 13 LED
  • The ability to direct debug text output over the same USB cable that runs the debugger, where is can perhaps show up as a virtual COM port on the host PC (like on the mbed).
I will post again soon with my progress applying the Vinculo/VNC2 to my own projects... watch this space!

Monday, 6 June 2011

Solenoid Percussion for BuildBrighton's Noise Toys Event





Last monday, BuildBrighton (my local hackspace) along with Playgroup (Brighton arts and events collective), ran “Noise Toys”... a day of making noisy gadgets in a local pub, anyone welcome – as part of the Brighton festival fringe.

At BB we were intending to provide a selection of “sound sculptures” around the place, but in the end we only managed a couple, which included my Lava-Lamp modulated synthesiser and an “interactive solenoid percussion” thing, which I'll give you the low-down on here

My idea was to have some MIDI triggered solenoid percussion (similar to http://hotchk155.blogspot.com/2010/10/solenoid-drum-machine.html) together with some kind of control surface to allow passing punters to control the solenoids and make little tunes and rhythms.

I thought it would be fun to use my Novation Launchpad to control the solenoids.

The Launchpad is a grid of illuminated buttons that is intended as a controller for Ableton Live (music app), but like most things it can be hacked :)

A while back I made a little Windows-based program to run a “rain storm” sequencer on the Launchpad (as seen on http://www.youtube.com/watch?v=ZgMDTJce9D8). Basically this was a simple step sequencer where notes are triggered by pressing buttons on the Launchpad and they “fall” - only sounding when they hit the bottom of grid. Pressing buttons on the lower row toggles them between Green (notes in the column are played then cycled back to top of grid) and Red (note plays once and does not cycle)

To add to the challenge (and because I needed the laptop to run Reason for the Lava Lamps) I thought it would be nice to be able to run the rain storm sequencer without the computer....

The Launchpad is a USB device (it doesn't have 5-pin MIDI connectors) so something would be needed to work as a “USB host” to allow a program running on a microcontroller (Arduino, PIC etc) to listen out for button presses and to control the Launchpad lights while sending out MIDI notes to trigger the solenoids.

I'd thought about making my Launchpad into a standalone MIDI controller before, and I had been looking at the FTDI VNC2 USB host chip (more about that later) but first of all I decided to try out the Sure Electronics USB HID Host Module which is based around a PIC and is a little short of £10 on eBay including the postage.

Sure's board is a nice little module, with 0.1” headers for the PICKit programmer and for serial comms with other application hardware. It also has a USB Type-A (host) socket and couple of addressable LED's. The on-board PIC24FJ256GB110 supports “USB On the go” (OTG) which means it can act as a USB host. Sure's web-site has downloadable source code for a firmware app, based Microchip's own open-source USB host stack, that will host a standard USB mouse or keyboard.

The only disappointment here is that only a minimal set of I/Os from the PIC are bought out through the headers which limits applications of the board since most of the PICs I/Os are inaccessible. Still, its a nice handy board and reasonably priced. But will it work with the Launchpad?

The Launchpad is not a standard USB MIDI or HID device. Rather it has a custom interface using two interrupt endpoints. This can be accommodated on the PIC with a couple of mods to the “Generic” device driver code from Microchips stack. It was my first time working with USB hosting and with 16-bit PICs so it was a learning experience.

When used under Windows via the Novation drivers, the Launchpad shows up as a MIDI device and is controlled by sending it MIDI note and controller info to toggle the LEDs. When Launchpad's buttons are pressed, it spits out MIDI notes/controllers which an application can act on.

So that the MIDI interface from Windows but exactly is happening on the USB wire? Well, a quick bit of trace code on the PIC showed that exactly the same MIDI bytes are being passed between the USB endpoints, making it nice and easy to drive the Launchpad from an embedded USB host like the PIC. Thankyou, Novation!

So on to the Rainstorm sequencer program, which I wanted to run on the same PIC. The sequencer code itself is pretty simple, but there are some complications when using Microchip's USB host stack which meant it took a while to get it working....

The main gotcha for me was that USB I/O operations need to be first initiated then polled for completion (or they can send completion events). However, to keep the stack ticking, the app must poll it via a “USBTasks” function. Without this polling, the stack does nothing and I/O will not complete. Ok, so just call USBTasks all over the place right? No sireeee, not if you don't want to end up in a confusing re-entrant mess and watch the PIC collapse in a heap.

In fact you need to be careful not to make USBTasks call anywhere but the top level loop, and to make sure that the application attempts just one USB I/O operation between USBTasks calls. One result of this is that long sequences of USB I/Os can become painfully slow to complete. With the Rainstorm sequencer I found that it became very sluggish at responding to input when there were more than a couple of dozen notes in play.

I am looking forward to trying this on the FTDI VNC2 chip which has the USB stack and application running in separate threads and should be able to get much better throughput.

OK – back to the fun and games! So the UART from the PIC is broken out to the header on the Sure Electronics board, and with the code changed to set up the correct MIDI baud rate and remove all other UART debug output from the code I could just stick on a 5-pin DIN socket via a couple of 220R resistors and I was sending MIDI.

On the other end of the MIDI connection I had a breadboard with a PIC16F688 receiving MIDI through a 6N138 isolator and triggering 8 digital outputs (each mapped to a MIDI note from the sequencer). Each output goes through a 1K resistor to a TIP120 NPN power transistor which directly drives a solenoid. The solenoids need about 18 volts to work properly so there's a 7805 and smoothing caps between the 18V side and the 5V logic side. I also had a hefty cap (2200uF) smoothing the 18V side since the solenoids can cause some big voltage dips when they fire all at once and this can reset the PIC. The schematic is available here

Once all the electronics was working it was time for the art... and unfortunately I didn't leave myself much time for that bit. I ended up gathering up milk bottles and hammering together a wooden frame for them to sit on, all the night before the gig. I had for some reason assumed that milk bottles, tuned with water, would make a pleasing “xylophone” effect... I hadn't really anticipated the the terrifying wall of machine gun clinking that they actually threw out.

Hmmm, well, there is always next time :)

Thursday, 5 May 2011

Adding a composite output to a ZX Spectrum

Tonight at BuildBrighton we have Sinclair night! One problem that we have is that the Spectrum, ZX81 etc (and a lot of other 1980's home computers) do not have composite video output sockets but rather were designed to run on an analog TV set tuned to the correct channel to pick up their signal. Analog TV sets are getting a bit hard to find these days, so this is an inconvenience...

Many years back I got my Spectrum to run on an old greenscreen mono monitor I was given. I don't have that speccy any more but decided to try the same trick on a spec I picked up on eBay earlier this year. With a composite output it is possible to hook it up to most modern TVs and many computer monitors.

Well, technically there is nothing to it... the Spectrum already has the composite signal (it is fed into the UHF modulator box that converts it to a TV signal) so its just a matter of getting the signal to the outside world.

I already had a 3.5mm mono jack to coaxial video lead from an Olympus digital camera (its the lead for showing your pics on the TV set) so I decided to simply add a 3.5mm socket so I could use the same lead.

The modulator is the nice little tin box on the inside of the Specc's TV connector. Take care when lifting the lid off the speccy or you might accidentally pull out the keyboard ribbons


 Connect the SIGNAL (jack plug tip) to the connection going into the box furthest back from the TV socket (on my speccy it had a white plastic insulator). Connect GROUND (jack plug barrel) to the metal box itself, using solder to make sure you get a good connection.
 Fit the socket... ah hot glue, how thee makes a craftsman of any pleb!

... get out the swiss army knife and scratch a groove to accomodate the socket in the lid so it can close

And the proof of the pudding... a "Specbook"