Inhaltsverzeichnis:

MIDI-Drum-Kit auf Python und Arduino - Gunook
MIDI-Drum-Kit auf Python und Arduino - Gunook

Video: MIDI-Drum-Kit auf Python und Arduino - Gunook

Video: MIDI-Drum-Kit auf Python und Arduino - Gunook
Video: Drum Kit to MIDI On Arduino and Python 2024, November
Anonim
Image
Image
MIDI-Drum-Kit auf Python und Arduino
MIDI-Drum-Kit auf Python und Arduino
MIDI-Drum-Kit auf Python und Arduino
MIDI-Drum-Kit auf Python und Arduino

Ich wollte schon als Kind immer ein Schlagzeug kaufen. Damals hatte das gesamte Musikequipment nicht alle digitalen Anwendungen, wie wir es heute haben, daher waren die Preise und die Erwartungen zu hoch. Vor kurzem habe ich mich entschieden, ein billigstes Schlagzeug von eBay zu kaufen, mit der einzigen Priorität: Die Möglichkeit, es abzubauen und meine eigene Hardware und Software an das Gerät anzuschließen.

Der Kauf war keineswegs enttäuschend: Tragbares Roll-Up-Drum-Kit mit 9 verschiedenen Soundpads, zwei Fußschalterpedalen für Kickdrum und Hi-Hat und Micro-USB-Steckdose. Was wirklich demotivierend war, sind die ausgegebenen Sounds (Der eigentliche Zweck dieses Kits besteht darin, externe Lautsprecher anzuschließen und zu genießen). Also beschloss ich, es in mein eigenes programmierbares über USB, MIDI-Schlagzeug basierend auf Arduino und eine Benutzeroberfläche basierend auf Python umzuwandeln, für eine praktische Verwendung und einfache Änderungen wie Lautstärke-, Noten- und Kanalauswahl.

Merkmale des Geräts:

  • Niedriger Preis
  • Erstellen von Drum-Kits aus beliebigen digitalen Eingängen – sogar eine Reihe von Drucktasten
  • Kommunikationsunterstützung und Stromversorgung nur über USB-Schnittstelle - Integration von USB-zu-UART-Konverter und Arduino-Gerät
  • Minimale Teile für den ordnungsgemäßen Betrieb
  • Benutzerfreundliche Python-basierte Benutzeroberfläche
  • Vollständige MIDI-Unterstützung mit einstellbarer Velocity, Note und Arduino-Pins
  • Speichern und laden Sie benutzerdefinierte Trommelkonfigurationen, die im Gerätespeicher gespeichert sind

Kommen wir zum Projekt…

Schritt 1: Betriebstheorie

Theorie der Arbeitsweise
Theorie der Arbeitsweise
Theorie der Arbeitsweise
Theorie der Arbeitsweise
Theorie der Arbeitsweise
Theorie der Arbeitsweise

Blockschaltbild

Konzentrieren wir uns zunächst auf die Projektstruktur und teilen sie in separate Blöcke auf:

Roll-Up-Drum-Kit

Die Haupteinheit des Projekts. Es besteht aus 9 separaten Drum-Pads, wobei jedes Pad aus einer Reihe von Tasten besteht, die ihren logischen Zustand ändern, während sie angeschlagen werden. Aufgrund seiner Struktur besteht die Möglichkeit, dieses spezielle Schlagzeug aus beliebigen Druckknöpfen aufzubauen. Jedes Drum-Pad ist mit dem Pull-Up-Widerstand auf der Hauptplatine verbunden. Während das Drum-Pad wiederholt angeschlagen wird, ist ein bestimmter Schalter mit der Masse der Schaltung verbunden und auf der Drum-Pad-Leitung liegt logisch LOW an. Wenn kein Druck ausgeübt wird, ist der Drum-Pad-Schalter geöffnet und aufgrund des Pull-Up-Widerstands zur Stromleitung liegt logisch HIGH an der Drum-Pad-Leitung an. Da der Zweck des Projekts darin besteht, ein vollständiges digitales MIDI-Gerät zu erstellen, können alle analogen Teile auf der Hauptplatine vernachlässigt werden. Es ist wichtig zu beachten, dass das Drum-Kit zwei Pedale für Kickdrum und Hi-Hat hat, die auch an die Pull-Up-Widerstände gebunden sind und die gleiche Betriebslogik wie alle Drum-Pads haben (wir werden es etwas später besprechen).

Arduino Pro-Mikro

Das Gehirn des Schlagzeugs. Sein Zweck besteht darin, zu erkennen, ob ein Signal von einem Drum-Pad kommt, und eine geeignete MIDI-Ausgabe mit allen notwendigen Parametern bereitzustellen: Note, Velocity und Dauer des Signals. Aufgrund der digitalen Natur von Drum-Pads können sie einfach an digitale Arduino-Eingänge (insgesamt 10 Pins) gebunden werden. Um alle gewünschten Einstellungen und MIDI-Informationen zu speichern, verwenden wir seinen Speicher - EEPROM, daher werden bei jedem Einschalten des Geräts MIDI-Informationen aus dem EEPROM geladen, wodurch es umprogrammiert und neu konfiguriert werden kann. Auch Arduino Pro-Micro ist in einem sehr kleinen Paket erhältlich und kann einfach im Schlagzeug-Innenkoffer untergebracht werden.

FTDI USB-zu-Seriell-Konverter

Um unsere Gerätefunktionen mit Hilfe der PC-Anwendung zu programmieren und zu definieren, müssen Sie die USB-Schnittstelle in eine Serielle konvertieren, da Arduino Pro-Micro kein USB hat. Da die Kommunikation zwischen Geräten auf UART basiert, wird in diesem Projekt das FTDI-Gerät aufgrund seiner einfachen Handhabung unabhängig von seinen zusätzlichen Eigenschaften verwendet.

PC-Anwendung - Python

Wenn es um die Entwicklung von Benutzeroberflächen und schnell zu erstellenden Projekten geht, ist Python eine hervorragende Lösung. Der Zweck der UI-Anwendung ist es, es viel bequemer zu machen, MIDI-Eigenschaften für unser Schlagzeug neu zu definieren, Informationen zu speichern, Geräte zu programmieren und die Kommunikation zwischen den Systemen herzustellen, ohne den Code immer wieder neu kompilieren zu müssen. Da wir eine serielle Schnittstelle zur Kommunikation mit dem Schlagzeug verwenden, gibt es im Internet zahlreiche kostenlose Module, die alle Arten der seriellen Kommunikation unterstützen. Darüber hinaus besteht die UART-Schnittstelle, wie später erläutert wird, aus insgesamt drei Pins: RXD, TXD und DTR. DTR wird verwendet, um das Arduino-Modul zurückzusetzen. Wenn wir also daran interessiert sind, eine MIDI-App auszuführen oder die Benutzeroberfläche mit dem Programmiergerät zu verbinden, müssen Sie das USB-Kabel oder sonstiges nicht erneut anschließen.

Schritt 2: Teile und Instrumente

Teile

  • Roll-Up-Drum-Kit
  • 2 x Sustain-Pedale (normalerweise im DK-Paket enthalten).
  • FTDI - USB-zu-Seriell-Konverter
  • Arduino Pro Micro
  • Micro-USB-Kabel

Instrumente

  • Lötkolben/Station
  • Lötzinn
  • Single-Core-Draht mit dünnem Durchmesser
  • Pinzette
  • Cutter
  • Zange
  • Messer
  • Schraubenzieher
  • 3D-Drucker (Optional - für maßgeschneiderte Pedalplattformen)

Software

  • Arduino-IDE
  • Python 3 oder höher
  • JetBrains Pycharm
  • Haarlose MIDI-Schnittstelle
  • loopMIDI

Schritt 3: Löten und Montage

Löten und Montage
Löten und Montage
Löten und Montage
Löten und Montage
Löten und Montage
Löten und Montage

Da drei Module kombiniert werden müssen, ist der Löt- und Montageprozess kurz und einfach:

  • Verbinden Sie Arduino Pro-Micro mit FTDI-Gerät und stellen Sie sicher, dass die Verbindungen mit den an jedem Gerät definierten I/O übereinstimmen:

    • VBUS-VBUS
    • GND-GND
    • DTR-DTR
    • RXD-TXD
    • TXD-RXD
  • Entfernen Sie alle Schrauben vom Kunststoffgehäuse der Trommel, stellen Sie sicher, dass Sie sich auf das Pad-zu-Board-Kabel und seine Pull-up-Widerstände konzentrieren können
  • Löten Sie dünne Drähte für das Arduino-FTDI-Modul, das wir zuvor konstruiert haben:

    • Digitaleingänge: D[2:11]
    • VBUS
    • D+
    • D-
    • Masse
  • Setzen Sie das Modul in das Batteriegehäuse ein, sodass die Drähte auf derselben Seite wie die Pull-up-Widerstände der Pads schwimmen
  • Löten Sie alle digitalen Eingänge an die Drum-Pad-Anschlüsse, wie in der letzten Abbildung gezeigt.
  • Löten Sie den Micro-USB-Bus (VBUS, D+, D-, GND) an das FTDI-Gerät, stellen Sie sicher, dass diese Drähte nicht fehlerfrei verfolgt werden.
  • Befestigen Sie das Arduino-FTDI-Modul mit Heißkleber am Batteriefach
  • Montage des Gerätes mit entsprechender Schraubenbefestigung

Wir haben es geschafft, Gerät ist montiert. Kommen wir zum Code…

Schritt 4: Programmierung A: Arduino

Programmierung A: Arduino
Programmierung A: Arduino

Lassen Sie uns unsere Skizze Schritt für Schritt beschreiben:

Zunächst müssen zwei notwendige Bibliotheken für den ordnungsgemäßen Betrieb eingebunden werden. EEPROM ist bereits in der Arduino IDE vorinstalliert, aber das Debouncer-Modul für Kick Drum muss separat installiert werden

#einschließen #einschließen

Diese Schalter werden hauptsächlich in Debugging-Sequenzen verwendet. Wenn Sie die Verbindung der Arduino-Klemmen zu den Drum-Pads ausprobieren und alle digitalen Eingänge bestimmen möchten, sollten diese Schalter definiert werden

/* Entwicklerschalter: Gewünschten Modus zum Debuggen oder Initialisieren auskommentieren *///#define LOAD_DEFAULT_VALUES // Konstantenwerte statt EEPROM laden //#define PRINT_PADS_PIN_NUMBERS // Pin-Nummer drucken, die mit einem Pad verbunden ist, das über die serielle Schnittstelle angeschlagen wurde

Konstantenfelder stellen alle Standardwerte dar, einschließlich der Schlagzeug-Pad-Aufzählung. Um das Gerät zum ersten Mal zu betreiben, müssen Sie die genaue Verbindung von Hi-Hat- und Kick-Pedalen kennen

/* Trommeltyp-Aufzählung */

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

/* Standardwerte */

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

/* Dauer der Kickdrum-Entprellung */

const uint8_t KICK_DB_DURATION = 30;

EEPROM wird zum Speichern/Laden aller Daten verwendet, die von der PC-Anwendung stammen. Die oben beschriebene Adressspanne zeigt die genaue Position der MIDI-Informationen für jedes Drum-Pad an

/* Zuordnung der EEPROM-Adressen

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

Pins: |0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13| Geschwindigkeiten |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 Variablen werden verwendet, um den Status jedes Pads zu bestimmen und die MIDI-Kommunikation entsprechend durchzuführen

/* Globale Variablen */

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

uint8_t uartBuffer[64]; // UART-Puffer zum Sammeln und Speichern von MIDI-Daten Debouncer-Kick(DRUM_PINS[KICK], KICK_DB_DURATION); // Debouncer-Objekt für Kick Drum volatile bool previousState[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Vorherige Logikzustände des Drumpads volatile bool currentState[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Aktuelle Logikzustände des Drumpads

EEPROM-Funktionen

/* Einstellungen im EEPROM speichern*/

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

/* Einstellungen vom EEPROM laden*/

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

Initialisierung von Variablen und Programmiermodus, bei Pedalen und Arduino Boot werden gleichzeitig aktiviert

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; sonst charCnt++; } } Serial.println("OK"); speichernEEPROM(); }

void initValues() {

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

MIDI-Kommunikationshandler mit einer Verzögerung von 1 ms Notenhaltezeit

/* MIDI-Notenfunktion abspielen */

void midiOut(enum DRUM_POSITION drumIn) {

if (drumIn == HIHAT) { // Wenn HI-HAT angeschlagen wurde, muss überprüft werden, ob das Pedal gedrückt ist if (!digitalRead(drumPins[HIHAT_PEDAL])) { noteOn(0x90, drumNotes[HIHAT_PEDAL], drumVelocities [HIHAT_PEDAL]); Verzögerung(1); noteOn(0x90, drumNotes[HIHAT_PEDAL], 0); aufrechtzuerhalten. Else { noteOn (0x90, drumNotes[HIHAT], drumVelocities[HIHAT]); Verzögerung(1); noteOn(0x90, drumNotes[HIHAT], 0); } } else { // Regelmäßige Drum-MIDI-Übertragung noteOn(0x90, drumNotes[drumIn], drumVelocities[drumIn]); Verzögerung(1); noteOn(0x90, drumNotes[drumIn], 0); } }

Void noteOn (int cmd, int Pitch, int Velocity) { Serial.write (cmd); Serial.write (Tonhöhe); Serial.write (Geschwindigkeit); }

setup()- und loop()-Funktionen mit unendlicher Geräteoperationsschleife:

Leere Einrichtung () {

Serial.begin(115200);

für (uint8_t i = 0; i < 10; i++) { pinMode (i + 2, INPUT); aufrechtzuerhalten.; Serial.print (i + '0'); // Zahl in ASCII-Zeichen umwandeln } } } #else initValues(); /* Programmiermodus: Wenn beim Booten zwei Pedale gedrückt werden - Modus wird aktiviert */ if (!digitalRead(drumPins[KICK]) && !digitalRead(drumPins[HIHAT_PEDAL])) enterProgrammingMode(); #endif }

Void Schleife () { for (uint8_t i = 1; i < 9; i = i + 1) { currentState = digitalRead (drumPins ); if (!currentState && previousState) midiOut(i); // Zustände vergleichen und fallende Flanke erkennen previousState = currentState; } kick.update(); // Kickdrum verwendet benutzerdefinierten Entprellalgorithmus if (kick.edge()) if (kick.falling()) midiOut(KICK); }

Schritt 5: Programmierung B: Python & Benutzeroberfläche

Programmierung B: Python & Benutzeroberfläche
Programmierung B: Python & Benutzeroberfläche
Programmierung B: Python & Benutzeroberfläche
Programmierung B: Python & Benutzeroberfläche
Programmierung B: Python & Benutzeroberfläche
Programmierung B: Python & Benutzeroberfläche

Die Python-Benutzeroberfläche ist auf den ersten Blick etwas kompliziert zu verstehen, daher würden wir versuchen, ihre Grundlagen zu erklären, wie man sie benutzt, welche Funktion jede Taste hat und wie man Arduino-Geräte richtig programmiert.

Benutzeroberfläche - Anwendung

Die Benutzeroberfläche ist eine grafische Darstellung für unseren Drum-Kit-Programmierer, die es wirklich einfach macht, Arduino-Geräte jederzeit zu programmieren. Die Benutzeroberfläche besteht aus mehreren grafischen Modulen, die an ihre vorgeschlagene Operation gebunden sind. Lassen Sie uns sie einzeln überprüfen:

  1. Drum-Set-Bild: Die Python-Benutzeroberfläche verwendet X-Y-Bildkoordinaten, um zu bestimmen, welcher Trommeltyp ausgewählt wurde. Wenn eine gültige Drum-Region ausgewählt wurde, wird eine sekundäre IO-Meldung mit Feldern für Note, Velocity und Arduino-Terminal für dediziertes Drum-Pad angezeigt. Nachdem diese Parameter vom Benutzer überprüft und freigegeben wurden, können diese Werte direkt an das Arduino-Gerät übertragen werden.
  2. Externes Controller-Image: Um MIDI-Schlagzeug mit einer VST/Musik-Erstellungsumgebung verwenden zu können, muss der Serial-to-MIDI-Interpreter ausgeführt werden. Ich habe Hairless verwendet, das kostenlos erhältlich ist und direkt über unsere Benutzeroberfläche ausgeführt werden kann, indem Sie einfach auf das Bild drücken.
  3. COM-Port-Liste: Um mit Arduino zu kommunizieren, muss der angeschlossene COM-Port angegeben werden. Die Liste wird durch Drücken der Schaltfläche Aktualisieren aktualisiert.
  4. Konfiguration laden/speichern: Im Code sind standardmäßige MIDI-Werte definiert, die vom Benutzer über die Interaktion mit der Benutzeroberfläche geändert werden können. Die Konfiguration wird in der Datei config.txt in einem bestimmten Format definiert, das vom Benutzer gespeichert oder geladen werden kann.
  5. Program Device Button: Um alle geänderten MIDI-Werte im Arduino EEPROM zu speichern, müssen Sie danach zwei Fußpedale (Kick Drum und Hi-Hat-Pedal) drücken und warten, bis die Datenübertragung abgeschlossen ist. Bei Kommunikationsproblemen wird das entsprechende Popup angezeigt. Wenn die Übertragung erfolgreich ist, zeigt die Benutzeroberfläche die erfolgreiche Nachricht an.
  6. Exit-Button: Beenden Sie einfach die Anwendung mit der Erlaubnis des Benutzers.

Python-Code-Highlights

Es passieren viele Dinge im Code, daher werden wir die geschriebenen Funktionen und nicht den gesamten Code erweitern.

Um die Benutzeroberfläche zu verwenden, müssen zunächst mehrere Module heruntergeladen werden, damit der Code funktioniert:

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

Einige der Module sind im Standard-Python-Paket enthalten. Mehrere Module sollten über das PIP-Tool installiert werden:

pip install Kissen

pip install numpy pip install ScreenInfo

Es wird dringend empfohlen, die Anwendung über PyCharm auszuführen. In zukünftigen Versionen plane ich, eine ausführbare Datei für das Projekt zu exportieren.

Kurze Code-Erklärung

Es wird viel einfacher, den Code zu verstehen, wenn wir seine Zeilen aus der Perspektive von Funktionen und Klassen betrachten:

1. Die Hauptfunktion - hier beginnt der Code

if _name_ == '_main_': drumkit_gui()

2. Drum-Kit-Konstanten, Koordinaten und Standard-MIDI-Informationen

class Drums: DRUM_TYPES = ["Kick", "Hihat", "Snare", "Crash 1", "Crash 2", "Tom High", "Tom Mid", "Tom Low", "Ride", "Hihat Pedal ", "Kontrolleur"]

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

KOORDINATEN_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-Funktionen - Umgang mit Benutzeroberfläche und grafischen Objekten

def set_active(ui)

def sekundäre_ui(drum_type)

Klasse SelectionUi(tk. Frame)

Klasse Application(tk. Frame)

def drumkit_gui()

def event_ui_clicked(Ereignis)

def getorigin(selbst, Ereignis)

4. Serielle Kommunikation

def get_serial_ports()

def kommunizieren_mit_arduino(port)

5. Arbeiten mit Dateien: Einstellungen aus der txt-Datei speichern/laden

def save_config()

def load_config()

6. Ausführen der externen Anwendung hairless.exe aus dem Code mit Python-Threading-Funktionen

Klasse ExternalExecutableThread(threading. Thread)

def run_hairless_executable()

Um den Code auszuführen, muss eine Liste von Dateien an den Projektordner angehängt werden:

  • config.txt: Einstellungsdatei
  • hairless.exe: Hairless MIDI-Konverter
  • drumkit.png: Bild, das alle anklickbaren Drum-Pads auf unserer Benutzeroberfläche definiert (muss aus dem Bildersatz dieses Schritts heruntergeladen werden)
  • drumgui.py: Der Projektcode

Das ist alles, was wir betonen müssen, damit es funktioniert. Es ist sehr wichtig, dem Projekt Dateien hinzuzufügen: Drumset-Image, ausführbare Datei hairless.exe und Einstellungsdatei config.txt.

Und.. Hier haben wir es geschafft!:)

Hoffe, Sie finden dieses instructable nützlich.

Danke fürs Lesen!:)

Empfohlen: