Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Robot de piano controlado por Arduino:PiBot

Componentes y suministros

Arduino 101
× 1
Texas Instruments 74HC595
× 11
IRFZ44N
Mosfet de canal N
× 88
Batería de 12V
× 2
Condensador 100 µF
× 11
Cable de alambre OpenBuilds - Por el pie
muchos de ellos.
× 1
Breadboard (genérico)
O una placa prototipo genérica. Casi cualquier cosa que pueda unir las cosas.
× 11
Enchufe IC de 8 patas
Opcional si está seguro de que no quemará NINGUNO de estos costosos 595
× 11
Resistencia de 10k ohmios
No se usa para este proyecto, pero es mejor tenerlo para cada mosfet
× 88
1N4007 - Diodo nominal de alta tensión y alta corriente
No se usa para este proyecto, pero es mejor tenerlo para cada mosfet
× 88

Herramientas y máquinas necesarias

Pistola de pegamento caliente (genérica)

Aplicaciones y servicios en línea

Procesamiento
Python
Archivo MIDI binario a texto

Acerca de este proyecto

Cómo empieza:

Hace muchos años, Yamaha introdujo el piano automatizado. Joven e inocente, vi ese piano tocando música detrás de la ventana de vidrio de una tienda de instrumentos.

Basta de pequeñas charlas, realmente no hay una gran razón por la que comencé este proyecto además de que solo quería hacerlo.

Descripción general:

Una sola placa de Arduino Mega cuesta alrededor de $ 40 y se necesitarán dos para controlar 88 solenoides. Eso es bastante caro. En su lugar, obtenga un Arduino Uno barato y 11 de shift-register. Shift Register es un método para controlar muchas salidas (generalmente LED) con una pequeña cantidad de pines de salida. Esencialmente, es un Arduino con 11 registros de cambio y controla 88 solenoides.

Como estamos usando registros Shift, una PC enviará un conjunto de bits a Arduino en lugar de MIDI com. El archivo MIDI se traducirá a un conjunto de bits de antemano.

Hardware:

Cuando recibí los solenoides directamente de China, descubrí que estos solenoides no son lo suficientemente fuertes para presionar las teclas del piano. Por supuesto, presionar las teclas del piano desde el lugar más interno requiere más fuerza, pero pensé que era el mejor método que no arruina un piano. Finalmente, presioné solenoides de 24 V a 12 V para obtener suficiente energía.

88 Los solenoides consumen mucha energía y como no puedo comprar una fuente de alimentación costosa, decidí ir con la batería del auto de mi papá. (¡Supongo que ahora no irá a ninguna parte!)

Con eso fuera del camino, cada uno de los registros de desplazamiento y MOSFET irá a una placa controladora.

595 a la derecha con un enchufe en caso de que lo queme. (Lo que hice una vez). El diagrama de circuito es exactamente el mismo que el del ejemplo 2 de aquí. Reemplace los LED con la puerta MOSFET. Como puede ver, no hay una resistencia desplegable porque las resistencias adicionales aumentarán el costo y soldarlas en esa placa derretirá mis dedos. En un lado un poco más serio, estos MOSFET se abrirán a 5 V y se cerrarán por debajo de 4 V más o menos. Lo confirmó a través de innumerables horas de pruebas. (No es teóricamente correcto. No me escuches.)

Por último, obtenga un trozo de placa de plástico para pegar solenoides. Usar pegamento termofusible y placa de plástico es una mala idea considerando que se calentará, pero es lo mejor que puedo pagar.

Y luego pase un lado de los cables del solenoide al lado positivo de la batería.

Software:

El primer paso es obtener un archivo midi.

El segundo paso es convertir el midi en texto. Esto se puede hacer en este útil sitio web:http://flashmusicgames.com/midi/mid2txt.php.

En aras de la simplicidad, ignore el tipo de compás, el tempo y el par. El tempo se puede multiplicar por el tiempo más tarde. Básicamente, desea un archivo como este:

Ahora, use esto para crear 11 conjuntos de datos de 8 bits con el tiempo ejecutándolo a través del código Python (adjunto).

Están listos para ser enviados a Arduino a través del procesamiento COM.

Vea el archivo adjunto para descubrir cómo el procesamiento envía estos datos y cómo los maneja Arduino.

* Nota:Mis hábitos de codificación son malos y puede ser difícil leerlos. El procesamiento envía datos de derecha a izquierda porque Arduino empuja los datos hacia la derecha en el piano físico.

Esta cosa funciona:

Solución de problemas:

Si un ingeniero profesional viera esta publicación, pensará que todo este sistema tendrá muchos problemas. Y hay muchos problemas.

Dado que los solenoides estaban pegados en caliente a la placa, el sobrecalentamiento de los solenoides y la fusión del pegamento caliente fue un gran problema. La solución fue simplemente quitarlos y reemplazarlo con una cinta de doble cara que puede soportar hasta 150 ° C.

Código

  • Código Python para traducción
  • Procesamiento para enviar datos al arduino
  • código Arduino
Código Python para traducción Python
Toma un archivo mifi textificado y lo traduce a 11 conjuntos de binarios para que arduino lo tome.
 output_file =open ("translate.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 ():para un in work_data:temp_time =time_finder (a) if result ==[] :result.append (str (temp_time) + ",") if on_off_finder (a):resultado [-1] + =set_bit (True, note_finder (a)) elif no on_off_finder (a):resultado [-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)) para b en el resultado:output_file .write (b) output_file.write ("\ n") output_file.close () def set_bit (On, note):#Toma booleano para si está activado o no, y número de nota. #Genera bit if (note> =21 y note <=28 y On):return str (2 ** (note - 21)) + ", 0,0,0,0,0,0,0,0,0 , 0 "elif (nota> =29 y nota <=36 y en adelante):return" 0, "+ str (2 ** (nota - 29)) +", 0,0,0,0,0,0, 0,0,0 "elif (nota> =37 y nota <=44 y On):return" 0,0, "+ str (2 ** (nota - 37)) +", 0,0,0,0 , 0,0,0,0 "elif (nota> =45 y nota <=52 y On):return" 0,0,0, "+ str (2 ** (nota - 45)) +", 0, 0,0,0,0,0,0 "elif (nota> =53 y nota <=60 y On):return" 0,0,0,0, "+ str (2 ** (nota - 53)) + ", 0,0,0,0,0,0" elif (nota> =61 y nota <=68 y On):return "0,0,0,0,0," + str (2 ** ( note - 61)) + ", 0,0,0,0,0" elif (note> =69 y note <=76 y On):return "0,0,0,0,0,0," + str (2 ** (nota - 69)) + ", 0,0,0,0" elif (nota> =77 y nota <=84 y On):return "0,0,0,0,0,0, 0, "+ str (2 ** (nota - 77)) +", 0,0,0 "elif (nota> =85 y nota <=92 y On):return" 0,0,0,0,0 , 0,0,0, "+ str (2 ** (nota - 85)) +", 0,0 "elif (nota> =93 y nota <=100 y On):return" 0,0,0, 0,0,0,0,0,0, "+ str (2 ** (nota - 93)) +", 0 "elif (nota> =101 y note <=108 y On):return "0,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 "def set_bit_prev (On, note, index):# Igual que set_bit pero con conocimiento previo temp =result [index] temp =temp [(temp.find (",") + 1):] if (nota> =21 y nota <=28):local_temp =temp [0:temp.find (",")] if (On):return str (int (local_temp) + (2 ** (nota - 21))) + temp [temp.find (","):] if (no On):return str (int (local_temp) - (2 ** (nota - 21))) + temp [temp.find (","):] elif (nota> =29 y nota <=36):local_temp =temp [(temp.find (",") + 1):indexTh (temp, "," , 2)] if (On):return temp [0:temp.find (",") + 1] + str (int (local_temp) + (2 ** (nota - 29))) + temp [indexTh (temp , ",", 2):] if (no activado):return temp [0:temp.find (",") + 1] + str (int (local_temp) - (2 ** (nota - 29))) + temp [indexTh (temp, ",", 2):] elif (note> =37 y 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 ** (nota - 37))) + temp [en dexTh (temp, ",", 3):] if (no activado):return temp [0:indexTh (temp, ",", 2) + 1] + str (int (local_temp) - (2 ** (nota - 37))) + temp [indexTh (temp, ",", 3):] elif (nota> =45 y nota <=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 ** (nota - 45))) + temp [indexTh (temp, ",", 4):] if (no activado):return temp [0:indexTh (temp, ",", 3) + 1] + str (int (local_temp ) - (2 ** (nota - 45))) + temp [indexTh (temp, ",", 4):] elif (nota> =53 y nota <=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 ** (nota - 53))) + temp [indexTh (temp, ",", 5):] if (no On):return temp [0:indexTh (temp, ",", 4) + 1] + str (int (local_temp) - (2 ** (nota - 53))) + temp [indexTh (temp, ",", 5):] elif (nota> =61 y nota <=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 ** (nota - 61))) + temp [indexTh (temp, ",", 6):] if (no On):return temp [0:indexTh (temp, ",", 5) + 1] + str (int (local_temp) - (2 ** (nota - 61))) + temp [indexTh (temp, ",", 6):] elif (nota> =69 y 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 ** (nota - 69))) + temp [indexTh (temp, ",", 7):] if (no On):return temp [0:indexTh (temp, ",", 6) + 1] + str (int (local_temp) - (2 ** (nota - 69))) + temp [indexTh (temp, ",", 7):] elif (nota> =77 y nota <=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 ** (nota - 77))) + temp [indexTh (temp, ",", 8):] if (no activado):return temp [0:indexTh (temp, ",", 7) + 1] + str (int (local_temp) - (2 ** (note - 77))) + temp [indexTh (temp , ",", 8):] elif (nota> =85 y nota <=92):# error aquí 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 ** (nota - 85) ))) + temp [indexTh (temp, ",", 9):] if (no On):return temp [0:indexTh (temp, ",", 8) + 1] + str (int (local_temp) - (2 ** (nota - 85))) + temp [indexTh (temp, ",", 9):] elif (nota> =93 y nota <=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 ** (nota - 93))) + temp [indexTh (temp, ",", 10):] if (no On):return temp [0:indexTh (temp, ",", 9) + 1] + str (int (local_temp) - (2 ** (nota - 93))) + temp [indexTh (temp, ",", 10):] elif (note> =101 y note <=108):local_temp =temp [(indexTh (temp, ",", 10) + 1):] if (On):return temp [0:indexTh (temp, ",", 10) + 1] + str (int (local_temp) + (2 ** (nota - 101))) if (no activado):return temp [0:indexTh (temp, ",", 10) + 1] + str (int (local_temp) - (2 ** (nota - 101) )) def indexTh (in_string, find_this, th):#Toma cadena, cadena para buscar y orden para encontrar cadena para encontrar en ese orden #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):#Toma una cadena y encuentra la hora, la devuelve como int time_end =in_string.index ("") return int (in_string [0:time_end]) def time_finder_comm (in_string):#Toma una cadena y encuentra la hora, la devuelve como una coma int time_end =in_string.index (",") return int (in_string [0:time_end]) def note_finder (in_string):#Toma una cadena, busca n =, devuelve un valor n como 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 una cadena, busca On o Off, devuelve verdadero si On start =in_string.index ("") + 1 end =in_string.index ("ch =") - 1 si in_string [start:end] =="On":return True elif in_string [start:end] =="Off":return Falsemain () 
Procesando para enviar datos al arduino Procesando
Lee el archivo de texto traducido y lo envía al arduino.
Debe modificar el multiplicador de tempo si el tempo es diferente de 50000.
Invierte bytes porque se desplaza de izquierda a derecha. (El archivo de texto asume de derecha a izquierda)
 import processing.serial. *; Serial myPort; String [] inputLines; void setup () {myPort =new Serial (this, "COM3", 9600); inputLines =loadStrings ("traducido.txt"); run ();} void run () {// lee la hora y envía datos bt line usando el método de datos int lastTime =0; for (int i =0; i  
Código Arduino Arduino
Código simple para arduino. Toma entradas de Serial. 888 y 999 están reservados para el comando de apertura y cierre del registro de desplazamiento.
 Sin vista previa (solo descarga). 

Esquemas

Lo siento por el dibujo no profesional. Este es el concepto completo. No hay diferencia entre el diagrama del documento Arduino -ShiftOut excepto por el mosfet. Recomiendo mirar eso también.

Proceso de manufactura

  1. Robot Raspberry Pi controlado por Bluetooth
  2. Cree su robot de transmisión de video controlado por Internet con Arduino y Raspberry Pi
  3. Robot controlado por Wifi usando Raspberry Pi
  4. LED controlados por Alexa a través de Raspberry Pi
  5. Iron Man
  6. Encuéntrame
  7. Control del humidificador Arduino
  8. Robot controlado por voz
  9. MobBob:Robot Arduino DIY controlado por un teléfono inteligente Android
  10. Joystick de Arduino
  11. Podómetro (Arduino 101)