Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Robot piano contrôlé par Arduino :PiBot

Composants et fournitures

Arduino 101
× 1
Texas Instruments 74HC595
× 11
IRFZ44N
Mosfet N-Channel
× 88
Batterie 12V
× 2
Condensateur 100 µF
× 11
Câble métallique OpenBuilds - Au pied
beaucoup d'entre eux.
× 1
Planche à pain (générique)
Ou carte prototype générique. À peu près tout ce qui va mettre les choses ensemble.
× 11
Douille IC à 8 pattes
Facultatif si vous êtes sûr de ne brûler AUCUN de ces 595 coûteux
× 11
Résistance 10k ohm
Non utilisé pour ce projet mais mieux à avoir pour chaque mosfet
× 88
1N4007 – Diode haute tension et courant nominal élevé
Non utilisé pour ce projet mais mieux à avoir pour chaque mosfet
× 88

Outils et machines nécessaires

Pistolet à colle chaude (générique)

Applications et services en ligne

Traitement
Python
Fichier MIDI binaire en texte

À propos de ce projet

Comment ça commence :

Il y a de nombreuses années, Yamaha a introduit le piano automatisé. Jeune et innocent, j'ai vu ce piano jouer de la musique derrière la vitre d'un magasin d'instruments.

Assez de petites discussions, il n'y a vraiment pas de grande raison pour laquelle j'ai commencé ce projet à part je le voulais juste.

Présentation :

Une seule carte d'Arduino Mega coûte environ 40 $ et deux seront nécessaires pour contrôler 88 solénoïdes. C'est assez cher. Au lieu de cela, procurez-vous un Arduino Uno bon marché et 11 de registre à décalage. Le registre à décalage est une méthode pour contrôler de nombreuses sorties (généralement des LED) avec un petit nombre de broches de sortie. Essentiellement, c'est un Arduino avec 11 registres à décalage et contrôle 88 solénoïdes.

Puisque nous utilisons des registres à décalage, un PC enverra un ensemble de bits à Arduino au lieu de MIDI com. Le fichier MIDI sera traduit en ensemble de bits à l'avance.

Matériel :

Quand j'ai reçu les solénoïdes directement de Chine, j'ai découvert que ces solénoïdes ne sont pas assez puissants pour pousser les touches du piano. Bien sûr, pousser les touches du piano à partir de l'endroit le plus à l'intérieur prend plus de force, mais je pensais que c'était la meilleure méthode qui ne détruit pas un piano. Finalement, j'ai poussé des solénoïdes de 24 V à 12 V pour obtenir suffisamment de puissance.

88 Les solénoïdes consomment beaucoup d'énergie et comme je ne peux pas acheter un bloc d'alimentation coûteux, j'ai décidé d'utiliser la batterie de voiture de mon père. (Je suppose qu'il n'ira nulle part maintenant !)

Avec cela à l'écart, chacun des registres à décalage et des MOSFET ira sur une carte contrôleur.

595 à droite avec une prise au cas où je la brûlerais. (Ce que j'ai fait une fois.) Le schéma de circuit est exactement le même que l'exemple 2 d'ici. Remplacez les LED par une porte MOSFET. Comme vous pouvez le voir, il n'y a pas de résistance de tirage, car des résistances supplémentaires augmenteront le coût et les souder sur cette carte me fera fondre les doigts. D'un côté un peu plus sérieux, ces MOSFET s'ouvriront à 5V et se fermeront sous 4V environ. Cela a été confirmé par d'innombrables heures de tests. (Ce n'est pas théoriquement correct. Ne m'écoutez pas.)

Enfin, procurez-vous une plaque en plastique sur laquelle coller les solénoïdes. Utiliser de la colle chaude et une assiette en plastique est une mauvaise idée étant donné qu'il va chauffer, mais c'est le mieux que je puisse me permettre.

Ensuite, faites passer un côté des fils du solénoïde vers le côté positif de la batterie.

Logiciel :

La toute première étape consiste à obtenir un fichier midi.

La deuxième étape consiste à mettre le midi dans le formulaire texte. Cela peut être fait sur ce site Web pratique :http://flashmusicgames.com/midi/mid2txt.php.

Par souci de simplicité, ignorez la signature rythmique, le tempo et le par. Le tempo peut être multiplié par la suite. Essentiellement, vous voulez un fichier comme celui-ci :

Maintenant, utilisez-le pour créer 11 ensembles de données 8 bits avec le temps en l'exécutant via le code Python (ci-joint).

Ils sont prêts à être envoyés à Arduino via le traitement COM.

Voir la pièce jointe pour comprendre comment le traitement envoie ces données et comment Arduino les gère.

*Remarque :Mes habitudes de codage sont mauvaises et il peut être difficile de les lire. Le traitement envoie les données de droite à gauche car Arduino pousse les données vers la droite sur le piano physique.

Cette chose fonctionne :

Dépannage :

Si un ingénieur professionnel devait voir ce poste, il pensera que tout ce système aura de nombreux problèmes. Et il y a beaucoup de problèmes.

Étant donné que les solénoïdes étaient collés à chaud sur la plaque, la surchauffe des solénoïdes et la fonte de la colle chaude étaient un gros problème. La solution consistait simplement à les retirer et à les remplacer par un ruban adhésif double face pouvant supporter jusqu'à 150 °C.

Code

  • Code Python pour la traduction
  • Traitement pour envoyer des données à l'arduino
  • Code Arduino
Code Python pour la traductionPython
Prend le fichier mifi textifié et le traduit en 11 ensembles de binaires pour qu'arduino le prenne.
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() :pour un 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)) pour b dans result:output_file .write(b) output_file.write("\n") output_file.close() def set_bit(On, note):# Prend un booléen pour s'il est activé ou non, et note le numéro. #Génère le bit if(note>=21 et note <=28 et On):return str(2**(note - 21)) + ",0,0,0,0,0,0,0,0,0,0 ,0" elif(note>=29 et note <=36 et On):return "0," + str(2**(note - 29)) + ",0,0,0,0,0,0, 0,0,0" elif(note>=37 et note <=44 et On):return "0,0," + str(2**(note - 37)) + ",0,0,0,0 ,0,0,0,0" elif(note>=45 et note <=52 et On):return "0,0,0," + str(2**(note - 45)) + ",0, 0,0,0,0,0,0" elif(note>=53 et note <=60 et On):return "0,0,0,0," + str(2**(note - 53)) + ",0,0,0,0,0,0" elif(note>=61 et note <=68 et On):return "0,0,0,0,0," + str(2**( note - 61)) + ",0,0,0,0,0,0" elif(note>=69 et note <=76 et On):return "0,0,0,0,0,0," + str (2**(note - 69)) + ",0,0,0,0" elif(note>=77 et note <=84 et On):return "0,0,0,0,0,0, 0," + str(2**(note - 77)) + ",0,0,0" elif(note>=85 et note <=92 et On):return "0,0,0,0,0,0 ,0,0,0," + str(2**(note - 85)) + ",0,0" elif(note>=93 et ​​note <=100 et On):return "0,0,0, 0,0,0,0,0,0," + str(2**(note - 93)) + ",0" elif(note>=101 et note <=108 et On):return "0,0,0,0,0,0,0,0,0,0," + str(2**(note - 101)) else:return "0,0 ,0,0,0,0,0,0,0,0,0,0"def set_bit_prev(On, note, index):#Identique à set_bit mais précédent temp =result[index] temp =temp[(temp.find (",") + 1):] if(note>=21 et 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(note>=29 et note <=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 et 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[dans 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 et 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**(note - 45))) + temp[indexTh(temp, ",", 4):] if(not On):return temp[0:indexTh(temp, ",", 3) + 1] + str(int(local_temp ) - (2**(note - 45))) + temp[indexTh(temp, ",", 4):] elif(note>=53 et 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**(note - 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 et 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 et 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 et 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 et 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**(note - 85))) + temp[indexTh(temp, ",", 9):] elif(note>=93 et ​​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**(note - 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 et note <=108):local_temp =temp [(indexTh(temp, ",", 10) + 1):] if(On):return temp[0:indexTh(temp, ",", 10) + 1] + str(int(local_temp) + (2 **(note - 101))) if(not On):return temp[0:indexTh(temp, ",", 10) + 1] + str(int(local_temp) - (2**(note - 101) )) def indexTh(in_string, find_this, th):#Takes String, string to find, and order to find string to find at cet ordre # renvoie l'ordre de l'index =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):#Prend une chaîne et trouve l'heure, la renvoie comme un int time_end =in_string.index(" ") return int(in_string[0:time_end])def time_finder_comm(in_string):#Prend une chaîne et trouve l'heure, la renvoie sous forme de virgule int time_end =in_string.index(",") return int(in_string[0:time_end]) def note_finder(in_string):#Prend une chaîne, recherche n=, renvoie n valeur sous la forme d'un int 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 une chaîne, recherche On ou Off, renvoie true si 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()
Traitement pour envoyer des données à l'arduinoTraitement
Lit le fichier texte traduit et l'envoie à l'arduino.
Doit modifier le multiplicateur de tempo si le tempo est différent de 50000.
Inverse les octets car il se déplace de gauche à droite. (Le fichier texte suppose de droite à gauche)
import processing.serial.*;Serial myPort;String[] inputLines;void setup(){ myPort =new Serial(this, "COM3", 9600); inputLines =loadStrings("translated.txt"); run();}void run(){ //lit l'heure et envoie la ligne de données bt en utilisant la méthode de données int lastTime =0; for(int i =0; i  
Code ArduinoArduino
Code simple pour arduino. Prend les entrées de Serial. 888 et 999 sont réservés à la commande d'ouverture et de fermeture du registre à décalage.
Aucun aperçu (téléchargement uniquement).

Schémas

Je suis désolé pour le dessin non professionnel. C'est tout le concept. Il n'y a pas de différence entre le diagramme du document Arduino -ShiftOut, à l'exception du mosfet. Je recommande de regarder ça aussi.

Processus de fabrication

  1. Robot Raspberry Pi contrôlé par Bluetooth
  2. Créez votre robot de streaming vidéo contrôlé par Internet avec Arduino et Raspberry Pi
  3. Robot contrôlé par Wi-Fi utilisant Raspberry Pi
  4. LED contrôlées par Alexa via Raspberry Pi
  5. Iron Man
  6. Trouvez-moi
  7. Contrôle de l'humidificateur Arduino
  8. Robot à commande vocale
  9. MobBob :Robot Arduino DIY contrôlé par smartphone Android