Innholdsfortegnelse:

MIDI Drum Kit på Python og Arduino: 5 trinn (med bilder)
MIDI Drum Kit på Python og Arduino: 5 trinn (med bilder)

Video: MIDI Drum Kit på Python og Arduino: 5 trinn (med bilder)

Video: MIDI Drum Kit på Python og Arduino: 5 trinn (med bilder)
Video: Драм-секвенсор Arduino: 8 дорожек, 16 шагов на такт, 8 тактов на паттерн 2024, November
Anonim
Image
Image
MIDI trommesett på Python og Arduino
MIDI trommesett på Python og Arduino
MIDI trommesett på Python og Arduino
MIDI trommesett på Python og Arduino

Jeg har alltid ønsket å kjøpe et trommesett siden jeg var liten. Da hadde ikke alt det musikalske utstyret alle digitale applikasjoner, ettersom vi har mye i dag, og derfor var prisene sammen med forventningene for høye. Nylig har jeg bestemt meg for å kjøpe et billigste trommesett fra eBay, med den eneste prioriteten: Evne til å rive det og feste min egen maskinvare og programvare til enheten.

Kjøpet var ikke skuffende i det hele tatt: Bærbart opprullbart trommesett med 9 forskjellige lydputer, to fotbryterpedaler for sparketrommel og hi-hat og mikro-USB-stikkontakt. Det som virkelig var demotiverende, det er utgangslydene (faktisk bruk for dette settet er å koble til en ekstern høyttaler og nyte den). Så jeg bestemte meg for å konvertere den til min egen programmerbare via USB, MIDI -trommesett basert på Arduino og brukergrensesnitt basert på Python, for praktisk bruk og enkle modifikasjoner som volum, notater og kanalvalg.

Funksjoner på enheten:

  • Lav pris
  • Lag trommesett fra alle digitale innganger - til og med mange trykknapper
  • Kommunikasjonsstøtte og strømforsyning bare via USB -grensesnitt - Integrering av USB til UART -omformer og Arduino -enhet
  • Mininum deler for riktig drift
  • Lett å bruke Python-basert brukergrensesnitt
  • Komplett MIDI -støtte med justerbar hastighet, notat og Arduino -pinner
  • Lagre og last inn egendefinerte trommelkonfigurasjoner lagret i enhetens minne

La oss gå videre til prosjektet …

Trinn 1: Teori om drift

Operasjonsteori
Operasjonsteori
Operasjonsteori
Operasjonsteori
Operasjonsteori
Operasjonsteori

Blokkdiagram

La oss først fokusere på prosjektstrukturen og dele den i separate blokker:

Roll-up trommesett

Prosjektets hovedenhet. Den består av 9 separate trommelunder, hvor hver pute er en rekke knapper som endrer logikkstatusen mens de treffes. På grunn av strukturen er det en mulighet til å konstruere dette trommesettet fra alle trykknapper. Hver trommelput er koblet til opptrekksmotstanden på det elektroniske hovedkortet, og mens trommelputen treffes gjentatte ganger, er en spesifikk bryter knyttet til kretsens bakke og logisk LOW er tilstede på trommelputelinjen. Når det ikke påføres noe trykk, er trommelputebryteren åpen, og på grunn av opptrekkmotstanden til kraftledningen er det logisk HØYT på trommelputelinjen. Fordi formålet med prosjektet er å lage en komplett digital MIDI -enhet, kan alle de analoge delene på hovedkortet ignoreres. Det er viktig å legge merke til at trommesettet har to pedaler for sparketromle og hi-hat, som også er knyttet til opptrekkmotstandene og deler den samme operasjonslogikken som alle trommelputene (Vi diskuterer det litt senere).

Arduino Pro-Micro

Hjernen til trommesettet. Formålet er å oppdage om det kommer et signal ut av en trommelplate og gi passende MIDI -utgang med alle nødvendige parametere: Merk, hastighet og varighet for signalet. På grunn av trommelputenes digitale karakter, kan de ganske enkelt knyttes til arduino digitale innganger (totalt 10 pins). For å lagre alle ønskede innstillinger og MIDI-informasjon, kommer vi til å bruke minnet-EEPROM, derfor blir hver MIDI-informasjon lastet ned fra EEPROM hver gang vi slår på enheten, noe som gjør den omprogrammerbar og omkonfigurerbar. Arduino Pro-Micro er også tilgjengelig i en veldig liten pakke og kan enkelt tildeles i trommesettet.

FTDI USB til seriell omformer

For å programmere og definere våre enhetsfunksjoner ved hjelp av PC-applikasjon, må du konvertere USB-grensesnitt til seriell, fordi Arduino Pro-Micro ikke har USB. Siden kommunikasjonen mellom enheter er basert på UART, brukes FTDI -enheten i dette prosjektet, på grunn av sin enkle bruk uansett tilleggsegenskaper.

PC -applikasjon - Python

Når det gjelder utvikling av brukergrensesnitt og prosjekter som er raske å bygge, er Python en ypperlig løsning. Formålet med UI -applikasjonen er å gjøre det mye mer praktisk å omdefinere MIDI -egenskaper for trommesettet vårt, lagre informasjon, programmere enheten og lage kommunikasjon mellom systemene uten at det er nødvendig å kompilere koden igjen og igjen. Fordi vi bruker serielt grensesnitt for å kommunisere med trommesett, er det mange gratis moduler rundt hele internett som støtter alle typer seriell kommunikasjon. I tillegg, som det vil bli diskutert senere, består UART -grensesnittet av totalt tre pinner: RXD, TXD og DTR. DTR brukes til å utføre tilbakestilling på Arduino -modulen, så når vi er interessert i å kjøre MIDI -app eller koble brukergrensesnitt til programmeringsenhet, er det absolutt ingen grunn til å koble til en USB -kabel eller noe som helst.

Trinn 2: Deler og instrumenter

Deler

  • Roll-up trommesett
  • 2 x Sustain Pedals (vanligvis inkludert i DK -pakken).
  • FTDI - USB til seriell omformer
  • Arduino Pro Micro
  • Micro-USB-kabel

Instrumenter

  • Loddejern/stasjon
  • Loddetinn
  • Enkel kjernetråd med tynn diameter
  • Pinsett
  • Kutter
  • Tang
  • Kniv
  • Skrutrekker
  • 3D -skriver (valgfritt - for tilpassede pedalplattformer)

Programvare

  • Arduino IDE
  • Python 3 eller høyere
  • JetBrains Pycharm
  • Hårfritt MIDI -grensesnitt
  • loopMIDI

Trinn 3: Lodding og montering

Lodding og montering
Lodding og montering
Lodding og montering
Lodding og montering
Lodding og montering
Lodding og montering

Siden det er tre moduler som må kombineres, er lodde- og monteringsprosessen kort og enkel:

  • Fest Arduino Pro-Micro sammen med FTDI-enhet, sørg for at tilkoblingene samsvarer med I/O som er definert på hver enhet:

    • VBUS-VBUS
    • GND-GND
    • DTR-DTR
    • RXD-TXD
    • TXD-RXD
  • Fjern alle skruene fra trommelplasthuset, sørg for at du kan fokusere på pad-to-board-kabelen og dens opptrekkbare motstander
  • Lodde tynne ledninger for Arduino-FTDI-modulen som vi har konstruert tidligere:

    • Digitale innganger: D [2:11]
    • VBUS
    • D+
    • D-
    • GND
  • Sett modulen inn i batterikassen slik at ledningene flyter på samme side som opptrekkmotstandene til putene
  • Lodd alle digitale innganger til trommelputterminalene slik det er vist i den siste figuren.
  • Lodd mikro-USB-buss (VBUS, D+, D-, GND) til FTDI-enhet, sørg for at det ikke er noen feil ved sporing av disse ledningene.
  • Fest Arduino-FTDI-modulen med varmt lim til batterikassen
  • Monter enheten med passende skruefeste

Vi har gjort det, enheten er satt sammen. La oss fortsette til koden …

Trinn 4: Programmering A: Arduino

Programmering A: Arduino
Programmering A: Arduino

La oss beskrive skissen vår trinn for trinn:

Først av alt er det nødvendig å inkludere to nødvendige biblioteker for riktig drift. EEPROM er allerede forhåndsinstallert i Arduino IDE, men debouncer-modulen for sparketrommel må installeres separat

#include #include

Disse bryterne brukes hovedsakelig i feilsøkingssekvenser. Hvis du vil prøve Arduino -tilkoblingene til trommelputene og bestemme alle digitale innganger, bør disse bryterne defineres

/ * Utviklerbrytere: Uncomment ønsket modus for feilsøking eller initialisering * ///#definere LOAD_DEFAULT_VALUES // Last inn konstante verdier i stedet for EEPROM //#definere PRINT_PADS_PIN_NUMBERS // Skriv ut pin -nummer som er koblet til en pad som ble truffet via seriell port

Konstantfelt representerer alle standardverdiene, inkludert trommelputen. For å kjøre enheten for første gang, må du vite nøyaktig tilkobling av Hi-Hat og Kick-pedaler

/ * Trommeltype oppregning */

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

/* Standardverdier */

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};

/ * Kick drum debounce varighet */

const uint8_t KICK_DB_DURATION = 30;

EEPROM brukes til å lagre/laste inn alle dataene som kommer fra PC -applikasjonen. Adressene som er beskrevet ovenfor, viser nøyaktig plassering for MIDI -informasjon for hver trommelplate

/* EEPROM Adressekartlegging

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

Pinner: | 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 | Hastigheter | 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 variabler brukes til å bestemme hver pads tilstand, og utføre MIDI -kommunikasjon deretter

/ * Globale variabler */

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

uint8_t uartBuffer [64]; // UART -buffer for innsamling og lagring av MIDI Data Debouncer kick (DRUM_PINS [KICK], KICK_DB_DURATION); // Debouncer -objekt for kick drum volatile bool previousState [9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Trommelputen forrige logikk angir flyktig bool currentState [9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Trommelputens nåværende logikktilstander

EEPROM -funksjoner

/* Lagre innstillinger i EEPROM*/

void storeEEPROM () {

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

/* Last inn innstillinger fra EEPROM*/

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

Initialisering av variabler og programmeringsmodus, når det gjelder pedaler og Arduino -støvel, aktiveres samtidig

void enterProgrammingMode () {

bool confirmBreak = false; uint8_t lineCnt = 0; uint8_t charCnt = 0; char readChar = 0; while (! confirmBreak) {if (Serial.available ()) {uartBuffer [charCnt] = Serial.read (); if (charCnt> = 29) confirmBreak = true; annet charCnt ++; }} Serial.println ("OK"); storeEEPROM (); }

ugyldig initValues () {

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

MIDI kommunikasjonsbehandlere med forsinkelse på 1ms notat holdetid

/ * Spill MIDI -notatfunksjon */

void midiOut (enum DRUM_POSITION drumIn) {

hvis (drumIn == HIHAT) {// Hvis HI-HAT ble truffet, må du kontrollere om pedalen er trykket hvis (! digitalRead (drumPins [HIHAT_PEDAL])) {noteOn (0x90, drumNotes [HIHAT_PEDAL], drumVelocities [HIHAT_PEDAL]); forsinkelse (1); noteOn (0x90, drumNotes [HIHAT_PEDAL], 0); } annet {noteOn (0x90, drumNotes [HIHAT], drumVelocities [HIHAT]); forsinkelse (1); noteOn (0x90, drumNotes [HIHAT], 0); }} else {// Vanlig trommel MIDI -overføringsnoteOn (0x90, drumNotes [drumIn], drumVelocities [drumIn]); forsinkelse (1); noteOn (0x90, drumNotes [drumIn], 0); }}

void noteOn (int cmd, int pitch, int velocity) {Serial.write (cmd); Serial.write (tonehøyde); Serial.write (hastighet); }

setup () og loop () -funksjoner med uendelig enhetsdriftsløyfe:

ugyldig oppsett () {

Serial.begin (115200);

for (uint8_t i = 0; i <10; i ++) {pinMode (i+2, INNGANG); } #ifdef PRINT_PADS_PIN_NUMBERS while (true) {// Infinite debug loop for (uint8_t i = 0; i <10; i ++) {if (! digitalRead (i+2)) {Serial.print ("Pin No: D"); Serial.print (i + '0'); // Konverter tall til ASCII -tegn}}} #else initValues (); / * Programmeringsmodus: Hvis du trykker på to pedaler under oppstart - modus er aktivert */ hvis (! DigitalRead (drumPins [KICK]) &&! DigitalRead (drumPins [HIHAT_PEDAL])) enterProgrammingMode (); #slutt om }

void loop () {for (uint8_t i = 1; i <9; i = i + 1) {currentState = digitalRead (drumPins ); if (! currentState && previousState ) midiOut (i); // Sammenlign tilstander og finn fallende edge previousState = currentState ; } kick.update (); // Kick drum bruker tilpasset debounce -algoritme if (kick.edge ()) if (kick.falling ()) midiOut (KICK); }

Trinn 5: Programmering B: Python og brukergrensesnitt

Programmering B: Python og brukergrensesnitt
Programmering B: Python og brukergrensesnitt
Programmering B: Python og brukergrensesnitt
Programmering B: Python og brukergrensesnitt
Programmering B: Python og brukergrensesnitt
Programmering B: Python og brukergrensesnitt

Python brukergrensesnitt er litt komplisert å forstå ved første blikk, derfor vil vi prøve å forklare det grunnleggende, hvordan du bruker, hvilken funksjon hver knapp har og hvordan du programmerer Arduino -enheten riktig.

Brukergrensesnitt - applikasjon

UI er en grafisk fremstilling for vår trommesettprogrammerer, noe som gjør den veldig enkel å bruke og praktisk å programmere Arduino -enheten når som helst. UI består av flere grafiske moduler som er knyttet til den foreslåtte operasjonen. la oss se på dem en etter en:

  1. Trommesettbilde: Python UI bruker XY-bildekoordinater for å bestemme hvilken trommeltype som ble valgt. Hvis gyldig trommelregion ble valgt, vises den sekundære IO -meldingen, med notatfelt, hastighet og Arduino -terminal for dedikerte trommelunderlag. Etter at disse parameterne er bekreftet av brukeren og godkjent, kan disse verdiene overføres direkte til Arduino -enheten.
  2. Eksternt kontrollerbilde: For å kunne bruke MIDI-trommesett med VST/musikkskapende miljø, er det behov for å kjøre Serial-to-MIDI-tolk. Jeg har brukt Hairless, som er tilgjengelig gratis og kan kjøres direkte fra brukergrensesnittet vårt, bare ved å trykke på bildet.
  3. COM -portliste: For å kommunisere med Arduino er det nødvendig å spesifisere den tilkoblede COM -porten. Listen oppdateres ved å trykke på Oppdater -knappen.
  4. Last/lagre konfigurasjon: Det er standard MIDI -verdier definert i koden, som kan endres av brukeren via interaksjon med brukergrensesnittet. Konfigurasjon er definert i config.txt -filen i et bestemt format, som kan lagres eller lastes av brukeren.
  5. Program Device Button: For å lagre alle de modifiserte MIDI-verdiene i Arduino EEPROM, må du trykke på to fotpedaler (sparketrommel og Hi-hat-pedal) etter det. Vent på at dataoverføringen er fullført. Hvis det var kommunikasjonsproblemer, vises riktig popup-vindu. Hvis overføringen lykkes, viser brukergrensesnittet sin vellykkede melding.
  6. Avslutt -knapp: Bare avslutt programmet, med brukerens tillatelse.

Høydepunkter i Python -koden

Det er mange ting som skjer i koden, så vi vil utvide de skrevne funksjonene i stedet for hele koden.

Først av alt, for å bruke brukergrensesnittet, må du laste ned flere moduler for å få koden til å fungere:

import osimport threading import tkinter as tk from tkinter import messagebox from tkinter import * from PIL import ImageTk, Image import numpy as np import serial import glob

Noen av modulene er inkludert i standard Python -pakke. Flere moduler bør installeres via PIP -verktøy:

pip installere Pute

pip install numpy pip install ScreenInfo

Det anbefales på det sterkeste å kjøre programmet via PyCharm. I fremtidige utgivelser planlegger jeg å eksportere en kjørbar for prosjektet.

Kort kode Forklaring

Det vil være mye lettere å forstå koden hvis vi ser på linjene fra perspektivet til funksjoner og klasser:

1. Hovedfunksjonen - her starter koden

hvis _name_ == '_main_': drumkit_gui ()

2. Trommesettkonstanter, koordinater og standard MIDI -informasjon

klasse trommer: DRUM_TYPES = ["Kick", "Hihat", "Snare", "Crash 1", "Crash 2", "Tom High", "Tom Mid", "Tom Low", "Ride", "Hihat Pedal "," Kontroller "]

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_LENGTH = [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 -funksjoner - Håndtering av brukergrensesnitt og grafiske objekter

def set_active (ui)

def sekundær_ui (trommeltype)

class SelectionUi (tk. Frame)

class Application (tk. Frame)

def drumkit_gui ()

def event_ui_clicked (hendelse)

def getorigin (selv, hendelse)

4. Seriell kommunikasjon

def get_serial_ports ()

def communic_with_arduino (port)

5. Arbeide med filer: Lagre/last inn innstillinger fra txt -filen

def save_config ()

def load_config ()

6. Kjøre ekstern applikasjon hairless.exe fra koden ved hjelp av Python Threading -funksjoner

klasse ExternalExecutableThread (threading. Thread)

def run_hairless_executable ()

For å kjøre koden, er det en liste over filer som må festes til prosjektmappen:

  • config.txt: Innstillingsfil
  • hårløs.exe: Hårløs MIDI -omformer
  • drumkit.png: Bilde som definerer alle de klikkbare trommelputene i brukergrensesnittet (må lastes ned fra dette trinnets bildesett)
  • drumgui.py: Prosjektkoden

Det er alt vi trenger å understreke for å få det til å fungere. Det er veldig viktig å legge til filer i prosjektet: trommesettbilde, kjørbart hairless.exe og innstillingsfil config.txt.

Og.. Her har vi gjort!:)

Håper du synes denne instruksjonen er nyttig.

Takk for at du leste!:)

Anbefalt: