posts/piano: rough draft

This commit is contained in:
dogeystamp 2024-05-17 15:46:08 -04:00
parent 1ba508485b
commit 2366190178
4 changed files with 147 additions and 0 deletions

147
posts/piano.md Normal file
View File

@ -0,0 +1,147 @@
# reviving a digital piano with new brains
2024-05-11
One day, I was playing my Roland HP-1500 digital piano,
which is an incredibly old model.
It suddenly started making weird electrical noises, and then it died.
I opened the piano up, and looked at the circuit board,
but my efforts to figure out what went wrong were ultimately futile.
At this point, I had a thought: maybe I could build a brand new circuit for the piano,
replacing the broken original board.
After all, how hard could it be?
I had just learned the basics of electronics, and this definitely seemed like a good learning experience.
That was a few months ago.
Recently, I finished implementing this project, which I named geode-piano.
Here is a quick demo of it (excuse the poor microphone quality):
<video width="640" height="360" controls>
<source src="/public/img/piano/demo.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
This project is powered by a single Raspberry Pi Pico, which runs firmware written in Rust.
Source code and build instructions are available on the [project repository](https://github.com/dogeystamp/geode-piano).
It took quite a while to get to this point, and so this blog post will document the process of designing and implementing geode-piano.
## how a digital piano works
First, before even designing anything, I did a bit of research on what was going on inside a digital piano.
This helps understand how feasible the project is and how complicated it will be.
### velocity detection
A digital piano is, electronically, just a bunch of buttons that trigger sound when pressed.
There is, however, a slight nuance to this.
A button switch has only two states, on and off.
On a piano, hitting a key really hard makes a loud note, and softly pressing it makes a soft note.
From the perspective of our hardware, a button press is just a button press ­
there is no information about intensity.
To measure the intensity of key-presses, some engineer decided that instead of every key having one switch,
they should have two switches.
These switches are placed so that they trip one after the other during a keypress.
By measuring the time between the switches' activations, the digital piano can estimate the intensity of a press.
A fast press is a hard press, and a slow press is a soft press.
This system works well, and is present in most digital pianos.
### key matrix
Because of the need for velocity detection, we expect that a typical 88-key piano will have 176 switches in total.
This is a problem:
usually, a microcontroller (the little computer inside the circuit that controls everything)
only has a few dozen input pins.
How are we going to connect all those switches to it?
If you are familiar with mechanical keyboard design, you'll have probably heard about a "key matrix".
This is what powers keyboards, both the typing and music-playing kind.
Essentially, a key matrix helps cram all those 176 key switches onto a microcontroller with way less input pins.
For example, look at this key matrix:
```
column
1 2 3 4
row
│ │ │ │
1 ─┼─┼─┼─┼
2 ─┼─┼─┼─┼
3 ─┼─┼─┼─┼
```
These lines represent wires.
The columns can be powered on and off,
and the row wires on the left are input wires.
Each intersection in this grid has a switch.
- When a switch is off, power flows only vertically.
- When a switch is on, power is also able to flow from the column into the row. Power can not flow from row to column, though.
> Note: this diagram and explanation are both simplified, so [click here](http://www.openmusiclabs.com/learning/digital/input-matrix-scanning/) for a more detailled explanation.
> In practice, diodes are used to ensure power doesn't flow the wrong way.
Let's say we turn on two switches in the column 1, and also put power through it:
```
column
1 2 3 4
row
┃ │ │ │
1 ━╋━┿━┿━┿
2 ─╂─┼─┼─┼
3 ━╋━┿━┿━┿
```
Power can now flow into both row 1 and row 3, where it can be detected.
Based on this, we can deduce that the switches pressed were `C1R1` and `C1R3`.
Now, turn off the power in column 1, and then test column 2 in the same way:
```
column
1 2 3 4
row
│ ┃ │ │
1 ─┼─╂─┼─┼
2 ━┿━╋━┿━┿
3 ─┼─╂─┼─┼
```
Here, only row 2 detects power, so we can deduce that only `C2R2` is pressed in this row.
At this moment, the switches in column 1 could still be pressed,
but we only check one column at a time.
Because power can not jump from a row back into a column, we only get results from the specific column that we are testing.
Now, we can test the 2 other columns in the same way.
By testing all columns rapidly, we will detect all the switches that are pressed down at any moment.
Using this matrix, we need 8 pins, while an equivalent non-matrix circuit would need 16 pins.
However, we sacrifice a bit of speed to save these pins because it takes time to scan each column.
### under the hood
So that's how a digital piano works, theoretically.
What does that look like, under the hood?
As it turns out, the matrix is accessible through ribbon cables (or _flat flexible cable_, or FFC).
The contacts on these cables correspond to the columns and rows of the key matrix.
Usually, you'll find one or multiple ribbon cables with one end plugged into the main board of the digital piano,
and the other ends leading inside the piano key mechanism.
Mine had two cables with respectively 18 and 22 pins.
A good practice when making projects like these is to ensure that it _is_ possible before doing anything.
To test that the ribbon cables were properly connected, I tested them with multimeter probes:
![A flat flexible cable with alligator clips on the contacts.](/public/img/piano/ffc-test.jpg)
After getting the polarity right, pressing some keys did trip the continuity test (which beeps if there is an electric connection between the probes).
Therefore, making my own digital piano circuit was feasible.
## project design

BIN
public/img/piano/demo.mp4 Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB