Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Arduino-gestuurde pianorobot:PiBot

Componenten en benodigdheden

Arduino 101
× 1
Texas Instruments 74HC595
× 11
IRFZ44N
N-Channel Mosfet
× 88
12V batterij
× 2
Condensator 100 µF
× 11
OpenBuilds draadkabel - bij de voet
veel van hen.
× 1
Broodplank (algemeen)
Of generiek prototypebord. Zowat alles dat dingen samenbrengt.
× 11
8-poots IC-socket
Optioneel als je zeker weet dat je GEEN van deze dure 595 zult verbranden
× 11
Weerstand 10k ohm
Niet gebruikt voor dit project, maar beter voor elke mosfet
× 88
1N4007 – Diode voor hoge spanning, hoge stroomsterkte
Niet gebruikt voor dit project, maar beter voor elke mosfet
× 88

Benodigde gereedschappen en machines

Hot lijmpistool (algemeen)

Apps en online services

Verwerking
Python
Binair MIDI-bestand naar tekst

Over dit project

Hoe het begint:

Vele jaren geleden introduceerde Yamaha geautomatiseerde piano. Jong en onschuldig zag ik die piano muziek spelen achter een glazen raam van een instrumentenwinkel.

Genoeg kleine praatjes, er is niet echt een grote reden waarom ik dit project ben begonnen, behalve dat ik het gewoon wilde.

Overzicht:

Een enkel bord van Arduino Mega kost ongeveer $ 40 en er zijn er twee nodig om 88 solenoïdes aan te sturen. Dat is vrij duur. Koop in plaats daarvan een goedkope Arduino Uno en 11 of shift-register. Shift Register is een methode om veel uitgangen (meestal LED's) te besturen met een klein aantal uitgangspinnen. In wezen is het één Arduino met 11 schuifregisters en 88 solenoïden aansturen.

Omdat we Shift-registers gebruiken, stuurt een pc een set bits naar Arduino in plaats van MIDI-com. MIDI-bestand wordt vooraf in een set bits vertaald.

Hardware:

Toen ik de magneetventielen rechtstreeks uit China haalde, kwam ik erachter dat deze magneetventielen niet sterk genoeg zijn om pianotoetsen in te drukken. Natuurlijk kost het meer kracht om de pianotoetsen van binnenuit te duwen, maar ik dacht dat dit de beste methode was om een ​​piano niet kapot te maken. Uiteindelijk heb ik 24V door 12V-solenoïdes geduwd om genoeg stroom te krijgen.

88 Elektromagneten verbruiken veel stroom en omdat ik geen dure PSU kan kopen, besloot ik voor de auto-accu van mijn vader te gaan. (Ik denk dat hij nu nergens heen gaat!)

Als dat uit de weg is, gaat elk van de schuifregisters en MOSFET's op een controllerkaart.

595 aan de rechterkant met een stopcontact voor het geval ik het verbrand. (Wat ik ooit heb gedaan.) Circuitdiagram is precies hetzelfde als voorbeeld 2 vanaf hier. Vervang LED's door MOSFET-poort. Zoals je kunt zien, is er geen pull-down-weerstand omdat extra weerstanden de kosten verhogen en als ik ze op dat bord soldeer, smelt mijn vingers. Aan een wat serieuzere kant zullen deze MOSFET's openen bij 5V en sluiten onder 4V of zo. Bevestigde het door talloze uren van testen. (Theoretisch niet correct. Luister niet naar me.)

Pak ten slotte een stukje plastic plaat om magneetventielen op te lijmen. Hete lijm en plastic plaat gebruiken is een slecht idee aangezien het heet zal worden, maar het is het beste wat ik me kan veroorloven.

En leid dan één kant van de solenoïdedraden naar de positieve kant van de batterij.

Software:

De allereerste stap is om een ​​midi-bestand te krijgen.

De tweede stap is om de midi in de tekstvorm te krijgen. Dat kan op deze handige website:http://flashmusicgames.com/midi/mid2txt.php.

Negeer voor de eenvoud maatsoort, tempo en par. Tempo kan worden vermenigvuldigd met de tijd later. In wezen wil je een bestand als dit:

Gebruik dit nu om in de loop van de tijd 11 sets van 8-bits gegevens te maken door deze door de Python-code (bijgevoegd) te laten lopen.

Ze zijn klaar om naar Arduino te worden verzonden via COM-verwerking.

Zie de bijlage om erachter te komen hoe de verwerking deze gegevens verzendt en hoe Arduino ermee omgaat.

*Opmerking:mijn codeergewoonten zijn slecht en het kan moeilijk zijn om deze te lezen. Processing stuurt gegevens van rechts naar links omdat Arduino gegevens naar rechts op de fysieke piano duwt.

Dit ding werkt:

Problemen oplossen:

Als een professionele ingenieur dit bericht zou zien, zal hij denken dat dit hele systeem veel problemen zal hebben. En er zijn veel problemen.

Omdat de solenoïden heet op de plaat waren gelijmd, was het oververhitten van de solenoïden en het smelten van de hete lijm een ​​groot probleem. De oplossing was om ze eenvoudig te verwijderen en te vervangen door dubbelzijdig plakband dat tot 150C kan weerstaan.

Code

  • Python-code voor vertaling
  • Verwerking om gegevens naar de Arduino te sturen
  • Arduino-code
Python-code voor vertalingPython
Neemt een getextureerd mifi-bestand en vertaalt het naar 11 sets binaire bestanden voor arduino om het te nemen.
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():voor een 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)) voor b in resultaat:output_file .write(b) output_file.write("\n") output_file.close() def set_bit(On, note):#Neemt boolean voor als het aan is of niet, en nootnummer. #Genereert bit 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" elif(note>=37 and note <=44 and On):return "0,0," + str(2**(note - 37)) + ",0,0,0,0 ,0,0,0,0" elif(noot>=45 en noot <=52 en Aan):return "0,0,0," + str(2**(noot - 45)) + ",0, 0,0,0,0,0,0" elif(note>=53 and note <=60 and On):return "0,0,0,0," + str(2**(note - 53)) + ",0,0,0,0,0,0" elif(noot>=61 en noot <=68 en Aan):return "0,0,0,0,0," + str(2**( noot - 61)) + ",0,0,0,0,0" elif(noot>=69 en noot <=76 en Aan):return "0,0,0,0,0,0," + str (2**(note - 69)) + ",0,0,0,0" elif(note>=77 and note <=84 and On):return "0,0,0,0,0,0, 0," + str(2**(noot - 77)) + ",0,0,0" elif(noot>=85 en noot <=92 en Aan):return "0,0,0,0,0 ,0,0,0," + str(2**(noot - 85)) + ",0,0" elif(noot>=93 en noot <=100 en Aan):return "0,0,0, 0,0,0,0,0,0," + str(2**(noot - 93)) + ",0" elif(noot>=101 en opmerking <=108 en Aan):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):#Hetzelfde als set_bit maar vorige bewust temp =resultaat[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(note>=29 en 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 en 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**(opmerking - 37))) + temp[indexTh(temp, ",", 3):] elif(note>=45 en 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**(opmerking - 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 en 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 en 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 en opmerking <=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 and 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**(note - 85))) + temp[indexTh(temp, ",", 9):] elif(note>=93 en 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 en 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 om te vinden, en volgorde om string te vinden om te vinden op 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):#Neemt een string en vindt tijd, retourneert deze als een int time_end =in_string.index(" ") return int(in_string[0:time_end])def time_finder_comm(in_string):#Neemt een string en vindt tijd, retourneert deze als een int komma time_end =in_string.index(",") return int(in_string[0:time_end]) def note_finder(in_string):#Neemt een string, zoekt naar n=, geeft n waarde terug als een 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 een string, zoekt naar Aan of Uit, retourneer true if 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] =="Uit":return Falsemain()
Verwerking om gegevens naar de arduino te verzendenVerwerking
Leest het vertaalde tekstbestand en stuurt het naar de Arduino.
Moet tempovermenigvuldiger wijzigen als het tempo anders is dan 50000.
Draait bytes om omdat het van links naar rechts verschuift. (Tekstbestand gaat van rechts naar links)
import processing.serial.*;Serial myPort;String[] inputLines;void setup(){ myPort =new Serial(this, "COM3", 9600); inputLines =loadStrings("translated.txt"); run();}void run(){ //lees tijd en verzendt data bt lijn met data methode int lastTime =0; for(int i =0; i  
Arduino-codeArduino
Eenvoudige code voor arduino. Neemt invoer van serieel. 888 en 999 zijn gereserveerd voor het openen en sluiten van het schuifregister.
Geen voorbeeld (alleen downloaden).

Schema's

Het spijt me voor onprofessioneel tekenen. Dit is het hele concept. Er is geen verschil tussen het diagram van het Arduino -ShiftOut-document, behalve de mosfet. Ik raad aan om daar ook naar te kijken.

Productieproces

  1. Raspberry Pi-robot bestuurd via Bluetooth
  2. Bouw uw internetgestuurde videostreamingrobot met Arduino en Raspberry Pi
  3. Wifi-gestuurde robot met Raspberry Pi
  4. Alexa gestuurde LED's via Raspberry Pi
  5. Iron Man
  6. Vind mij
  7. Arduino-luchtbevochtigerbediening
  8. Spraakgestuurde robot
  9. MobBob:doe-het-zelf Arduino-robot bestuurd door Android-smartphone
  10. Arduino-joystick
  11. Stappenteller (Arduino 101)