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

No comments:

Post a Comment