Toy Keyboard Tone Piano

I have a few old toy keyboards kicking around that I’ve wanted to put an Arduino in, so I finally pulled one apart and had a go.  I was “live tweeting” it as I went in this Twitter thread, but thought I’d gather everything so far together into a single post.

Further posts in this series:

  • This part provides all the details for adding an Arduino to the original toy keyboard.
  • Part 2 demonstrates the toy keyboard running the Oskitone “Scout” firmware.
  • Part 3 introduced a 74HC138 3 to 8 decoder to handle some of the keyboard IO and added a simple volume control.
  • Part 4 started to document applications using the additional IO.
  • Part 5 fully embeds the Arduino into a second keyboard.

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

These are the key Arduino tutorials for the main concepts used in this project:

If you are new to Arduino, see the Getting Started pages.

Introduction

This is the keyboard I want to play with. I believe it is a “Chad Valley” 2.5 octave toy keyboard, with 8 voices, 8 rhythms, a few effects, and some basic recording capability. Inside it has three PCBs in total: one for the keyboard, one for the buttons, and a smaller daughter board with the main “chip on board” intelligence soldered to the button PCB via an edge connector.

IMG_5783IMG_5782IMG_5785

The original plan was to hook up an Arduino to the ribbon cable to the keyboard and decode the keys, but seeing as all the buttons are also on a PCB using the same “matrix” of IO pins and all IO appears on the edge connector to the “chip on board” module, I instead opted to hook up all the IO to an Arduino.

IMG_5788

As a bonus, I found that all the buttons were labelled with the IO pins used, which mean I wouldn’t need to spend ages following traces to work out what is connected to where!

IMG_5789IMG_5791IMG_5790

So there was just the small matter of removing the daughter card!

IMG_5793

Looking at the daughter card, pretty much all of it is an IO breakout for the “chip on board” under the blob.  The only circuitry seems to relate to the power: VCC and GND from the battery box was connected here and fed to the main board via the edge connector; and what looks like it might be a simple passive filter for the audio output.

In fact, I was able to show that connecting VCC and GND to a 5V supply; the “DAC” pin to a 3.5mm jack socket plugged into some amplification; and touching BP04 to BP24 I could make it play one of its demo songs!

So how are the IO pins used?  A little more examination of the main button PCB shows a bit more circuitry.

IMG_5801

There is an LED driver circuit hanging off BP14, and some kind of (what looks like it is labelled) “BOND OPTION” off BP10 which ties it to GND via an unidentified surface mount component.

BP20 to BP27 seem to be the eight common connections for the matrix of buttons and keys; and BP00, BP02-06 appear to be the other half of the connections for the buttons; while BP07, and BP11-13 appear to be the other half of the connections for the music keys.  All of these “other half” connections have diodes indicating that the BP20-27 are the positive connections and these “other half” connections will be negative.  BP01, and BP15-17 don’t appear to connect to anything and BP08, 09, 18 and 19 are not broken out on the connector at all.

I’ve superimposed the image of the daughter board connectors onto the button PCB below to show all this.

Toy Keyboard Edge Connector Circuit

So, in terms of scanning the matrix, BP20-27 can be set as INPUTS and BP00-13 (less the gaps) as OUTPUTS.  Typically, the INPUTS are configured as PULLUPs and the OUTPUTS are set HIGH by default.  Then when it is time to scan one “column” of the matrix, BP04 say, then that line will go LOW and any of the BP20-27 that then read LOW indicate a contact is being made.

KeypadSwitchScan

There is the possibility of some ghosting, but the diodes should help here I believe.  Curiously, BP13 doesn’t have a diode.  It isn’t obvious to me why that should be the case.

Other points to note at this stage:

  • The LED circuit appears to be “active LOW”.  The LEDs are lit when BP14 is LOW.
  • The cathode of the LEDs is connected via a resistor to BP04 (more on that later).
  • The two large capacitors on the daughter board are marked 220uF on the silkscreen, but have 47uF printed on them.

I decided to solder jumper wires onto the edge connector to allow me to plug them into an Arduino Nano.  Once I’ve had a bit of a play and everything is as I want it, I might soldering it in directly somehow, but for now this will do.

IMG_5802IMG_5803IMG_5810IMG_5811

It transpires that there was a bit of a problem with the connections from the right hand side of the button PCB to BP20, 21 and 22.  Some of the buttons on these lines weren’t working. I couldn’t find out exactly where the problem was, so surmised it was either in some of the “graphite” (I’m guessing?) over-track bridges, or maybe, as these all pass along the thin edge of the PCB parallel to the edge connector, they got damaged when the daughter card was removed.  There is certainly nothing visibly wrong that I can see.

Either way, I just opted to add in some small patch wires to restore connectivity.

The other piece of weirdness is that the cathodes of the LEDs were connected to BP04 via a 51R SMT resistor.  I don’t know why this was the case, but wondered if it meant they could be synced to the action of the keys or buttons somehow.  Anyway, I removed the SMT resistor and added a 10k resistor from the LED negative connection on the PCB to GND.  10k is high, but it meant that the LEDs were a lot dimmer, which is what I wanted.

As it isn’t really possible to test the keyboard itself without the back of the casing fixed in, I opted to make a small cut-out in the battery compartment for the jumper wires, so I can “hang” the Arduino out the back.  Again once everything is sorted, I’ll mount it internally somehow.

There was one final bit of weirdness I had to content with however.  It turns out that the keys on the keyboard are mapped to IO pins in a peculiar way.  First of all, I know that the “rows” are not full octaves – BP20-27 allow for 8 notes at a time to be coded – but they were reversed to how I would have expected them to be.  The lowest set of 8 notes is on BP13 moving up via BP12, BP11 to the highest set on BP07.

But the really weird part is that the lower octaves decode C-G and G#-D# for BP20 to BP27 (on BP13 and BP12 respectively) which is what you’d expect.  But the two upper sets of notes are backwards! The third sets goes from B down to E and the fourth and highest set goes from G down to C; for the same BP20 to BP27 (on BP11 and BP07).

Oh, and at some point I managed to damage some of the keyboard PCBs ribbon cable links to the button PCB, but that was relatively easy to fix once spotted.

Tying all this up with the markings for the buttons, means I have the following keyboard matrix to work with (note octave numbers are arbitrary, but show the continuity and sequence).  Yes, it really is labelled “BLUSE” on the PCB.  I noticed later that there is also a “FORG” and “VILON”.

toy keyboard edge connector table

This can therefore be treated as a 8×10 matrix with 8 rows (as INPUTs) and 10 columns (as OUTPUTs).  Coupled with an IO pin to drive the LEDs and one for the audio output, this means that I need 20 IO pins in total.

Here is how I’ve connected it up to an Arduino Nano. Notice that I’ve had to use RX/TX as digital IO pins.  A0-A5 are used in “digital mode”. Note that it isn’t possible to use A6 and A7 as digital pins otherwise I’d have used them instead.

I’m feeding the board with 5V from the Arduino 5V pin, which will be used to drive the LEDs and the onboard mini-amplifier for the speakers.  It was all driven by 3×1.5V batteries before, so I’m naively choosing to believe the extra 0.5V for VCC won’t be a problem…

Toy Keyboard Arduino Pinouts_bb

The Arduino KeyPad library can be used to decode all the keys and buttons.  The ROWs are set to INPUTs with PULLUPs active, so will always read HIGH unless a switch brings it low.  The COLS are OUTPUTs and all read HIGH by default except when one of the COLS is being scanned, when it is set LOW.  This means that any switches pressed will connect that ROW and COL and the ROW will then read LOW letting us know which switch is pressed.

As already mentioned, when using an Arduino Nano, only A0 to A5 can be used as digital INPUTs.  It isn’t possible to configure A6 or A7 as an digital INPUT pin on the ATMega328.

The key matrix I’ve used is therefore as follows:

const byte ROWS = 8;
const byte COLS = 10;
char keys[ROWS][COLS] = {
/*          BP00    BP02      BP03     BP04     BP05        BP06      BP07 11  12  13 */
/* BP20 */ {0,      B_ROCK,   B_VOLP,  0,       B_SLOWROCK, B_DEMOSEL, 79, 71, 56, 48},
/* BP21 */ {0,      B_MARCH,  B_VOLN,  B_STOP,  0,          B_GUITAR,  78, 70, 57, 49},
/* BP22 */ {0,      B_NEWAGE, 0,       B_PLAY,  B_DISCO,    B_TRUMPET, 77, 69, 58, 50},
/* BP23 */ {B_SW2,  B_SAMBA,  0,       B_REC,   B_BLUES,    0,         76, 68, 59, 51},
/* BP24 */ {B_DOG,  0,        B_TEMPP, B_DEMO,  B_VIOLIN,   0,         75, 67, 60, 52},
/* BP25 */ {B_BIRD, 0,        B_TEMPN, B_PIANO, B_BELL,     0,         74, 66, 61, 53},
/* BP26 */ {B_FROG, 0,        0,       B_ORGAN, B_MUSICBOX, 0,         73, 65, 62, 54},
/* BP27 */ {B_DUCK, 0,        0,       B_WALTZ, B_MANDOLIN, 0,         72, 64, 63, 55},
//                  BP20,21,22,23,24,25,26,27
byte rowPins[ROWS] = { 4, 5, 6, 7, 8,10,11,12 };
//                  BP00,02,03,04,05,06,07,11,12,13
byte colPins[COLS] = {A0,A1,A2,A3,A4,A5, 1, 0, 2, 3};
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

The numbers correspond to MIDI notes which might be useful in the future, but for now I turn these into frequencies for the Arduino tone() function, which outputs on D9 through the built-in speakers from the keyboard.

Find the code on GitHub here.

Closing Thoughts

It would have been a lot simpler to have ditched the buttons and just hooked up the keyboard to the Arduino, but I’m now pleased I can decode everything!

I thought the diodes would prevent ghosting of keys, but there are still certain combinations that have problems, so I’d like to look into that to at least understand why. I wonder if it is related to the fact that D13 has no diode…

In terms of turning this into something a bit more interesting, here is my todo list:

  • Get a simple Mozzi application installed to see how it sounds.
  • I have two analog inputs spare (A6 and A7) so I might see if I could add two potentiometers.
  • I need to decide what I’d like the buttons to do.
  • If I wanted more IO, I could use some kind of IO expander, shift register, or something else to drive the matrix – e.g. a 74HC138 3 to 8 line decoder.
  • I need to decide if I want MIDI out or not.  At present, I’m using RX/TX as IO pins for the matrix.
  • Do I want brighter, different, or just something more interested to happen with the, LEDs.
  • Once I’ve settled on the functionality, I need to find a way to mount the Arduino internally. I did even wonder about adding a socket in the battery bay to plug in the Arduino in and allow easy removal for programming, etc.
  • I need to decide on how to power it all.  Do I switch to USB or do I find a way to use batteries still?  Do I want to incorporate the slider power switch?

So, all in all, not a bad start.

Kevin

IMG_5827

Leave a comment