Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

PiBot: Robot Piano Berbasis Arduino untuk Pertunjukan Musik Presisi

Komponen dan Perlengkapan

Nama BagianJumlah
Arduino 1011
Texas Instruments 74HC59511
IRFZ44N (N-Channel Mosfet)88
Aki 12V2
Kapasitor 100 µF11
Kabel kawat OpenBuilds1
Breadboard (generik)11
Soket IC 8 kaki11
Resistor 10k ohm88
Diod 1N4007 (Tegangan Tinggi, Arus Tinggi)88

Alat dan Mesin yang Diperlukan

Pistolet lem panas (generik)

Aplikasi dan Layanan Online

Processing
Python
Konversi File MIDI Biner ke Teks

Tentang Proyek

Bagaimana semuanya dimulai:

Banyak tahun lalu, Yamaha memperkenalkan piano otomatis. Saya yang masih muda dan tidak berpengetahuan melihat piano itu memainkan musik di balik jendela kaca toko alat musik.

Cukup obrolan kecil, sebenarnya tidak ada alasan besar mengapa saya memulai proyek ini selain karena saya hanya ingin melakukannya.

Ringkasan:

Papan tunggal Arduino Mega berbiaya sekitar $40 dan dua akan diperlukan untuk mengontrol 88 solenoid. Itu cukup mahal. Sebaliknya, dapatkan Arduino Uno yang murah dan 11 shift register. Shift Register adalah metode untuk mengontrol banyak output (biasanya LED) dengan sejumlah kecil pin output. Pada dasarnya, itu satu Arduino dengan 11 shift register dan mengontrol 88 Solenoid.

Karena kita menggunakan shift register, sebuah PC akan mengirim sekumpulan bit ke Arduino daripada komunikasi MIDI. File MIDI akan diterjemahkan menjadi sekumpulan bit sebelumnya.

Hardware:

Saat saya mendapatkan solenoid langsung dari China, saya menemukan bahwa solenoid ini tidak cukup kuat untuk mendorong tombol piano. Tentu saja mendorong tombol piano dari titik terdalam membutuhkan lebih banyak gaya, tetapi saya pikir itu metode terbaik yang tidak merusak piano. Akhirnya saya mendorong 24V melalui solenoid 12V untuk mendapatkan cukup daya.

PiBot: Robot Piano Berbasis Arduino untuk Pertunjukan Musik Presisi

88 Solenoid mengonsumsi banyak daya dan karena saya tidak bisa pergi membeli PSU mahal, saya memutuskan untuk menggunakan aki mobil ayah saya.

PiBot: Robot Piano Berbasis Arduino untuk Pertunjukan Musik Presisi

Setelah itu, setiap shift register dan MOSFET akan ditempatkan pada papan kontrol.

PiBot: Robot Piano Berbasis Arduino untuk Pertunjukan Musik Presisi

595 di kanan dengan sokongan untuk kasus saya membakarnya. Diagram rangkiran sama persis dengan contoh 2 dari sumber referensi. Ganti LED dengan gerbang MOSFET. Seperti yang Anda lihat, tidak ada resistor pull down karena resistor tambahan akan meningkatkan biaya dan memelatkannya pada papan itu akan melelehkan jari. MOSFET ini akan membuka pada 5V dan menutup di bawah 4V atau sekitarnya.

Terakhir, dapatkan sepotong plat plastik untuk melekatkan solenoid ke dalamnya. Menggunakan lem panas dan plat plastik adalah ide buruk mengingat itu akan menjadi panas, tetapi itu yang terbaik yang mampu saya beli.

Dan kemudian jalankan satu sisi kabel solenoid ke sisi positif aki.

PiBot: Robot Piano Berbasis Arduino untuk Pertunjukan Musik Presisi

Perangkat Lunak:

Langkah pertama adalah mendapatkan file MIDI.

Langkah kedua adalah mendapatkan MIDI dalam bentuk teks. Ini dapat dilakukan di situs web yang berguna ini: https://flashmusicgames.com/midi/mid2txt.php.

Untuk kesederhanaan, abaikan tanda waktu, tempo, dan par. Tempo dapat dikalikan ke waktu nanti. Pada dasarnya Anda ingin file seperti ini:

PiBot: Robot Piano Berbasis Arduino untuk Pertunjukan Musik Presisi

Sekarang, gunakan ini untuk membuat 11 set data 8 bit dengan waktu dengan menjalankannya melalui kode Python (dilampirkan).

PiBot: Robot Piano Berbasis Arduino untuk Pertunjukan Musik Presisi

Mereka siap dikirim ke Arduino melalui COM Processing.

Lihat lampiran untuk mengetahui cara Processing mengirim data ini dan bagaimana Arduino menanganinya.

Catatan: Kebiasaan coding saya buruk dan mungkin sulit dibaca. Processing mengirim data dari kanan ke kiri karena Arduino mendorong data ke kanan pada piano fisik.

Semuanya bekerja:

Pemecahan Masalah:

Jika insinyur profesional melihat posting ini, dia akan berpikir bahwa sistem ini akan memiliki banyak masalah. Dan ada banyak masalah.

Karena solenoid ditempel dengan lem panas pada plat, solenoid terlalu panas dan melelehkan lem panas adalah masalah besar. Solusinya adalah dengan mencabutnya dan menggantinya dengan lem dua sisi yang tahan panas hingga 150C.

Kode

Kode Python untuk terjemahanPython
output_file = open("translated.txt", "w")
input_file = open("megalocania.txt")
raw_input_data = input_file.read()
work_data = raw_input_data.splitlines()
result = []

def main():
    for 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))
    for b in result:
        output_file.write(b)
        output_file.write("\n")
    output_file.close()

def set_bit(On, note):
    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(note >= 45 and note <= 52 and On): return "0,0,0," + str(2**(note - 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(note >= 61 and note <= 68 and On): return "0,0,0,0,0," + str(2**(note - 61)) + ",0,0,0,0,0"
    elif(note >= 69 and note <= 76 and On): 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**(note - 77)) + ",0,0,0"
    elif(note >= 85 and note <= 92 and On): return "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**(note - 93)) + ",0"
    elif(note >= 101 and note <= 108 and 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):
    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(note >= 29 and 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 and 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[indexTh(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 and 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 and 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 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 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):
        local_temp = temp[(indexTh(temp, ",", 8) + 1):indexTh(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 and 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 and 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):
    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 + 1

def time_finder(in_string):
    time_end = in_string.index(" ")
    return int(in_string[0:time_end])

def time_finder_comm(in_string):
    time_end = in_string.index(",")
    return int(in_string[0:time_end])

def note_finder(in_string):
    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):
    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 False

main()
Processing untuk mengirim data ke arduinoProcessing
import processing.serial.*;
Serial myPort;
String[] inputLines;
void setup() {
  myPort = new Serial(this, "COM3", 9600);
  inputLines = loadStrings("translated.txt");
  run();
}
void run() {
  int lastTime = 0;
  for(int i = 0; i < inputLines.length; i++) {
    String temp = inputLines[i];
    delay((Integer.parseInt(temp.substring(0, temp.indexOf(","))) - lastTime) * 5);
    lastTime = Integer.parseInt(temp.substring(0, temp.indexOf(",")));
    send(temp.substring(temp.indexOf(",") + 1));
  }
}
void send(String data) {
  String eleventh = data.substring(0, indexOforder(data, ",", 1));
  String tenth = data.substring((indexOforder(data, ",", 1) + 1), (indexOforder(data, ",", 2)));
  String ninth = data.substring((indexOforder(data, ",", 2) + 1), (indexOforder(data, ",", 3)));
  String eighth = data.substring((indexOforder(data, ",", 3) + 1), (indexOforder(data, ",", 4)));
  String seventh = data.substring((indexOforder(data, ",", 4) + 1), (indexOforder(data, ",", 5)));
  String sixth = data.substring((indexOforder(data, ",", 5) + 1), (indexOforder(data, ",", 6)));
  String fifth = data.substring((indexOforder(data, ",", 6) + 1), (indexOforder(data, ",", 7)));
  String forth = data.substring((indexOforder(data, ",", 7) + 1), (indexOforder(data, ",", 8)));
  String third = data.substring((indexOforder(data, ",", 8) + 1), (indexOforder(data, ",", 9)));
  String second = data.substring((indexOforder(data, ",", 9) + 1), (indexOforder(data, ",", 10)));
  String first = data.substring(indexOforder(data, ",", 10) + 1);
  myPort.write("888f");
  myPort.write(first + "f");
  myPort.write(second + "f");
  myPort.write(third + "f");
  myPort.write(forth + "f");
  myPort.write(fifth + "f");
  myPort.write(sixth + "f");
  myPort.write(seventh + "f");
  myPort.write(eighth + "f");
  myPort.write(ninth + "f");
  myPort.write(tenth + "f");
  myPort.write(eleventh + "f");
  myPort.write("999f");
}
int indexOforder(String data, String find, int order) {
  int currentOrder = 0;
  int lastLocation = 0;
  while(currentOrder < order) {
    lastLocation = data.indexOf(find, (lastLocation + 1));
    currentOrder += 1;
  }
  return lastLocation;
}
Kode ArduinoArduino
No preview (download only).

Skematik

Maaf untuk gambar yang tidak profesional. Ini adalah seluruh konsep. Tidak ada perbedaan antara diagram dokumen Arduino -ShiftOut kecuali untuk MOSFET. Saya merekomendasikan untuk melihat itu juga.

PiBot: Robot Piano Berbasis Arduino untuk Pertunjukan Musik Presisi

Proses manufaktur

  1. Membuat Robot Raspberry Pi yang Dikontrol Bluetooth dengan Umpan Balik Suara
  2. Membuat Robot Streaming Video yang Dikontrol Internet dengan Arduino & Raspberry Pi
  3. Membangun Robot Raspberry Pi Dikontrol Wi‑Fi dengan Python – Panduan Langkah demi Langkah
  4. Kendalikan LED dengan Alexa melalui Raspberry Pi – Panduan Langkah demi Langkah yang Mudah
  5. Bangun Iron Man Arduino: Komponen, Sensor, dan Panduan Langkah demi Langkah
  6. Find Me: Pelacak Item Cerdas dengan Arduino dan Bluetooth
  7. Pengontrol Kelembapan Arduino DIY dengan Relay – Pengaturan Tegangan Tinggi yang Aman
  8. Membangun Robot Kendali Suara dengan Arduino Nano
  9. MobBob: Buat Robot Arduino Sendiri, Dikontrol dengan Mulus melalui Smartphone Android
  10. Volant Joystick Arduino Kustom untuk Gaming