Tuesday, October 23, 2012

Five Dollar Synthesiser (post in progress)

What do you get out of interfacing Arduino to a low cost keyboard -

UPDATE - New synthesis mode added - Auduino style grain synthesis



UPDATE - Listen to the five dollar synthesiser here - 


Why hack a cheap childs keyboad -
1) Three octaves or more of ready made piano style keys
2) A large number of general purpose buttons for configuring you synth engine, adding effects or controlling a sequencer

This post concludes with a sketch which will provide your keyboard with some interesting capabilities to experiment with -

3) Four different waveforms - sine, square, ramp and dirty triangle
4) An adjustable speed arpeggio mode, low speed = arpeggios, high speed = chord like effects, very high speed = spacey distortion
5) Arpeggio record and play back
6) Transpose function, this shifts the three octave keyboard up and down by upto 7 octaves to give full access to the 128 midi note range - its also used in the video to creating the sweeping Arpeggios.

7) Delay ! - the code now features a delay function which you can here in action in the video.

Quick demonstration of using transpose with arpeggios -



Interfacing a low cost keyboard to Arduino -

The keyboard I am using is available for around 5 to 10 dollars, any similar keyboard in this price bracket is likely to work in the same way so pick one up and prepare to plug in.

So whats inside your typical five dollar keyboard ?

The main features are two PCBs which connect the many buttons and keys in a matrix.

The top PCB has been turned over to show the buttons and connections.

The entire matrix of buttons and keys is accessible from the17 solder pads visible in the center of the top PCB. Through these 17 pads we can read the state of any of the 36 keys and 33 buttons on our example keyboard.

Your keyboard may have a different number of keys and buttons, but the concept will be the same - all of the buttons are connected in a matrix pattern and this matrix is used to read the state of the individual buttons.

In the top right of the picture you might be able to make out a small amplifier. This amplifier uses a LM386 Chip which has previously been featured on RC Arduino in the post 'Adding Audio To Arduino Projects', this drives a small speaker fitted in the keyboard.

http://rcarduino.blogspot.com/2012/08/adding-audio-to-arduino-projects.html


Zooming in for a closer look
While it might not be obvious from the picture the 17 solder connections represent 9 rows of 8 columns.

When a button is pressed it makes a unique connection between a row and a column.

By reading the state of these unique connections we know which keys are currently pressed. 


The great thing about using a ready made keyboard is that someone has already built the matrix for us. This many buttons and keys to plug into our Arduino is an excellent deal - its even better when you consider that we can read these buttons using only 10 or less Arduino pins.

How can we read the buttons using only 10 pins ?

The solution is multiplexing. To do this we switch all of the rows off and then switch each one on in turn. We record which row is currently on and then read the column to see if any keys are pressed.

If we press the center key of the keyboard, our column pins will not read anything until row 3 is the active (on) row. Then we can then do some simple maths to get the key number -

key number = (row * number of pins in a column) + column;

20 = (2*8) + 4

How do we do this with Arduino ?

One approach to this would be to dedicate a digital output pin for each row and a digital input pin for each column. This can be done but its a huge waste of resources, we would also need to write code to manage the switching on and off (multiplexing) of all of these pins.

A 4017 Decade Counter is a low cost widely available chip that will do this work for us using only 2 pins from the Arduino.


This chip has previously been featured on RC Arduino as a means to drive upto 10 Servos from just two digital output pins. It is a chip with all sorts of uses - LED Chasers, input and output multiplexing and more. If you don't have any, order a few, they are about 30 cents each and I can guarantee you will find a use for them.

http://rcarduino.blogspot.com/2012/08/arduino-serial-servos.html

The 4017 Decade counter does exactly what we want -

1) Has ten outputs
2) It only activates one output at a time
3) It automatically figures out which output to turn off and which one to turn on in a repeatable sequence
4) It does this switching across the 10 outputs and all we have to do is simply set an output HIGH then LOW to tell it when to switch to the next row.

Upgrading your keyboard
Your keyboard almost certainly has an existing micro controller inside it. In the example keyboard the micro controller is encased in a blob of white plastic so there is no chance to identify it or reprogram it.

To upgrade the keyboard we want to access the keyboard matrix using our Arduino, in the case of the example keyboard the microcontroller is on a separate board which can easily be removed by desoldering. 

Before - The microcontroller PCB is fitted sideways into the main key matrix PCB.

After - The original micro controller replaced with a set of wires that we can use to access the key matrix from Arduino.


Once the original micro controller is disconnected from the key matrix we can solder in a set of wires in its place, these wires will be used to connect the Arduino and 4017.

The Schematic

Parts List - 
8 * Current limiting resistors ( whatever you have between 500Ohms and 1K Ohms)
8 * 10K Pull down resistors
10 Diodes
1 * 4017 Decade Counter
Connecting wire



The arrangement of resistors shown for pin 4 should be duplicated for the 8 columns (pins 4 to 11). The 10K resistor pulls the input down to ground when the switch is open, without this, the switch would be floating leading to inconsistent readings. The 680 Resistors is in series with the pin and is there to limit the current entering the pin when a key is pressed.

In pictures
Columns
Starting at the bottom of the picture each column is connect to ground through a 10K pull down resistor.

The keyboard columns are connected through the thin white wires in the center of the picture.

These are then connected to the white jumper wires at the top of the screen through 680 Ohm current limiting resistors.

Thats it for the columns







Rows
Starting from the bottom we have the keyboard rows connected through the thin white wires.

Each of these is connected through a diode to an output of the 4017 Decade counter.










The full circuit - 72 Keys from 10 Arduino Pins using just one IC, 16 Resistors and 9 Diodes - 

Later in the series we can introduce a shift register to bring the number of Arduino pins down to 5 from the current 10.

Key Scanning Code


In order to ensure the code is portable between the Arduino Mega, Uno, Leonardo, Teensy and Due, the code makes use of the DigitalIO Library. This is not as fast as using direct port manipulation or the DigitalPin library but it is around four times faster than standard Arduino digitalRead and digitalWrite functions - a useful saving.

The DigitalIO and DigitalPin libraries are the work of Arduino forum user FatLib16 whose name comes from fast SD Card libraries that FatLib16 has also created.

The DigitalIO and DigitalPin Libraries can be downloaded from the following link -

http://code.google.com/p/beta-lib/downloads/detail?name=DigitalPinBeta20120804.zip&can=2&q=

For a complete list of FatLib16's libraries see here -
http://code.google.com/p/beta-lib/downloads/list

Some of these will be interesting to explore in the future as a way to add a sample and playback capability to the 5 dollar keyboard.

Key Scan using DigitalIO Library


 for(unsigned char sRow = 0;sRow <= (KEYS/COL_PINS);sRow++)
  {
    for(unsigned char sCol = 0;sCol < COL_PINS;sCol++)
    {

      // read each column pin using an array of DigitalIO objects, its faster than digital read
      // and portable to UNO, Mega, Leonardo, Teensy, Teensy 3 and Due in the future
      // Direct port manipulation is faster, but not portable.
      if(columnPins[sCol].read())
      {
        unsigned char sKey = (sRow<<3) + sCol;

        // Do something with this key
      }
     }
     clockKeyScanCounter(); // clock the 4017 to scan the next keypad row
   }


The Next Step


 The synth engine is provided by a single oscillator, using the library referenced in this post -


http://rcarduino.blogspot.com/2012/10/arduino-modular-synthesizer-part-one.html

The next version will include a simulated patch panel to configure the oscillator paths for a wider range of sounds and effects.

For a zip file including the complete sketch and modular synth library, message me Duane B on the Arduino Forum.

Duane B

11 comments:

  1. Man I really love your project. You've done a great job of simplifying it and explaining it well. This is exactly what I've been searching the web for for a year now, something this easy to understand yet freakin awesome!!! I have 3 keyboards, a load of rock band controllers and a Mixman dm2 dj controller and an arduino UNO still wrapped up just waiting to be hacked for a bit the ol sonic madness. You are great, can't believe you don't have a million comments, this is brilliant.

    ReplyDelete
  2. Thanks for the complements on the blog, you should check out the new video clip I added to the post today. I also have a few more I need to edit - one of them has me failing to play the 'fly like a G 5' hook, the synth sound is very close especially for a little 8-bit micro controller - its my attempt at playing it that is not so close.

    ReplyDelete
  3. Great project. I like the "five dollar synth" concept.
    I've made too Illutron and Auduino and some other arduino/audio/midi creations, and try to follow your tutorials. And I was wondering if it was possible (I'm sure you already thought about it) to add some LP, BP or HP filter effects. It seems impossible without FFT analysis, but maybe you have a cheap solution :)
    With multiple waveforms, 2 oscillos (arduino not enough powerful ?), and filters, the five dollars synth would be better than most of 200 dollars synth...

    ReplyDelete
  4. Hi, I Have a few ideas for filters, but I also have a half formed philosophy that the five dollar synth should continue to develop as a low cost machine with a highly configurable sound of its own - rather than try and build in features that any serious musician will already have or that would drive up the cost for any less serious visitors that want to build a machine of their own. Having said that I am looking at using switched capacitor filters and also for software techniques which would provide interesting ways to morph the sound without requiring too much computation. Stay tuned. Duane B

    ReplyDelete
  5. Yes, of course, the filter should have to work on the Arduino Uno. Or maybe some electronic (a few capacitors and resistors should be enough to make a basic LP filter). Maybe you already know, but I found this library which work on the Uno, and have a filter algorithm, but I don't understand at all how it works.
    https://github.com/sensorium/Mozzi/blob/master/LowPass1stOrder.h

    ReplyDelete
  6. Other idea for synth effects : There's a little effect processor called "biscuit" made by Oto :
    http://en.audiofanzine.com/multi-effects-processor/oto/biscuit/news/a.play,n.6103.html
    The principle is to create drive or bitcrushing by inverting bits of the digitalized signal (when you push a button on the box, it's inverting a bit). The sound is very crazy and impredictible.
    I think it shouldn't be too difficult to implement an algorithm which inverts bits in an arduino, and shouldn't take too much cpu. And the effect is very original.

    ReplyDelete
  7. Hi,
    I have used bit crushing and another similar effect 'gain' in the five dollar synth. The type of bit crush I have implemented is effectivley down sampling. The other effect, 'gain' is simply digitally multiplying the signal, this causes the output to overflow and wrap around distoring the waveform. I will have a look at the links you have suggested over the holidays.

    Thanks

    Duane B

    ReplyDelete
  8. hi, can you show the entire sketch? thanks so much...

    ReplyDelete
  9. Hi, If anyone wants the code, send me a message with your email address through the arduino forum - www.arduino.cc my username is DuaneB

    Duane B

    ReplyDelete
  10. Hey, I co-run our high school engineering club, and we're starting Arduino stuff right now. What are your thoughts on this project as a beginner project? If not, then what are some good projects you did as a young neophyte?

    ReplyDelete
  11. Hi, I would suggest the Illutron B or the Auduino as good projects to start with -

    http://rcarduino.blogspot.ae/2012/08/the-must-build-arduino-project-illutron.html

    or

    http://rcarduino.blogspot.ae/2012/08/adding-audio-to-arduino-projects.html

    Would be interested to hear if your club builds them and happy to post any picture or videos particularly if you come up with some nice enclosures or use interesting sensors instead of the simple potentiometers.

    Duane B

    ReplyDelete