Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Robô de piano controlado por Arduino:PiBot

Componentes e suprimentos

Arduino 101
× 1
Texas Instruments 74HC595
× 11
IRFZ44N
Mosfet de N-Channel
× 88
Bateria de 12 V
× 2
Capacitor 100 µF
× 11
OpenBuilds Wire Cable - By the Foot
muitos deles.
× 1
Breadboard (genérico)
Ou placa de protótipo genérico. Praticamente qualquer coisa que junte as coisas.
× 11
Soquete IC de 8 pernas
Opcional se você tiver certeza de que não queimará QUALQUER destes caros 595
× 11
Resistor 10k ohm
Não usado para este projeto, mas é melhor ter para cada mosfet
× 88
1N4007 - Alta tensão, diodo nominal de alta corrente
Não usado para este projeto, mas é melhor ter para cada mosfet
× 88

Ferramentas e máquinas necessárias

Pistola de cola quente (genérica)

Aplicativos e serviços online

Processamento
Python
Arquivo MIDI binário para texto

Sobre este projeto







Como começou:


Muitos anos atrás, a Yamaha introduziu o piano automatizado. Jovem e inocente eu vi aquele piano tocando música atrás da vitrine de uma loja de instrumentos.

Chega de pequenas conversas, realmente não há um grande motivo pelo qual comecei este projeto, além do que eu só queria.





Visão geral:


Uma única placa do Arduino Mega custa cerca de US $ 40 e duas serão necessárias para controlar 88 solenóides. Isso é muito caro. Em vez disso, compre um Arduino Uno barato e 11 de shift-register. O Shift Register é um método para controlar muitas saídas (geralmente LEDs) com um pequeno número de pinos de saída. Basicamente, é um Arduino com 11 registradores de deslocamento e 88 solenóides de controle.

Como estamos usando registradores Shift, um PC enviará um conjunto de bits para o Arduino em vez do MIDI com. O arquivo MIDI será traduzido em conjunto de bits de antemão.





Hardware:


Quando comprei os solenóides direto da China, descobri que esses solenóides não são fortes o suficiente para pressionar as teclas do piano. É claro que pressionar as teclas do piano a partir do ponto interno exige mais força, mas eu pensei que era o melhor método que não destrói um piano. Eventualmente eu empurrei 24 V através de solenóides de 12 V para obter energia suficiente.

88 Solenóides consomem muita energia e como não posso comprar uma fonte de alimentação cara, decidi ir com a bateria de carro do meu pai. (Acho que ele não vai a lugar nenhum agora!)

Com isso resolvido, cada um dos registradores de deslocamento e MOSFETs irá para uma placa controladora.

595 à direita com um soquete caso eu queime. (O que eu fiz uma vez.) O diagrama de circuito é exatamente igual ao exemplo 2 daqui. Substitua os LEDs pela porta MOSFET. Como você pode ver, não há resistor pull down porque resistores extras aumentam o custo e soldá-los naquela placa derrete meus dedos. Em um lado um pouco mais sério, esses MOSFETs abrirão em 5 V e fecharão em 4 V ou mais. Confirmei isso através de incontáveis ​​horas de testes. (Não é teoricamente correto. Não me dê ouvidos.)

Por último, pegue um pedaço de placa de plástico para colar os solenóides. Usar cola quente e placa de plástico é uma má ideia, considerando que vai ficar quente, mas é o melhor que posso pagar.

E, em seguida, passe um lado dos fios do solenóide até o lado positivo da bateria.





Software:


O primeiro passo é obter um arquivo midi.

A segunda etapa é colocar o midi na forma de texto. Isso pode ser feito neste site útil:http://flashmusicgames.com/midi/mid2txt.php.

Para simplificar, ignore a fórmula de compasso, o andamento e o par. O tempo pode ser multiplicado pelo tempo mais tarde. Basicamente, você deseja um arquivo como este:

Agora, use isso para criar 11 conjuntos de dados de 8 bits com o tempo, executando-os por meio do código Python (em anexo).

Eles estão prontos para serem enviados ao Arduino por meio do processamento COM.

Veja o anexo para descobrir como o processamento envia esses dados e como o Arduino os trata.

* Nota:Meus hábitos de codificação são ruins e pode ser difícil lê-los. O processamento envia dados da direita para a esquerda porque o Arduino empurra os dados para a direita no piano físico.





Esta coisa funcionando:







Solução de problemas:


Se um engenheiro profissional visse este posto, ele pensaria que todo o sistema terá muitos problemas. E existem muitos problemas.

Como os solenóides estavam colados a quente na placa, o superaquecimento dos solenóides e o derretimento da cola quente eram um grande problema. A solução foi simplesmente removê-los e substituí-los por uma fita dupla-face que pode suportar até 150C.

Código

  • Código Python para tradução
  • Processamento para enviar dados ao arduino
  • código Arduino
Código Python para tradução Python
Pega um arquivo mifi textificado e traduz em 11 conjuntos de binários para que o Arduino o pegue.
 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 ():para a em 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 não 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)) para b no resultado:output_file .write (b) output_file.write ("\ n") output_file.close () def set_bit (On, note):# Toma booleano para se está ligado ou não, e o número da nota. # Gera bit if (note> =21 e note <=28 e 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 "elif (nota> =37 e nota <=44 e Ligado):return" 0,0, "+ str (2 ** (nota - 37)) +", 0,0,0,0 , 0,0,0,0 "elif (nota> =45 e nota <=52 e On):return" 0,0,0, "+ str (2 ** (nota - 45)) +", 0, 0,0,0,0,0,0 "elif (nota> =53 e nota <=60 e On):return" 0,0,0,0, "+ str (2 ** (nota - 53)) + ", 0,0,0,0,0,0" elif (nota> =61 e nota <=68 e Ligado):return "0,0,0,0,0," + str (2 ** ( note - 61)) + ", 0,0,0,0,0" elif (note> =69 and note <=76 e On):return "0,0,0,0,0,0," + str (2 ** (nota - 69)) + ", 0,0,0,0" elif (nota> =77 e nota <=84 e On):return "0,0,0,0,0,0, 0, "+ str (2 ** (nota - 77)) +", 0,0,0 "elif (nota> =85 e nota <=92 e On):return" 0,0,0,0,0 , 0,0,0, "+ str (2 ** (nota - 85)) +", 0,0 "elif (nota> =93 e nota <=100 e On):return" 0,0,0, 0,0,0,0,0,0, "+ str (2 ** (nota - 93)) +", 0 "elif (nota> =101 e note <=108 e 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 "def set_bit_prev (On, note, index):#Im mesmo como set_bit, mas anterior ciente 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 ** (nota - 21))) + temp [temp.find (","):] if (not On):return str (int (local_temp) - (2 ** (note - 21))) + temp [temp.find (","):] elif (nota> =29 e nota <=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 e 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 [em 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 (nota> =45 e 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 ** (note - 45))) + temp [indexTh (temp, ",", 4):] if (not On):return temp [0:indexTh (temp, ",", 3) + 1] + str (int (local_temp ) - (2 ** (nota - 45))) + temp [indexTh (temp, ",", 4):] elif (nota> =53 e 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 ** (note - 53))) + temp [indexTh (temp, ",", 5):] if (not On):return temp [0:indexTh (temp, ",", 4) + 1] + str (int (local_temp) - (2 ** (nota - 53))) + temp [indexTh (temp, ",", 5):] elif (nota> =61 e 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 (not On):return temp [0:indexTh (temp, ",", 5) + 1] + str (int (local_temp) - (2 ** (nota - 61))) + temp [indexTh (temp, ",", 6):] elif (nota> =69 e 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 (not On):return temp [0:indexTh (temp, ",", 6) + 1] + str (int (local_temp) - (2 ** (note - 69))) + temp [indexTh (temp, ",", 7):] elif (note> =77 e 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 (nota> =85 e nota <=92):# erro aqui 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 ** (nota - 85))) + temp [indexTh (temp, ",", 9):] elif (nota> =93 e 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 (not On):return temp [0:indexTh (temp, ",", 9) + 1] + str (int (local_temp) - (2 ** (nota - 93))) + temp [indexTh (temp, ",", 10):] elif (nota> =101 e nota <=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):# Toma String, string para encontrar e ordem para encontrar string para encontrar em essa ordem #retorna a ordem do índice =1 last_index =0 while (True):temp =in_string.find (find_this, last_index) if (temp ==-1):return -1 if (ordem ==th):return temp ordem + =1 last_index =temp + 1def time_finder (in_string):# Pega uma string e encontra o tempo, retorna como um int time_end =in_string.index ("") return int (in_string [0:time_end]) def time_finder_comm (in_string):# Pega uma string e encontra o tempo, retorna como um int vírgula time_end =in_string.index (",") return int (in_string [0:time_end]) def note_finder (in_string):# Pega uma string, procura n =, retorna o valor n como um 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 uma string, procura On ou Off, retorna true se On start =in_string.index ("") + 1 end =in_string.index ("ch =") - 1 se in_string [start:end] =="On":return True elif in_string [start:end] =="Off":return Falsemain () 
Processamento para enviar dados ao arduino Processing
Lê o arquivo de texto traduzido e o envia para o arduino.
Deve modificar o multiplicador de tempo se o tempo for diferente de 50000.
Inverte bytes porque muda da esquerda para a direita. (O arquivo de texto assume da direita para a esquerda)
 importação processing.serial. *; Serial myPort; String [] inputLines; void setup () {myPort =new Serial (this, "COM3", 9600); inputLines =loadStrings ("translated.txt"); run ();} void run () {// lê a hora e envia os dados da linha bt usando o método de dados int lastTime =0; para (int i =0; i  
Código do Arduino Arduino
Código simples para arduino. Recebe entradas de Serial. 888 e 999 são reservados para o comando de abertura e fechamento do registro de deslocamento.
 Sem visualização (somente download). 

Esquemas

Sinto muito pelo desenho não profissional. Este é todo o conceito. Não há diferença entre o diagrama do documento Arduino -ShiftOut, exceto para o mosfet. Eu recomendo olhar para isso também.

Processo de manufatura

  1. Robô Raspberry Pi controlado por Bluetooth
  2. Construa seu robô de streaming de vídeo controlado pela Internet com Arduino e Raspberry Pi
  3. Robô controlado por Wi-Fi usando Raspberry Pi
  4. LEDs controlados por Alexa através do Raspberry Pi
  5. Homem de Ferro
  6. Encontre-me
  7. Controle do umidificador Arduino
  8. Robô controlado por fala
  9. MobBob:DIY Arduino Robot Controlado por Smartphone Android
  10. Joystick Arduino