Week 20 - May 30th 2012 - Final Project Presentations

Weekly Assignment - Final Project Documentation

FabSynth Part 1 - Internals

This week I am presenting the internal workings of my final project, the FabSynth. This work covers skills from the electronics production, electronics design, embedded programming, input devices, interface and application programming, output devices and embedded networking and communications modules.

During the design process, I tried to utilise the 'spiral development' technique outlined early in the semester, whereby instead of trying to fabricate a large system all at once, incomplete until all the requirements are met, a series of more manageable interim endpoints are planned out and achieved sequentially, at each stage resulting in a complete though limited product. In terms of the electronics, this was partly achieved by having small boards each performing a distinct role that could gradually be networked together. The diagram below illustrates the way the different modules designed so far communicate:

General Info

The internals will be driven with attiny44 microcontrollers, with firmware written in C. All of the development had been done on breadboards, using the the breakout boards I designed earlier on the course. The basic board includes an attiny44, ISP header, 10k resistor pulling RST high, power LED and power capacitor, and header pins spaced to fit into a standard breadboard and provide access to all the attiny44 pins. the second board was an extension that included a USB socket and associated hardware, and linked the data lines to appropriate pins (a switch allowed software-resetting to be enabled or disabled - more documentation to follow).

PCB 1: Master_USB

The first board developed connects to a host computer via USB and sends and receives MIDI messages (according to the formatting specified in this document). The firmware is based on the V-USB software USB implementation and the attiny45 USB MIDI example here. I included a debugging LED in the circuit (as well as in all additional circuits) to give an easy way to confirm things are working - for instance, by turning the LED on/off according to received MIDI noteon/noteoff messages. At one point (before reading the USB MIDI specifications) I was actually using the LED to blink the individual bits of a status byte (using for loops and _delay_ms()) to try and work out what was going on - there's a lot you can do with one little light! Once I was satisfied MIDI messages were being accurately received and parsed, it was time for PCB 2.

PCB 2: Slave_Synth

The code for the synth board is almost entirely lifted from the 4bitsynth project, which I modified to be suitable for a tiny44 as opposed to a mega48 (not much work - changing some interrupt vector names, not using PORTD etc). However, while the original project includes a MIDI socket and uses USART to read in MIDI data, I replaced this with the bit-banging code from Neil's hello.bus.45 example. So this microcontroller waits for a transmission from the Master_USB board that includes the Slave_Synth ID (0x01), and parses the subsequent MIDI message as appropriate according to the original project code. Output, through an R-2R resistor network, is amplified using an LM386 low voltage audio power amplifier in standard 20x gain configuration which drives a small speaker.

One problem that I have encountered with this board is that will not play the full range of MIDI notes; below note 18 and above note 65 it goes a little haywire. For the minute, I've restricted the notes that it responds to in the code to this range, while I try to figure out the problem. The microcontroller is running with an external 20mHz crystal so is going as fast as it can. I have tried speeding up the communications (by reducing the bit_delay_time constant - on each of the microcontrollers!) but this doesn't improve the range. It may be a limitation of the attiny44 (the code was originally written for an atmega48)? Still working on it.

PCB 3: Slave_LCD

So by this stage I had a working USB MIDI synth. The next thing I wanted to do was to add a visual output. I decided to use an LCD and bought a Nokia 5110 LCD (84 x 48 pixels) mounted on a board with the required PCD8544 controller. There are various sources of information on driving this LCD - general info at Sparkfun, ladyada tutuorial, Arduino sketch, C code. I wrote my own version based on an almagamation of these. The LCD is very easy to drive using just five pins (possibly four, experimentation needed) plus power and the mass-produced LCDs (originally mobile phone replacement screens) are relatively cheap. The communications aspect of the code works in a similar manner to the Slave_Synth board, listening for messages directed the the lcdID (0x02) from the Master_USB board and then pasrsing the MIDI message to generate the 'real life' note (ie. note 60 = middle C, or C3) and displaying whether the note has been turned on or off.

PCB 4: Slave_IO

Communications with this board are slightly more complicated, as it needs to send the button presses to the Master_USB board. My initial attempt had the Master_USB board request a status from the Slave_IO board and then listen for a response, however this seems to take too long so affects the other functions of the Master_USB board. I think an interrupt-driven solution should help, and am still working on this!

<<< Week 19

Module Index >>>