PiBot: De Arduino-aangedreven pianorobot voor precisiemuziek
Onderdelen en benodigdheden
| Arduino 101 | × | 1 |
| Texas Instruments 74HC595 (shift register) | × | 11 |
| IRFZ44N N-kanaal MOSFET | × | 88 |
| 12V accu | × | 2 |
| Condensator 100 µF | × | 11 |
| OpenBuilds draadkabel (per meter) | × | 1 |
| Breadboard (standaard) | × | 11 |
| 8-pots IC-socket | × | 11 |
| Weerstand 10k ohm | × | 88 |
| 1N4007 diode | × | 88 |
Benodigde tools en machines
- Lijmpistool
Apps en online diensten
- Processing
- Python
- Binary MIDI-bestand naar tekst-converter
Over dit project
Hoe het begon
Jaren geleden introduceerde Yamaha een geautomatiseerde piano. Ik zag als jong kind een piano spelen achter het raam van een muziekwinkel. Er is eigenlijk geen grote reden waarom ik dit project startte – ik wilde het gewoon.
Overzicht
Een enkel Arduino Mega-board kost ongeveer $40 en er zijn er twee nodig voor 88 solenoïdes. Dat is duur. In plaats daarvan gebruik ik een goedkope Arduino Uno met 11 shift registers. Een shift register stelt je in staat om veel uitgangen (meestal LEDs) te besturen met weinig output-pins. Eigenlijk is het één Arduino met 11 shift registers die 88 solenoïdes besturen.
Omdat we shift registers gebruiken, stuurt de PC een set bits naar de Arduino in plaats van MIDI-commando's. Het MIDI-bestand wordt van tevoren omgezet in bitsets.
Hardware
De solenoïdes uit China bleken niet krachtig genoeg om pianotoetsen in te drukken. Uiteindelijk liep ik 24V door de 12V solenoïdes om voldoende kracht te krijgen.

88 solenoïdes verbruiken veel stroom. Omdat ik geen dure voeding kon kopen, gebruikte ik de autobatterij van mijn vader.

Elk shift register en MOSFET komt op een controllerbord.

Het schema is identiek aan voorbeeld 2 uit de Arduino ShiftOut-documentatie, met de LEDs vervangen door MOSFET-gates. Er zit geen pull-down-weerstand op omdat extra weerstanden de kosten verhogen en solderen op dat bord mijn vingers zou smelten. De MOSFETs openen bij 5V en sluiten onder 4V – bevestigd door urenlange tests (niet theoretisch correct, luister niet naar mij).
Tot slot: een plastic plaat om de solenoïdes op te lijmen. Met lijmpistool en plastic is dat een slecht idee omdat het warm wordt, maar het was het beste wat ik me kon permitteren.

Software
- Verkrijg een MIDI-bestand.
- Converteer naar tekstformaat via flashmusicgames.com. Negeer tijdsteken, tempo en par – tempo kan later vermenigvuldigd worden.
- Gebruik de Python-code (bijgevoegd) om 11 sets van 8-bit data met timing te genereren.
- Stuur de data via Processing COM naar de Arduino.


Let op: mijn programmeergewoontes zijn slecht en de code kan moeilijk leesbaar zijn. Processing stuurt data van rechts naar links omdat de Arduino data naar rechts pusht op het fysieke piano.
Probleemoplossing
Een professionele ingenieur zou veel problemen zien – en die zitten erin. Omdat de solenoïdes met lijmpistool waren vastgelijmd, smolt de lijm door oververhitting. Oplossing: verwijderen en vervangen door dubbelzijdig tape dat tot 150°C bestand is.
Code
Python-code voor vertaling
output_file = open("translated.txt", "w")
input_file = open("megalocania.txt")
raw_input_data = input_file.read()
work_data = raw_input_data.splitlines()
result = []
def main():
for a in work_data:
temp_time = time_finder(a)
if result == []:
result.append(str(temp_time) + ",")
if on_off_finder(a):
result[-1] += set_bit(True, note_finder(a))
elif not on_off_finder(a):
result[-1] += set_bit(True, note_finder(a))
elif time_finder_comm(result[-1]) == temp_time:
result[-1] = str(temp_time) + "," + set_bit_prev(on_off_finder(a), note_finder(a), -1)
elif time_finder_comm(result[-1]) != temp_time:
result.append(str(temp_time) + "," + set_bit_prev(on_off_finder(a), note_finder(a), -1))
for b in result:
output_file.write(b)
output_file.write("\n")
output_file.close()
def set_bit(On, note):
if(note >= 21 and note <= 28 and On):
return str(2**(note - 21)) + ",0,0,0,0,0,0,0,0,0,0"
elif(note >= 29 and note <= 36 and On):
return "0," + str(2**(note - 29)) + ",0,0,0,0,0,0,0,0,0"
# ... (verder analog voor alle notenbereiken)
else:
return "0,0,0,0,0,0,0,0,0,0,0"
# Overige helper-functies: set_bit_prev, indexTh, time_finder, time_finder_comm, note_finder, on_off_finder
main()
Processing-code om data naar Arduino te sturen
import processing.serial.*;
Serial myPort;
String[] inputLines;
void setup() {
myPort = new Serial(this, "COM3", 9600);
inputLines = loadStrings("translated.txt");
run();
}
void run() {
int lastTime = 0;
for(int i = 0; i < inputLines.length; i++) {
String temp = inputLines[i];
delay((Integer.parseInt(temp.substring(0, temp.indexOf(","))) - lastTime) * 5);
lastTime = Integer.parseInt(temp.substring(0, temp.indexOf(",")));
send(temp.substring(temp.indexOf(",") + 1));
}
}
void send(String data) {
// Bytes omkeren omdat shift register van links naar rechts werkt
String eleventh = data.substring(0, indexOforder(data, ",", 1));
String tenth = data.substring((indexOforder(data, ",", 1) + 1), (indexOforder(data, ",", 2)));
// ... (verder voor ninth tot first)
String first = data.substring(indexOforder(data, ",", 10) + 1);
myPort.write("888f");
myPort.write(first + "f");
myPort.write(second + "f");
// ... (tot eleventh)
myPort.write("999f");
}
int indexOforder(String data, String find, int order) {
int currentOrder = 0;
int lastLocation = 0;
while(currentOrder < order) {
lastLocation = data.indexOf(find, (lastLocation + 1));
currentOrder += 1;
}
return lastLocation;
}
Arduino-code
Eenvoudige code voor Arduino. Neemt invoer van Serial. 888 en 999 zijn gereserveerd voor shift register open/close commando's. (Download enkel beschikbaar)
Schema's
Excuses voor de onprofessionele tekening. Dit is het hele concept. Er is geen verschil met het Arduino ShiftOut-documentatieschema behalve de MOSFET. Ik raad aan om dat ook te bekijken.

Productieproces
- Bouw een Bluetooth-gecontroleerde Raspberry Pi Robot met Audio Feedback
- Bouw een Internet-gecontroleerde Video-streamende Robot met Arduino & Raspberry Pi
- Bouw een Wi-Fi-gecontroleerde Raspberry Pi Robot met Python – Stap-voor-stap Gids
- LED's bedienen met Alexa via Raspberry Pi – Eenvoudige stapsgewijze handleiding
- Een Arduino Iron Man bouwen: onderdelen, sensoren en stapsgewijze handleiding
- Find Me: Slimme Item Locator met Arduino en Bluetooth
- DIY Arduino Luchtbevochtiger Controller met Relais – Veilige Hoogspanningsopstelling
- Bouw een Stemgecontroleerde Robot met Arduino Nano
- MobBob: Bouw Je Eigen Arduino Robot, Naadloos Bestuurd via Android Smartphone
- Bouw een Aangepaste Arduino Joystick Stuurwiel voor Gaming
- Arduino 101: Bouw een teller met DHT11 sensor & LCD display