INHOUDSOPGAWE:

MIDI Drum Kit op Python en Arduino: 5 stappe (met foto's)
MIDI Drum Kit op Python en Arduino: 5 stappe (met foto's)

Video: MIDI Drum Kit op Python en Arduino: 5 stappe (met foto's)

Video: MIDI Drum Kit op Python en Arduino: 5 stappe (met foto's)
Video: Fun with Music and Programming by Connor Harris and Stephen Krewson 2024, November
Anonim
Image
Image
MIDI Drum Kit op Python en Arduino
MIDI Drum Kit op Python en Arduino
MIDI Drum Kit op Python en Arduino
MIDI Drum Kit op Python en Arduino

Ek wou nog altyd van kleins af 'n dromstel koop. Destyds het al die musikale toerusting nie al die digitale toepassings gehad nie, aangesien ons baie vandag het, daarom was die pryse en die verwagtinge te hoog. Ek het onlangs besluit om 'n goedkoopste dromstel van eBay te koop, met die enigste prioriteit: die vermoë om dit af te breek en my eie hardeware en sagteware aan die toestel te koppel.

Die aankoop was glad nie teleurstellend nie: draagbare oprol-dromstel met 9 verskillende klankblokkies, twee voetskakelpedale vir skoptrommel en hi-hat en mikro-USB-aansluiting. Wat werklik demotiverend was, is die uitsetgeluide (die werklike gebruik vir hierdie kit is om 'n eksterne luidspreker aan te sluit en dit te geniet). Daarom het ek besluit om dit oor te skakel na my eie programmeerbare via USB, MIDI -dromstel gebaseer op Arduino en gebruikersinterface gebaseer op Python, vir handige gebruik en maklike aanpassings, soos volume, noot en kanaalkeuses.

Kenmerke van die toestel:

  • Lae prys
  • Skep dromstel uit enige digitale insette - selfs 'n verskeidenheid drukknoppies
  • Ondersteuning vir kommunikasie en kragtoevoer slegs via USB -koppelvlak - Integrasie van USB na UART -omskakelaar en Arduino -toestel
  • Mininum onderdele vir behoorlike werking
  • Maklik om te gebruik Python-gebaseerde UI
  • Volledige MIDI -ondersteuning met verstelbare snelheid, noot en Arduino -penne
  • Stoor en laai pasgemaakte dromkonfigurasies wat in die geheue van die toestel gestoor is

Kom ons gaan voort met die projek …

Stap 1: Teorie van werking

Teorie van werking
Teorie van werking
Teorie van werking
Teorie van werking
Teorie van werking
Teorie van werking

Blokdiagram

Kom ons fokus eerstens op die projekstruktuur en verdeel dit in aparte blokke:

Oprol tromstel

Die hoofeenheid van die projek. Dit bestaan uit 9 aparte trommelblokkies, waar elke blok 'n verskeidenheid knoppies is wat hul logiese toestand verander terwyl dit raak. As gevolg van die struktuur, is daar 'n moontlikheid om hierdie spesifieke dromstel uit enige drukknoppies te bou. Elke dromblokkie is gekoppel aan die optrekweerstand op die hoofelektroniese bord, terwyl 'n dromkussing herhaaldelik getref word, word 'n spesifieke skakelaar aan die stroombaan se grond vasgemaak en is daar 'n logiese laag op die trommelbloklyn. As daar geen druk uitgeoefen word nie, is die dromblokkie-skakelaar oop en as gevolg van die optrekweerstand na die kraglyn, is daar logies HOOG op die drombloklyn. Omdat die doel van die projek is om 'n volledige digitale MIDI -toestel te skep, kan al die analoog dele op die hoof PCB verwaarloos word. Dit is belangrik om op te let dat die dromstel twee pedale vir skoptrommel en hi-hat het, wat ook aan die optrekweerstands vasgemaak is en dieselfde operasie-logika as al die trommelblokkies het (ons bespreek dit 'n bietjie later).

Arduino Pro-Micro

Die brein van die dromstel. Die doel daarvan is om op te spoor of daar 'n sein uit 'n dromblok kom en die gepaste MIDI -uitset te voorsien met al die nodige parameters: Let op, snelheid en duur van die sein. Vanweë die digitale aard van dromblokkies, kan hulle eenvoudig aan arduino -digitale insette gekoppel word (in totaal 10 penne). Om al die gewenste instellings en MIDI-inligting te stoor, gaan ons die geheue daarvan gebruik-EEPROM, en elke keer dat ons die toestel aanskakel, word MIDI-inligting vanaf EEPROM gelaai, sodat dit herprogrammeerbaar en herkonfigureer kan word. Arduino Pro-Micro is ook in 'n baie klein verpakking beskikbaar en kan maklik in die binnekas van die dromstel toegewys word.

FTDI USB na reeksomskakelaar

Om ons toestelkenmerke te kan programmeer en te definieer met behulp van 'n rekenaarprogram, moet u die USB-koppelvlak na die reeks omskakel, want Arduino Pro-Micro het nie USB nie. Aangesien die kommunikasie tussen toestelle op UART gebaseer is, word die FTDI -toestel in hierdie projek gebruik, vanweë die eenvoudige gebruik daarvan, ongeag die bykomende eienskappe.

PC -toepassing - Python

As dit kom by die ontwikkeling van gebruikerskoppelvlakke en vinnig te bou projekte, is Python 'n uitstekende oplossing. Die doel van die UI -toepassing is om dit baie geriefliker te maak om MIDI -eienskappe vir ons dromstel te herdefinieer, inligting te stoor, programmeertoestelle te maak en kommunikasie tussen die stelsels te maak sonder om die kode telkens weer op te stel. Omdat ons 'n seriële koppelvlak gebruik om met die dromstel te kommunikeer, is daar baie gratis modules op die internet wat alle soorte seriële kommunikasie ondersteun. Boonop, soos later bespreek sal word, bestaan die UART -koppelvlak uit drie penne: RXD, TXD en DTR. DTR word gebruik om die Arduino -module terug te stel, dus as ons belangstel om 'n MIDI -app uit te voer of 'n gebruikersinterface aan te sluit op 'n programmeertoestel, hoef u absoluut geen USB -kabel weer aan te sluit nie.

Stap 2: Onderdele en instrumente

Dele

  • Oprol tromstel
  • 2 x Sustain Pedals (gewoonlik ingesluit in die DK -pakket).
  • FTDI - USB na reeksomskakelaar
  • Arduino Pro Micro
  • Mikro-USB-kabel

Instrumente

  • Soldeerbout/stasie
  • Soldeer blik
  • Enkeldrank draad met dun deursnee
  • Pincet
  • Snyer
  • Tang
  • Mes
  • Skroewedraaier
  • 3D -drukker (opsioneel - vir pasgemaakte pedaalplatforms)

Sagteware

  • Arduino IDE
  • Python 3 of hoër
  • JetBrains Pycharm
  • Haarlose MIDI -koppelvlak
  • loopMIDI

Stap 3: Soldeer en monteer

Soldeer en monteer
Soldeer en monteer
Soldeer en monteer
Soldeer en monteer
Soldeer en monteer
Soldeer en monteer

Aangesien daar drie modules gekombineer moet word, is die soldeer- en monteerproses kort en eenvoudig:

  • Koppel Arduino Pro-Micro aan met FTDI-toestel, maak seker dat die verbindings voldoen aan I/O wat by elke toestel gedefinieer is:

    • VBUS-VBUS
    • GND-GND
    • DTR-DTR
    • RXD-TXD
    • TXD-RXD
  • Verwyder al die skroewe uit die plastiekomhulsel van die trommel, maak seker dat u kan fokus op die pad-tot-bord-kabel en die optrekweerstande daarvan
  • Soldeer dun drade vir die Arduino-FTDI-module wat ons voorheen gebou het:

    • Digitale insette: D [2:11]
    • VBUS
    • D+
    • D-
    • GND
  • Plaas die module in die batterykas sodat die drade aan dieselfde kant dryf as die optrekweerstands van die pads
  • Soldeer alle digitale insette aan die trommelblokkies, soos in die laaste figuur getoon word.
  • Soldeer mikro-USB-bus (VBUS, D+, D-, GND) na FTDI-toestel, maak seker dat daar geen foute is om hierdie drade op te spoor nie.
  • Bevestig die Arduino-FTDI-module met warm gom aan die batterykas
  • Monteer die toestel met die toepaslike skroewe

Ons het dit gedoen, die toestel is saamgestel. Kom ons gaan voort met die kode …

Stap 4: Programmering A: Arduino

Programmering A: Arduino
Programmering A: Arduino

Laat ons ons skets stap-vir-stap beskryf:

Eerstens moet twee noodsaaklike biblioteke ingesluit word vir die korrekte werking. EEPROM is reeds vooraf geïnstalleer in die Arduino IDE, maar die debouncer-module vir skoptrommel moet afsonderlik geïnstalleer word

#include #include

Hierdie skakelaars word hoofsaaklik gebruik in ontfoutingsreekse. As u die verbinding van die Arduino -terminale met die dromblokkies wil probeer en al die digitale insette wil bepaal, moet hierdie skakelaars gedefinieer word

/ * Ontwikkelaarswisselaars: laai die gewenste modus af vir ontfouting of initialisering * ///#definieer LOAD_DEFAULT_VALUES // Laai konstante waardes in plaas van EEPROM //#definieer PRINT_PADS_PIN_NUMBERS // Druk pin -nommer wat gekoppel is aan 'n pad wat via seriële poort getref is

Konstante velde verteenwoordig al die standaardwaardes, insluitend die trommelkussentelling. Om die toestel vir die eerste keer te laat werk, moet u die presiese verbinding van Hi-Hat en Kick-pedale ken

/ * Trommeltipe opsomming */

enum DRUM_POSITION {KICK = 0, SNARE, HIHAT, RIDE, CYMBAL1, CYMBAL2, TOM_HIGH, TOM_MID, TOM_LO, HIHAT_PEDAL};

/ * Standaardwaardes */

const uint8_t DRUM_NOTES [10] = {36, 40, 42, 51, 49, 55, 47, 45, 43, 48}; const uint8_t DRUM_VELOCITIES [10] = {110, 100, 100, 110, 110, 110, 110, 110, 110, 110}; const uint8_t DRUM_PINS [10] = {8, 6, 4, 3, 11, 9, 5, 10, 2, 7};

/ * Duur van afskop van skoptrommel */

const uint8_t KICK_DB_DURATION = 30;

EEPROM word gebruik om alle data wat van 'n rekenaarprogram afkomstig is, te stoor/te laai. Die adresse wat hierbo beskryf is, toon die presiese ligging vir MIDI -inligting vir elke trommelblok

/* EEPROM Adresse kartering

Notas: | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 |

Spelde: | 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 | Snelhede | 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23 | */ const uint8_t NOTES_ADDR = 0x00; const uint8_t VELOCITIES_ADDR = 0x14; const uint8_t PINS_ADDR = 0x0A;

Globale veranderlikes word gebruik om die toestand van elke pad te bepaal en dienooreenkomstig MIDI -kommunikasie uit te voer

/ * Globale veranderlikes */

uint8_t drumNotes [10], drumVelocities [10], drumPins [10]; // MIDI -veranderlikes

uint8_t uartBuffer [64]; // UART -buffer vir die versameling en berging van MIDI Data Debouncer -skop (DRUM_PINS [KICK], KICK_DB_DURATION); // Debounser -voorwerp vir kick drum vlugtige bool previousState [9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Drum pad vorige logika state vlugtige bool currentState [9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Die huidige logika van die trommelblok

EEPROM funksies

/* Stoor instellings in die EEPROM*/

leegte winkelEEPROM () {

memcpy (drumNotes, uartBuffer, 10); memcpy (drumPins, uartBuffer + 10, 10); memcpy (drumVelocities, uartBuffer + 20, 10); vir (uint8_t i = 0; i <10; i ++) EEPROM.write (NOTES_ADDR+i, drumNotes ); vir (uint8_t i = 0; i <10; i ++) EEPROM.write (PINS_ADDR+i, drumPins ); vir (uint8_t i = 0; i <10; i ++) EEPROM.write (VELOCITIES_ADDR+i, drumVelocities ); }

/* Laai instellings vanaf die EEPROM*/

void loadEEPROM () {for (uint8_t i = 0; i <10; i ++) drumNotes = EEPROM.read (NOTES_ADDR+i); vir (uint8_t i = 0; i <10; i ++) drumPins = EEPROM.read (PINS_ADDR+i); vir (uint8_t i = 0; i <10; i ++) drumVelocities = EEPROM.read (VELOCITIES_ADDR+i); }

Initialisering van veranderlikes en programmeermodus, in die geval van pedale en Arduino -boot word gelyktydig geaktiveer

void enterProgrammingMode () {

bool confirmBreak = vals; uint8_t lineCnt = 0; uint8_t charCnt = 0; char readChar = 0; terwyl (! confirmBreak) {if (Serial.available ()) {uartBuffer [charCnt] = Serial.read (); as (charCnt> = 29) confirmBreak = waar; anders charCnt ++; }} Serial.println ("OK"); storeEEPROM (); }

leegte initValues () {

#ifdef LOAD_DEFAULT_VALUES memcpy (drumNotes, DRUM_NOTES, 10); memcpy (drumVelocities, DRUM_VELOCITIES, 10); memcpy (drumPins, DRUM_PINS, 10); #else loadEEPROM (); #endif}

MIDI -kommunikasiehanteerders met 'n vertraging van 1ms se ophou tyd

/ * Speel MIDI -nootfunksie */

leeg midiOut (enum DRUM_POSITION drumIn) {

if (drumIn == HIHAT) {// As HI-HAT getref is, moet nagegaan word of die pedaal ingedruk word as (! digitalRead (drumPins [HIHAT_PEDAL])) {noteOn (0x90, drumNotes [HIHAT_PEDAL], drumVelocities [HIHAT_PEDAL]); vertraging (1); noteOn (0x90, drumNotes [HIHAT_PEDAL], 0); } anders {noteOn (0x90, drumNotes [HIHAT], drumVelocities [HIHAT]); vertraging (1); noteOn (0x90, drumNotes [HIHAT], 0); }} anders {// Gewone drum MIDI transmissie noteOn (0x90, drumNotes [drumIn], drumVelocities [drumIn]); vertraging (1); noteOn (0x90, drumNotes [drumIn], 0); }}

void noteOn (int cmd, int pitch, int velocity) {Serial.write (cmd); Reeks.skryf (toonhoogte); Reeks.skryf (snelheid); }

setup () en loop () funksies met oneindige apparaatbedieninglus:

ongeldige opstelling () {

Serial.begin (115200);

vir (uint8_t i = 0; i <10; i ++) {pinMode (i+2, INVOER); } #ifdef PRINT_PADS_PIN_NUMBERS terwyl (waar) {// Oneindige ontfoutlus vir (uint8_t i = 0; i <10; i ++) {if (! digitalRead (i+2)) {Serial.print ("Pin No: D"); Serial.print (i + '0'); // Skakel getal om na ASCII -karakter}}} #else initValues (); / * Programmeermodus: As twee pedale ingedruk word tydens die opstart - modus is geaktiveer */ as (! DigitalRead (drumPins [KICK]) &&! DigitalRead (drumPins [HIHAT_PEDAL])) enterProgrammingMode (); #endif}

leemte -lus () {vir (uint8_t i = 1; i <9; i = i + 1) {currentState = digitalRead (drumPins ); if (! currentState && previousState ) midiOut (i); // Vergelyk toestande en ontdek dalende rand previousState = currentState ; } kick.update (); // Kick drum gebruik 'n pasgemaakte debounce -algoritme as (kick.edge ()) if (kick.falling ()) midiOut (KICK); }

Stap 5: Programmering B: Python en gebruikerskoppelvlak

Programmering B: Python en gebruikerskoppelvlak
Programmering B: Python en gebruikerskoppelvlak
Programmering B: Python en gebruikerskoppelvlak
Programmering B: Python en gebruikerskoppelvlak
Programmering B: Python en gebruikerskoppelvlak
Programmering B: Python en gebruikerskoppelvlak

Die Python -gebruikerskoppelvlak is op die eerste oogopslag 'n bietjie ingewikkeld om te verstaan, daarom probeer ons die basiese beginsels daarvan verduidelik, hoe om dit te gebruik, watter funksie elke knoppie het en hoe ons die Arduino -toestel behoorlik kan programmeer.

Gebruikerskoppelvlak - toepassing

UI is 'n grafiese voorstelling vir ons dromstelprogrammeerder, wat dit baie maklik maak om te gebruik en maklik om Arduino -toestelle altyd te programmeer. UI bestaan uit verskeie grafiese modules wat gekoppel is aan hul voorgestelde werking. laat ons hulle een vir een hersien:

  1. Drumstelbeeld: Python UI gebruik XY-beeldkoördinate om te bepaal watter tipe trommel gekies is. As 'n geldige trommelgebied gekies is, verskyn 'n sekondêre IO -boodskap met nootvelde, snelheid en Arduino -terminaal vir 'n spesiale dromblok. Nadat hierdie parameters deur die gebruiker geverifieer en goedgekeur is, kan hierdie waardes direk na die Arduino -toestel oorgedra word.
  2. Beeld van eksterne kontroleerder: om 'n MIDI-dromstel met 'n VST/musiek-skepomgewing te kan gebruik, moet Serial-to-MIDI-tolk gebruik word. Ek het Hairless gebruik, wat gratis beskikbaar is en direk vanaf ons gebruikersinterface gebruik kan word, net deur op die beeld daarvan te druk.
  3. COM -poortlys: om met Arduino te kommunikeer, moet u die aangehegte COM -poort spesifiseer. Die lys word verfris deur op die knoppie Refresh te druk.
  4. Laai/stoor konfigurasie: Daar is standaard MIDI -waardes gedefinieer in die kode, wat deur die gebruiker gewysig kan word deur interaksie met UI. Konfigurasie word gedefinieer in die config.txt -lêer in 'n spesifieke formaat, wat deur die gebruiker gestoor of gelaai kan word.
  5. Programtoetsknoppie: Om al die gewysigde MIDI-waardes in Arduino EEPROM te stoor, moet u twee voetpedale (skoptrommel en Hi-hat-pedaal) druk, wag totdat die oordrag van data voltooi is. As daar kommunikasieprobleme was, word die regte pop-up vertoon. As die oordrag slaag, sal UI sy suksesvolle boodskap wys.
  6. Uitgangsknoppie: verlaat net die program, met toestemming van die gebruiker.

Hoogtepunte van Python -kode

Daar is baie dinge wat in die kode aangaan, so ons sal die geskrewe funksies eerder as op die hele kode uitbrei.

Om UI te kan gebruik, moet u eers verskeie modules aflaai om die kode te laat werk:

invoer osimport threading invoer tkinter as tk van tkinter invoer boodskapsboks van tkinter invoer * van PIL invoer ImageTk, beeld invoer numpy as np invoer reeks invoer glob

Sommige modules is ingesluit in die standaard Python -pakket. Verskeie modules moet geïnstalleer word via PIP -instrument:

pip installeer Pillow

pip installeer numpy pip installeer ScreenInfo

Dit word sterk aanbeveel om die program via PyCharm uit te voer. In die toekomstige uitgawes beplan ek om 'n uitvoerbare uitvoer vir die projek uit te voer.

Kort kode verduideliking

Dit sal baie makliker wees om die kode te verstaan as ons na die lyne daarvan kyk vanuit die perspektief van funksies en klasse:

1. Die hooffunksie - hier begin die kode

as _name_ == '_main_': drumkit_gui ()

2. Drumstel -konstantes, koördinate en standaard MIDI -inligting

klas tromme: DRUM_TYPES = ["Kick", "Hihat", "Snare", "Crash 1", "Crash 2", "Tom High", "Tom Mid", "Tom Low", "Ride", "Hihat Pedal "," Beheerder "]

COORDINATES_X = [323, 117, 205, 173, 565, 271, 386, 488, 487, 135, 79]

COORDINATES_Y = [268, 115, 192, 40, 29, 107, 104, 190, 71, 408, 208] DIMS_WIDTH = [60, 145, 130, 120, 120, 70, 70, 130, 120, 70, 145] DIMS_LENGTE = [60, 60, 80, 35, 35, 40, 40, 70, 35, 100, 50]

DRUM_ENUM = ["Kick", "Snare", "Hihat", "Ride", "Crash 1", "Crash 2", "Tom High", "Tom Mid", "Tom Low", "Hihat Pedal"]

DRUM_NOTES = [36, 40, 42, 51, 49, 55, 47, 45, 43, 48] DRUM_VELOCITIES = [110, 100, 100, 110, 110, 110, 110, 110, 110, 110] DRUM_PINS = [8, 6, 4, 3, 11, 9, 5, 10, 2, 7]

3. UI -funksies - hantering van gebruikerskoppelvlak en grafiese voorwerpe

def set_active (ui)

def sekondêre_ui (drum_type)

klas SelectionUi (tk. Frame)

klas aansoek (tk. Frame)

def drumkit_gui ()

def event_ui_clicked (gebeurtenis)

def getorigin (self, gebeurtenis)

4. Seriële kommunikasie

def get_serial_ports ()

def communicate_ with_arduino (poort)

5. Werk met lêers: Stoor/laai instellings uit die txt -lêer

def save_config ()

def load_config ()

6. Die bestuur van eksterne program hairless.exe vanaf die kode met behulp van Python Threading -vermoëns

klas ExternalExecutableThread (threading. Thread)

def run_hairless_executable ()

Om die kode uit te voer, is daar 'n lys met lêers wat by die projekmap aangeheg moet word:

  • config.txt: Instellingslêer
  • haarloos.exe: Haarlose MIDI -omskakelaar
  • drumkit.png: Beeld wat alle klikbare dromblokkies in ons gebruikersinterface definieer (moet afgelaai word uit hierdie stap 'beelde stel')
  • drumgui.py: Die projekkode

Dit is alles wat ons moet beklemtoon om dit te laat werk. Dit is baie belangrik om lêers by die projek te voeg: 'n dromstelbeeld, 'n uitvoerbare hairless.exe en 'n konfigurasie -lêer config.txt.

En.. Hier het ons gedoen!:)

Hoop dat u hierdie instruksies nuttig vind.

Dankie vir die lees!:)

Aanbeveel: