Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Arduino-gesteuerter Klavierroboter:PiBot

Komponenten und Verbrauchsmaterialien

Arduino 101
× 1
Texas Instruments 74HC595
× 11
IRFZ44N
N-Channel-Mosfet
× 88
12-V-Batterie
× 2
Kondensator 100 µF
× 11
OpenBuilds-Drahtkabel - am Fuß
viele davon.
× 1
Breadboard (generisch)
Oder generisches Prototypenboard. So ziemlich alles, was die Dinge zusammenfügt.
× 11
IC-Sockel mit 8 Beinen
Optional, wenn Sie sicher sind, dass Sie keine dieser teuren 595 verbrennen
× 11
Widerstand 10k Ohm
Nicht für dieses Projekt verwendet, aber besser für jeden Mosfet
× 88
1N4007 – Hochspannungs-, Hochstrom-Nenndiode
Nicht für dieses Projekt verwendet, aber besser für jeden Mosfet
× 88

Notwendige Werkzeuge und Maschinen

Heißklebepistole (generisch)

Apps und Onlinedienste

Verarbeitung
Python
Binäre MIDI-Datei in Text

Über dieses Projekt

Wie es beginnt:

Vor vielen Jahren führte Yamaha das automatisierte Klavier ein. Jung und unschuldig sah ich das Klavier hinter dem Glasfenster eines Instrumentenladens Musik spielen.

Genug der Smalltalks, es gibt wirklich keinen triftigen Grund, warum ich dieses Projekt gestartet habe, außer dass ich es einfach wollte.

Übersicht:

Eine einzelne Platine von Arduino Mega kostet etwa 40 US-Dollar und zwei werden benötigt, um 88 Magnetspulen zu steuern. Das ist ziemlich teuer. Holen Sie sich stattdessen ein billiges Arduino Uno und 11 Schieberegister. Schieberegister ist eine Methode, um viele Ausgänge (normalerweise LEDs) mit einer kleinen Anzahl von Ausgangspins zu steuern. Im Wesentlichen ist es ein Arduino mit 11 Schieberegistern und steuert 88 Magnetspulen.

Da wir Schieberegister verwenden, sendet ein PC eine Reihe von Bits an Arduino anstelle von MIDI com. Die MIDI-Datei wird vorher in Bits übersetzt.

Hardware:

Als ich die Magnetspulen direkt aus China bekam, stellte ich fest, dass diese Magnetspulen nicht stark genug sind, um Klaviertasten zu drücken. Natürlich erfordert es mehr Kraft, Klaviertasten von der innersten Stelle aus zu drücken, aber ich dachte, es wäre die beste Methode, um ein Klavier nicht zu zerstören. Schließlich habe ich 24V durch 12V-Magnetspulen geschoben, um genug Strom zu bekommen.

88 Magnetspulen verbrauchen viel Strom und da ich kein teures Netzteil kaufen kann, habe ich mich für die Autobatterie meines Vaters entschieden. (Ich schätze, er wird jetzt nirgendwo hingehen!)

Wenn das aus dem Weg ist, wird jedes der Schieberegister und MOSFETs auf einer Controllerplatine untergebracht.

595 rechts mit einer Steckdose, falls ich es verbrenne. (Was ich einmal getan habe.) Der Schaltplan ist genau der gleiche wie in Beispiel 2 von hier. Ersetzen Sie LEDs durch MOSFET-Gate. Wie Sie sehen, gibt es keinen Pull-Down-Widerstand, da zusätzliche Widerstände die Kosten erhöhen und das Löten auf dieser Platine meine Finger zum Schmelzen bringen wird. Auf einer etwas ernsteren Seite öffnen diese MOSFETs bei 5 V und schließen unter 4 V oder so. Bestätigt es durch unzählige Stunden des Testens. (Theoretisch nicht richtig. Hör nicht auf mich.)

Als letztes besorgen Sie sich ein Stück Plastikplatte, um die Magnetspulen darauf zu kleben. Heißkleber und Plastikplatten zu verwenden ist eine schlechte Idee, wenn man bedenkt, dass es heiß wird, aber es ist das Beste, was ich mir leisten kann.

Führen Sie dann eine Seite der Magnetspulenkabel zur positiven Seite der Batterie.

Software:

Der allererste Schritt besteht darin, eine Midi-Datei zu erhalten.

Der zweite Schritt besteht darin, das Midi in die Textform zu bringen. Dies kann auf dieser praktischen Website erfolgen:http://flashmusicgames.com/midi/mid2txt.php.

Der Einfachheit halber ignorieren Sie Taktart, Tempo und Par. Tempo kann mit der Zeit später multipliziert werden. Im Wesentlichen möchten Sie eine Datei wie diese:

Verwenden Sie dies nun, um mit der Zeit 11 Sätze von 8-Bit-Daten zu erstellen, indem Sie sie durch den Python-Code (beigefügt) ausführen.

Sie können durch die Verarbeitung von COM an Arduino gesendet werden.

Sehen Sie sich den Anhang an, um herauszufinden, wie die Verarbeitung diese Daten sendet und wie Arduino sie verarbeitet.

*Hinweis:Meine Programmiergewohnheiten sind schlecht und es kann schwierig sein, diese zu lesen. Die Verarbeitung sendet Daten von rechts nach links, da Arduino Daten auf dem physischen Klavier nach rechts schiebt.

Dieses Ding funktioniert:

Fehlerbehebung:

Wenn ein professioneller Ingenieur diesen Beitrag sehen würde, wird er denken, dass dieses gesamte System viele Probleme haben wird. Und es gibt viele Probleme.

Da die Magnetspulen heiß auf die Platte geklebt wurden, war das Überhitzen der Magnetspulen und das Schmelzen des Heißklebers ein großes Problem. Die Lösung bestand darin, sie einfach zu entfernen und durch ein doppelseitiges Klebeband zu ersetzen, das bis zu 150°C standhält.

Code

  • Python-Code für die Übersetzung
  • Verarbeitung zum Senden von Daten an das Arduino
  • Arduino-Code
Python-Code für die ÜbersetzungPython
Nimmt eine textifizierte Mifi-Datei und übersetzt sie in 11 Binärsätze, damit Arduino sie aufnehmen kann.
output_file =open("translated.txt", "w")input_file =open("megalocania.txt")raw_input_data =input_file.read ()work_data =raw_input_data.splitlines()result =[]#output_file =open("result.txt", "w")def main():für 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)) für b in result:output_file .write(b) output_file.write("\n") output_file.close() def set_bit(On, note):# Nimmt boolean ob es an ist oder nicht, und die Nummer der Notiz. #Erzeugt Bit if(note>=21 and note <=28 and On):return str(2**(note - 21)) + ",0,0,0,0,0,0,0,0,0,0 ,0" elif(note>=29 und note <=36 and On):return "0", + str(2**(note - 29)) + ",0,0,0,0,0,0, 0,0,0" elif(Note>=37 und Note <=44 und On):return "0,0", + str(2**(Note - 37)) + ",0,0,0,0 ,0,0,0,0" elif(note>=45 und note <=52 and On):return "0,0,0," + str(2**(note - 45)) + ",0, 0,0,0,0,0,0" elif(note>=53 und note <=60 and On):return "0,0,0,0," + str(2**(note - 53)) + ",0,0,0,0,0,0" elif(Note>=61 und Note <=68 und On):return "0,0,0,0,0,0," + str(2**( note - 61)) + ",0,0,0,0,0,0" elif(note>=69 and note <=76 and On):return "0,0,0,0,0,0" + str (2**(Anmerkung - 69)) + ",0,0,0,0" elif(Anmerkung>=77 und Anmerkung <=84 und On):Rückgabe "0,0,0,0,0,0, 0," + str(2**(Note - 77)) + ",0,0,0" elif(Note>=85 und Note <=92 und On):Rückgabe "0,0,0,0,0 ,0,0,0," + str(2**(note - 85)) + ",0,0" elif(note>=93 and note <=100 and On):return "0,0,0, 0,0,0,0,0,0," + str(2**(Anmerkung - 93)) + ",0" elif(Anmerkung>=101 and note <=108 und On):Rückgabe von "0,0,0,0,0,0,0,0,0,0," + str(2**(note - 101)) sonst:Rückgabe von "0,0 ,0,0,0,0,0,0,0,0,0,0"def set_bit_prev(On, note, index):#Gleiche wie set_bit, aber vorher bekannt temp =result[index] temp =temp[(temp.find (",") + 1):] if(note>=21 and note <=28):local_temp =temp[0:temp.find(",")] if(On):return str(int(local_temp) + (2**(note - 21))) + temp[temp.find(","):] if(not On):return str(int(local_temp) - (2**(note - 21))) + temp[temp.find(","):] elif(Notiz>=29 und Notiz <=36):local_temp =temp[(temp.find(",") + 1):indexTh(temp, "," , 2)] if(On):return temp[0:temp.find(",") + 1] + str(int(local_temp) + (2**(note - 29))) + temp[indexTh(temp , ",", 2):] if(not On):return temp[0:temp.find(",") + 1] + str(int(local_temp) - (2**(note - 29))) + temp[indexTh(temp, ",", 2):] elif(note>=37 und note <=44):local_temp =temp[(indexTh(temp, ",", 2) + 1):indexTh(temp , ",", 3)] if(On):return temp[0:indexTh(temp, ",", 2) + 1] + str(int(local_temp) + (2**(note - 37))) + temp[in dexTh(temp, ",", 3):] if(not On):return temp[0:indexTh(temp, ",", 2) + 1] + str(int(local_temp) - (2**(note - 37))) + temp[indexTh(temp, ",", 3):] elif(note>=45 und note <=52):local_temp =temp[(indexTh(temp, ",", 3) + 1 ):indexTh(temp, ",", 4)] if(On):return temp[0:indexTh(temp, ",", 3) + 1] + str(int(local_temp) + (2**(Hinweis - 45))) + temp[indexTh(temp, ",", 4):] if(not On):return temp[0:indexTh(temp, ",", 3) + 1] + str(int(local_temp ) - (2**(Anmerkung - 45))) + temp[indexTh(temp, ",", 4):] elif(note>=53 und note <=60):local_temp =temp[(indexTh(temp, ",", 4) + 1):indexTh(temp, ",", 5)] if(On):return temp[0:indexTh(temp, ",", 4) + 1] + str(int(local_temp ) + (2**(Anmerkung - 53))) + temp[indexTh(temp, ",", 5):] if(not On):return temp[0:indexTh(temp, ",", 4) + 1] + str(int(local_temp) - (2**(note - 53))) + temp[indexTh(temp, ",", 5):] elif(note>=61 and note <=68):local_temp =temp[(indexTh(temp, ",", 5) + 1):indexTh(temp, ",", 6)] if(On):return temp[0:indexTh(temp, ",", 5) + 1 ] + str(int(local_temp) + (2**(note - 61))) + temp[indexTh(temp, ",", 6):] if(not On):return temp[0:indexTh(temp, ",", 5) + 1] + str(int(local_temp) - (2**(note - 61))) + temp[indexTh(temp, ",", 6):] elif(note>=69 and note <=76):local_temp =temp[(indexTh(temp, ",", 6) + 1):indexTh(temp, ",", 7)] if(On):return temp[0:indexTh(temp, ",", 6) + 1] + str(int(local_temp) + (2**(note - 69))) + temp[indexTh(temp, ",", 7):] if(not On):return temp[0:indexTh(temp, ",", 6) + 1] + str(int(local_temp) - (2**(note - 69))) + temp[indexTh(temp, ",", 7):] elif(note>=77 und note <=84):local_temp =temp[(indexTh(temp, ",", 7) + 1):indexTh(temp, ",", 8)] if(On):return temp[0:indexTh(temp, ",", 7) + 1] + str(int(local_temp) + (2**(note - 77))) + temp[indexTh(temp, ",", 8):] if(not On):return temp[0:indexTh(temp, ",", 7) + 1] + str(int(local_temp) - (2**(note - 77))) + temp[indexTh(temp , ",", 8):] elif(note>=85 and note <=92):#error here local_temp =temp[(indexTh(temp, ",", 8) + 1):indexT h(temp, ",", 9)] if(On):return temp[0:indexTh(temp, ",", 8) + 1] + str(int(local_temp) + (2**(note - 85 ))) + temp[indexTh(temp, ",", 9):] if(not On):return temp[0:indexTh(temp, ",", 8) + 1] + str(int(local_temp) - (2**(Anmerkung - 85))) + temp[indexTh(temp, ",", 9):] elif(note>=93 und note <=100):local_temp =temp[(indexTh(temp, ", ", 9) + 1):indexTh(temp, ",", 10)] if(On):return temp[0:indexTh(temp, ",", 9) + 1] + str(int(local_temp) + (2**(Anmerkung - 93))) + temp[indexTh(temp, ",", 10):] if(not On):return temp[0:indexTh(temp, ",", 9) + 1] + str(int(local_temp) - (2**(note - 93))) + temp[indexTh(temp, ",", 10):] elif(note>=101 und note <=108):local_temp =temp [(indexTh(temp, ",", 10) + 1):] if(On):return temp[0:indexTh(temp, ",", 10) + 1] + str(int(local_temp) + (2 **(Anmerkung - 101))) if(not On):return temp[0:indexTh(temp, ",", 10) + 1] + str(int(local_temp) - (2**(Anmerkung - 101) )) def indexTh(in_string, find_this, th):#Takes String, string to such, and order to find string to find at that order #returns index order =1 last_index =0 while(True):temp =in_string.find(find_this, last_index) if(temp ==-1):return -1 if(order ==th):return temp order + =1 last_index =temp + 1def time_finder(in_string):#Nimmt einen String und findet die Zeit, gibt sie als int zurück time_end =in_string.index(" ") return int(in_string[0:time_end])def time_finder_comm(in_string):#Nimmt einen String und findet die Zeit, gibt ihn als Int-Komma zurück time_end =in_string.index(",") return int(in_string[0:time_end]) def note_finder(in_string):#Nehmt einen String, sucht nach n=, gibt n Wert als int zurück num_start =in_string.index("n=") + 2 num_end =in_string.index("v=") - 1 return int(in_string[num_start:num_end])def on_off_finder(in_string):#takes ein String, sucht nach On oder Off, gibt true zurück, wenn On start =in_string.index(" ") + 1 end =in_string.index("ch=") - 1 if in_string[start:end] =="On":return True elif in_string[start:end] =="Off":return Falsemain()
Verarbeitung zum Senden von Daten an das ArduinoVerarbeitung
Liest die übersetzte Textdatei und sendet sie an das Arduino.
Muss den Tempomultiplikator modifizieren, wenn das Tempo nicht 50000 beträgt.
Kehrt Bytes um, da sie von links nach rechts verschoben werden. (Textdatei geht von rechts nach links)
import processing.serial.*;Serial myPort;String[] inputLines;void setup(){ myPort =new Serial(this, "COM3", 9600); inputLines =loadStrings("translated.txt"); run();}void run(){//liest die Zeit und sendet die Daten-BT-Zeile mit der Datenmethode int lastTime =0; for(int i =0; i  
Arduino-CodeArduino
Einfacher Code für Arduino. Nimmt Eingaben von Serial. 888 und 999 sind für die Befehle zum Öffnen und Schließen von Schieberegistern reserviert.
Keine Vorschau (nur Download).

Schaltpläne

Es tut mir leid für das unprofessionelle Zeichnen. Das ist das ganze Konzept. Es gibt keinen Unterschied zwischen dem Diagramm des Arduino -ShiftOut-Dokuments, mit Ausnahme des Mosfet. Ich empfehle auch, sich das anzuschauen.

Herstellungsprozess

  1. Raspberry Pi Roboter über Bluetooth gesteuert
  2. Bauen Sie Ihren internetgesteuerten Videostreaming-Roboter mit Arduino und Raspberry Pi
  3. WLAN-gesteuerter Roboter mit Raspberry Pi
  4. Alexa-gesteuerte LEDs über Raspberry Pi
  5. Iron Man
  6. Finde mich
  7. Arduino-Befeuchtersteuerung
  8. Sprachgesteuerter Roboter
  9. MobBob:DIY-Arduino-Roboter, der von einem Android-Smartphone gesteuert wird
  10. Arduino-Joystick