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

PiBot: De Arduino-aangedreven pianorobot voor precisiemuziek

Onderdelen en benodigdheden

Arduino 101 × 1
Texas Instruments 74HC595 (shift register) × 11
IRFZ44N N-kanaal MOSFET × 88
12V accu × 2
Condensator 100 µF × 11
OpenBuilds draadkabel (per meter) × 1
Breadboard (standaard) × 11
8-pots IC-socket × 11
Weerstand 10k ohm × 88
1N4007 diode × 88

Benodigde tools en machines

  • Lijmpistool

Apps en online diensten

  • Processing
  • Python
  • Binary MIDI-bestand naar tekst-converter

Over dit project

Hoe het begon

Jaren geleden introduceerde Yamaha een geautomatiseerde piano. Ik zag als jong kind een piano spelen achter het raam van een muziekwinkel. Er is eigenlijk geen grote reden waarom ik dit project startte – ik wilde het gewoon.

Overzicht

Een enkel Arduino Mega-board kost ongeveer $40 en er zijn er twee nodig voor 88 solenoïdes. Dat is duur. In plaats daarvan gebruik ik een goedkope Arduino Uno met 11 shift registers. Een shift register stelt je in staat om veel uitgangen (meestal LEDs) te besturen met weinig output-pins. Eigenlijk is het één Arduino met 11 shift registers die 88 solenoïdes besturen.

Omdat we shift registers gebruiken, stuurt de PC een set bits naar de Arduino in plaats van MIDI-commando's. Het MIDI-bestand wordt van tevoren omgezet in bitsets.

Hardware

De solenoïdes uit China bleken niet krachtig genoeg om pianotoetsen in te drukken. Uiteindelijk liep ik 24V door de 12V solenoïdes om voldoende kracht te krijgen.

PiBot: De Arduino-aangedreven pianorobot voor precisiemuziek

88 solenoïdes verbruiken veel stroom. Omdat ik geen dure voeding kon kopen, gebruikte ik de autobatterij van mijn vader.

PiBot: De Arduino-aangedreven pianorobot voor precisiemuziek

Elk shift register en MOSFET komt op een controllerbord.

PiBot: De Arduino-aangedreven pianorobot voor precisiemuziek

Het schema is identiek aan voorbeeld 2 uit de Arduino ShiftOut-documentatie, met de LEDs vervangen door MOSFET-gates. Er zit geen pull-down-weerstand op omdat extra weerstanden de kosten verhogen en solderen op dat bord mijn vingers zou smelten. De MOSFETs openen bij 5V en sluiten onder 4V – bevestigd door urenlange tests (niet theoretisch correct, luister niet naar mij).

Tot slot: een plastic plaat om de solenoïdes op te lijmen. Met lijmpistool en plastic is dat een slecht idee omdat het warm wordt, maar het was het beste wat ik me kon permitteren.

PiBot: De Arduino-aangedreven pianorobot voor precisiemuziek

Software

  1. Verkrijg een MIDI-bestand.
  2. Converteer naar tekstformaat via flashmusicgames.com. Negeer tijdsteken, tempo en par – tempo kan later vermenigvuldigd worden.
  3. Gebruik de Python-code (bijgevoegd) om 11 sets van 8-bit data met timing te genereren.
  4. Stuur de data via Processing COM naar de Arduino.
PiBot: De Arduino-aangedreven pianorobot voor precisiemuziek
PiBot: De Arduino-aangedreven pianorobot voor precisiemuziek

Let op: mijn programmeergewoontes zijn slecht en de code kan moeilijk leesbaar zijn. Processing stuurt data van rechts naar links omdat de Arduino data naar rechts pusht op het fysieke piano.

Probleemoplossing

Een professionele ingenieur zou veel problemen zien – en die zitten erin. Omdat de solenoïdes met lijmpistool waren vastgelijmd, smolt de lijm door oververhitting. Oplossing: verwijderen en vervangen door dubbelzijdig tape dat tot 150°C bestand is.

Code

Python-code voor vertaling

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"
    # ... (verder analog voor alle notenbereiken)
    else:
        return "0,0,0,0,0,0,0,0,0,0,0"

# Overige helper-functies: set_bit_prev, indexTh, time_finder, time_finder_comm, note_finder, on_off_finder
main()

Processing-code om data naar Arduino te sturen

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) {
    // Bytes omkeren omdat shift register van links naar rechts werkt
    String eleventh = data.substring(0, indexOforder(data, ",", 1));
    String tenth = data.substring((indexOforder(data, ",", 1) + 1), (indexOforder(data, ",", 2)));
    // ... (verder voor ninth tot first)
    String first = data.substring(indexOforder(data, ",", 10) + 1);

    myPort.write("888f");
    myPort.write(first + "f");
    myPort.write(second + "f");
    // ... (tot eleventh)
    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;
}

Arduino-code

Eenvoudige code voor Arduino. Neemt invoer van Serial. 888 en 999 zijn gereserveerd voor shift register open/close commando's. (Download enkel beschikbaar)

Schema's

Excuses voor de onprofessionele tekening. Dit is het hele concept. Er is geen verschil met het Arduino ShiftOut-documentatieschema behalve de MOSFET. Ik raad aan om dat ook te bekijken.

PiBot: De Arduino-aangedreven pianorobot voor precisiemuziek

Productieproces

  1. Bouw een Bluetooth-gecontroleerde Raspberry Pi Robot met Audio Feedback
  2. Bouw een Internet-gecontroleerde Video-streamende Robot met Arduino & Raspberry Pi
  3. Bouw een Wi-Fi-gecontroleerde Raspberry Pi Robot met Python – Stap-voor-stap Gids
  4. LED's bedienen met Alexa via Raspberry Pi – Eenvoudige stapsgewijze handleiding
  5. Een Arduino Iron Man bouwen: onderdelen, sensoren en stapsgewijze handleiding
  6. Find Me: Slimme Item Locator met Arduino en Bluetooth
  7. DIY Arduino Luchtbevochtiger Controller met Relais – Veilige Hoogspanningsopstelling
  8. Bouw een Stemgecontroleerde Robot met Arduino Nano
  9. MobBob: Bouw Je Eigen Arduino Robot, Naadloos Bestuurd via Android Smartphone
  10. Bouw een Aangepaste Arduino Joystick Stuurwiel voor Gaming
  11. Arduino 101: Bouw een teller met DHT11 sensor & LCD display