Making a MIDI keyboard from an old children's synthesizer

image

One day, returning home, near the garbage chute in the entrance, I saw an old children's toy synthesizer. Passed by, since it was “sinful” to take it from the trash, but in my heart I wanted to drag it out of there. Already late at night, at about 2 o’clock, I decided to see if she was still standing there. And yes, she was still there! In appearance, she was completely whole and clean, so there was no squeamishness so as not to take her. So yes, I took her.

I have long wanted a piano for myself, I'm not a professional musician, but just to indulge - why not? Buying something "for the sake of pampering" I was "strangled by a toad", and here - a free toy. When I took it from the trash, I didn’t even think of using it as a child’s toy, I immediately thought: “Ohhhh ... a good base to try to make a MIDI keyboard.”
Since I already have some experience communicating with professional keyboards and MIDI keyboards, I immediately understood all the disadvantages of my idea. That is, a toy in fact will remain a toy. On the basis of it it will be impossible to realize the power of keystrokes. The “lightweight” plastic keys themselves, which are also incomplete, will not make it possible to perform something worthy on it.

First of all, the toy synthesizer was disassembled "to the screw", all plastic was washed well with soap. The boards and contact groups of keys are also cleaned.

After the disassembly, an understanding came of why people threw it away. A toy (I don’t know why: from time to time, from the Chinese quality of components or tough operation) firstly: the built-in speakers fell apart, and secondly: a broken connector from them stuck in the headphone jack, so there was practically no way to pull it out . Probably, after the toy stopped playing with the built-in speakers, they used it with headphones, and then after they broke the connector there, they just threw it away.

Inside, the toy synthesizer consisted of three boards that were interconnected by a cable loop. The central board, which was responsible for generating sound and other things, was immediately unsoldered from the other two boards and set aside. On the other two boards there were contacts for the buttons on the front panel of the toy and the piano keys themselves. I soldered the PBS connectors to them, especially since the hole pitch on the boards was just 2.54 mm.





After that, I spent a couple of hours drawing up diagrams of these boards with keys. As it turned out, the scheme is a simple matrix keyboard.



In the picture in yellow circles, the numbers are the numbers of the “horizontal” contacts, and the numbers on the keys are the numbers of the “vertical” contacts in the PBS-13 connector on the keyboard board.







After that, all this was thrown into a corner and dusted for a year. And then the period of self-isolation began ... It became boring and I wanted to do something with my own hands, especially since there is nowhere to go, and it’s impossible ...

In the end, I decided to try to finish this toy at least a little. The Arduino board was taken as the basis for the controller, and since the number of key chains is greater than the number of Arduino UNO pins, I decided to use the shift registers 74HC595 and 74HC165. As a result, we got such a scheme.



The circuit was originally assembled on a solderless breadboard. To test the operability of the circuit (that there are no errors in the connections anywhere), a test program was developed that showed that everything seemed to work. The algorithm of the test program was simple: one of the outputs of the shift output chip is turned on and values ​​are read in a cycle from the shift input chip, while pressing the keys. At first glance, nothing foreshadowed the trouble ... and everything seemed to work fine ...



The next few days, I slowly worked on “homework,” namely, carefully soldering all the components of the board onto a breadboard. I collected it all from what was at my place. He took the Arduino NANO as the control board.



Such a “sandwich” from the boards is due to the fact that the two boards of the toy (one with buttons, and the other with the keyboard) are located at different levels, and before I soldered it all I thought: “Is it possible to somehow connect it together using the components that I have at home to look more or less good? ” And so it turned out this design of two boards interconnected by connectors. From my point of view, for the home option, when we sit in self-isolation, it turned out quite well. I only had to cut the breadboard and slightly modify the toy body so that you could connect the USB cable to the Arduino board.



The realization that the device does not work exactly as I wanted came when I finalized the test program. The algorithm was simple: turn on each output of the 74HC595 chip, taking into account the state of the inputs of the 74HC165 chip, and write the result in separate variables. In total, 5 outputs of the 74HC595 are connected to the keyboard, so in the end I got 40 bits (5 * 8) of data after this poll. A string of 40 bits was output to the console, and keys were pressed to see how the device handles simultaneous keystrokes of several keys.



This is where the problem surfaced: if you press one key, everything was fine, but when you try to press more than 2 keys at the same time a situation arose when it was impossible to predict what would be read. The result could be correct with one combination, and with another it could be completely unpredictable. The problem was that the feature of this scheme was not taken into account. When several keys are pressed at the same time, not only several keyboard scanning verticals are locked (this is permissible), but several horizontal lines can be closed through the keys (which is by no means permissible). You can read more about this problem and how to solve it here.

I chose the “cardinal solution” of the problem, namely: I decided that for each key in the keyboard there will be a diode.

In my head, I already mentally began to think how I would have to cut the tracks on the board and put the diode in the SMD case in the gap. I climbed into my storage rooms and saw that I simply didn’t have so many diodes in the SMD case (do not forget that we all sit on self-isolation and going to the store for radio components is not very possible - since these are definitely not essential goods). A little upset, I decided to look more closely at the board: it may be possible to put output diodes on some of the tracks (I also had some of them). And then I saw that each key has a jumper (the board is single-sided) and the circuit is made so that instead of this jumper you can put a diode. Immediately I thought - you don’t even have to cut anything, you just have to put output diodes instead of jumpers everywhere.I also did not have such a number of output diodes. A thought flashed through my head: “maybe LEDs?” The circuit operates at + 5V and if you put red LEDs that have a minimum voltage drop (among the LEDs), then in the end there should be a logical level for the correct determination: the key is pressed or not.



With this in mind, I climbed into my stocks again and grabbed the red LEDs from wherever possible. There were exactly as many as the keys on the keyboard! This is a sign, I thought, and soldered several LEDs instead of jumpers for testing. Test results showed that the solution is working. After that, I soldered the remaining LEDs instead of jumpers. The test program showed that you can press at least all the keys at the same time, and they are all read correctly.



I decided not to put diodes on the additional buttons that are on the toy, because it is unlikely that they will be pressed by several pieces at once. Moreover, in the program I do not yet have processing for clicking on these buttons. Well, I haven’t yet decided yet how to use them.

The time has come to figure out how to make this device appear on your computer as a MIDI keyboard and in what format you need to send data.

The information found on the Internet told me that it is possible to make a MIDI keyboard from Arduino very easily and simply by pouring firmware into it, which will make the computer see it not as a COM port, but as a MIDI keyboard. Initially, I was guided by this decision , not particularly going into how it is implemented.

Now, when I got to him and read it carefully, I realized that my Arduino NANO board would not be suitable for this solution, since it had a COM port based on the CH340 chip. To use the firmware from the link above, only those cards are suitable where the USB port is already on the controller (for example: AtMega32u4) or communication via the COM port is not done on FT232RL type conversion chips or the like, but on AtMega microcontrollers. Therefore, the firmware in the board must send the data in MIDI format to the COM port, and on the computer you will have to install and configure software that will intercept this data and transmit it to the virtual MIDI port.
The algorithm for reading keys and generating MIDI commands was as follows:



The program for the Arduino NANO controller now looks like this.
//    +5V
//   ST_CP  74HC595
#define latchPin      11
//   SH_CP  74HC595
#define clockPin      13
//   DS  74HC595
#define dataPin       12

//     +5V
#define latchPin_IN   9
#define clockPin_IN   10
#define dataPin_IN    8

// ,       1-16    
#define BUT_OUT0      7
#define BUT_OUT1      6
#define BUT_OUT2      5
#define BUT_OUT3      4

byte but_out[4] = {BUT_OUT0, BUT_OUT1, BUT_OUT2, BUT_OUT3};
//       
byte kbd_in[5] = {0, 0, 0, 0, 0};
byte kbd_in_new[5] = {0, 0, 0, 0, 0};

//       
byte btn_in[4] = {0, 0, 0, 0};
byte btn_in_new[4] = {0, 0, 0, 0};

//  3  -   (1 - , 0 - )
byte kbd_out = 0b11100000;

//  
void init_electronics() {
  //  ,   +5V
  //  OUTPUT
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  //  ,   +5V
  pinMode(latchPin_IN, OUTPUT);
  pinMode(clockPin_IN, OUTPUT);
  pinMode(dataPin_IN, INPUT);

  //          
  for (byte i = 0; i < 4; i++) pinMode(but_out[i], OUTPUT);
}

//      74HC595
void write_5V(byte a) {
    digitalWrite(latchPin, LOW);
    //    dataPin
    shiftOut(dataPin, clockPin, MSBFIRST, a); 
     //"" ,      
    digitalWrite(latchPin, HIGH); 
}

void read_5V(byte *btn, byte *kbd) {
  digitalWrite(clockPin_IN, HIGH);
  digitalWrite(latchPin_IN, LOW);
  digitalWrite(latchPin_IN, HIGH);
  
  //    -    
  *btn = shiftIn(dataPin_IN, clockPin_IN, LSBFIRST);
  
  //    -    
  *kbd = shiftIn(dataPin_IN, clockPin_IN, LSBFIRST);
}

void setup() {
  init_electronics();
  write_5V(kbd_out);
  Serial.begin(115200);
}

//       ,   
void read_kbd_and_btn_state(byte *btn, byte *kbd) {
 byte tmp;
  for (byte i = 0; i < 5; i++) {
    write_5V(kbd_out | (1 << i));
    read_5V(&tmp, &kbd[i]);
  }
}

void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

//     num  ,   
// 0 -  0,  0
// 1 -  0,  1
// 2 -  1,  1
// 3 -  1,  0
byte compare_bit(byte old_state, byte new_state, byte num) {
  byte tmp_old, tmp_new;
  tmp_old = (old_state >> num) & 1;
  tmp_new = (new_state >> num) & 1;
  if ((tmp_old == 0) && (tmp_new == 0)) return 0;
  if ((tmp_old == 0) && (tmp_new == 1)) return 1;
  if ((tmp_old == 1) && (tmp_new == 1)) return 2; 
  if ((tmp_old == 1) && (tmp_new == 0)) return 3;  
}

void loop() {
  read_kbd_and_btn_state(btn_in_new, kbd_in_new);
  for (byte i = 0; i < 5; i++) {
    for (byte j = 0; j < 8; j++) {
      switch (compare_bit(kbd_in[i], kbd_in_new[i], 7 - j)) {
        //  
        case 1: noteOn(0x90, 0x1D + (8 * i + j), 0x7F);
                break;
        //  
        case 2: //noteOn(0x00, 0x1D + (8 * i + j), 0x7F);
                break;
        //  
        case 3: noteOn(0x90, 0x1D + (8 * i + j), 0x00);
                break;
      }
    }
    kbd_in[i] = kbd_in_new[i];
  }
} 


It makes no sense to paint in detail how to work with MIDI data, because it can be read here.

I will dwell in more detail on the software for the computer and the problems that I encountered. Problems arose, simply due to the lack of normal documentation for this software. So, in order for the computer to be able to successfully receive MIDI data from a device like mine, you will need two programs: loopMIDI and Serial-Midi Converter . For Serial-MIDI Converter, you also need to install Java, if it is not installed on the computer.

We start the loopMIDI program and create two virtual ports. I called them Arduino IN and Arduino OUT. This program will be a virtual MIDI device.



Next, run Serial-MIDI Converter and at startup we go through the process of setting it up. Unfortunately, you have to do this every time you start, but it’s not very scary, it is done literally in four keystrokes on the keyboard. The COM port number may be different; it appears on the computer when the Arduino NANO board is connected. The port speed is set in the Arduino NANO firmware. The red arrows indicate my settings, at which everything worked for me.



Actually, the setup process has been completed and you can already use some software that will play sounds by accepting keystrokes from the device. In the software settings, you must select "Arduino_OUT" as the input. In the picture below, an example of Kontakt Player setup.



It ultimately works like this:


What's next? And then everything happened exactly as I expected - the toy remains a toy with exactly all the shortcomings that I mentioned at the very beginning. Probably, the child will play this one in a buzz, but for an adult, after normal keyboard instruments ... It’s easier to buy any used MIDI keyboard cheaply and it will be much better than this toy. I decided to leave this toy as it is, but make some modifications with it:

  1. Leave the original case.
  2. Put working speakers and make an amplifier for them.
  3. Make it work in the “children's toy” mode without connecting to a computer, that is, so that it can play sounds itself.
  4. Make it possible to connect FootSwitch (the same pedal on the piano below) so that you can hold the sound after releasing the keys, like on a normal instrument.
  5. , .
  6. , -, .



I can’t do the implementation of most of the points, while we all are together “at home,” since I simply don’t have all the required components for this at home.

To implement paragraph 3 on the Internet, a solution was found called SamplerBox . The essence of the project is that you can connect any MIDI keyboard to the Raspberry Pi board, which processes MIDI commands from the keyboard and plays sounds or switches instruments, etc. It remains only to put the Raspberry Pi board inside the toy body, without the possibility of replacing the SD card (without disassembling the case), configure the buttons on the toy body so that they switch tools and this will be enough to leave this project in this form.

But all this will happen after the period of self-isolation ends.

I hope that someone will find my experience useful.

All Articles