İçindekiler:

Python ve Arduino'da MIDI Davul Kiti: 5 Adım (Resimlerle)
Python ve Arduino'da MIDI Davul Kiti: 5 Adım (Resimlerle)

Video: Python ve Arduino'da MIDI Davul Kiti: 5 Adım (Resimlerle)

Video: Python ve Arduino'da MIDI Davul Kiti: 5 Adım (Resimlerle)
Video: haftalık vb seansı, bol konuşma az kod 2024, Aralık
Anonim
Image
Image
Python ve Arduino'da MIDI Davul Kiti
Python ve Arduino'da MIDI Davul Kiti
Python ve Arduino'da MIDI Davul Kiti
Python ve Arduino'da MIDI Davul Kiti

Çocukluğumdan beri hep bir bateri seti almak istemişimdir. O zamanlar, bugün elimizde bol miktarda olduğu için tüm müzik ekipmanlarının tüm dijital uygulamaları yoktu, bu nedenle fiyatlar ve beklentiler çok yüksekti. Son zamanlarda eBay'den en ucuz bateri setini almaya karar verdim, tek önceliğim: Onu parçalayıp kendi donanım ve yazılımımı cihaza bağlayabilme.

Satın alma hiç de hayal kırıklığı yaratmadı: 9 farklı ses pedli portatif roll-up bateri seti, kick davul ve hi-hat için iki ayak pedalı ve mikro USB güç soketi. Gerçekten moral bozucu olan şey, çıkış sesleridir (Bu kitin asıl kullanımı harici hoparlörü bağlayıp keyfini çıkarmaktır). Bu yüzden, kullanışlı kullanım ve hacim, nota ve kanal seçimleri gibi kolay değişiklikler için USB, Arduino tabanlı MIDI bateri seti ve Python tabanlı Kullanıcı Arayüzü aracılığıyla kendi programlanabilirime dönüştürmeye karar verdim.

Cihazın özellikleri:

  • Düşük fiyat
  • Herhangi bir dijital girişten bateri seti oluşturma - hatta bir dizi basma düğmesi
  • Yalnızca USB arabirimi üzerinden iletişim desteği ve güç kaynağı - USB'nin UART dönüştürücüye ve Arduino cihazına entegrasyonu
  • Düzgün çalışma için minimum parçalar
  • Kullanımı kolay Python tabanlı kullanıcı arayüzü
  • Ayarlanabilir hız, nota ve Arduino pinleri ile eksiksiz MIDI desteği
  • Cihazın hafızasında saklanan özel davul konfigürasyonlarını Kaydet ve Yükle

Gelelim projeye…

Adım 1: Çalışma Teorisi

Operasyon teorisi
Operasyon teorisi
Operasyon teorisi
Operasyon teorisi
Operasyon teorisi
Operasyon teorisi

Blok Şeması

Öncelikle proje yapısına odaklanalım ve onu ayrı bloklara ayıralım:

Roll-Up Davul Seti

Projenin ana birimi. 9 ayrı bateri pedinden oluşur; her ped, vurulduğunda mantık durumlarını değiştiren bir dizi düğmedir. Yapısı nedeniyle, bu özel bateri kitini herhangi bir basmalı düğmeden oluşturma olasılığı vardır. Her bateri pedi ana elektronik kart üzerindeki pull-up direncine bağlıdır, böylece bateri pedine defalarca vurulurken, devrenin toprağına özel bir anahtar bağlanır ve bateri pedi hattında mantıksal LOW bulunur. Basınç uygulanmadığında, bateri pedi anahtarı açıktır ve güç hattına çekme direnci nedeniyle, bateri pedi hattında mantıksal YÜKSEK mevcuttur. Projenin amacı tam bir dijital MIDI cihazı oluşturmak olduğundan, ana PCB üzerindeki tüm analog parçalar ihmal edilebilir. Davul setinin kick davul ve hi-hat için iki pedalı olduğunu ve bu pedalların da pull-up dirençlerine bağlı olduğunu ve tüm bateri pedleri ile aynı çalışma mantığını paylaştığını fark etmek önemlidir (Bunu biraz sonra tartışacağız).).

Arduino Pro-Mikro

Davul setinin beyni. Amacı, bir davul pedinden gelen bir sinyal olup olmadığını tespit etmek ve gerekli tüm parametrelerle uygun MIDI çıkışı sağlamaktır: Not, hız ve sinyal süresi. Davul pedlerinin dijital doğası nedeniyle, arduino dijital girişlerine kolayca bağlanabilirler (toplam 10 pin). İstenen tüm ayarları ve MIDI bilgilerini depolamak için hafızasını - EEPROM'u kullanacağız, bu nedenle cihazı her çalıştırdığımızda, MIDI bilgisi EEPROM'dan yükleniyor, yeniden programlanabilir ve yeniden yapılandırılabilir hale geliyor. Ayrıca Arduino Pro-Micro çok küçük bir pakette mevcuttur ve bateri seti iç kasasına kolayca tahsis edilebilir.

FTDI USB'den Seri Dönüştürücüye

PC uygulaması yardımıyla cihaz özelliklerimizi programlamak ve tanımlamak için Arduino Pro-Micro'nun USB'si olmadığı için USB arayüzünü seri hale getirmemiz gerekiyor. Cihazlar arasındaki iletişim UART'a dayandığından, ek özelliklerinden bağımsız olarak kullanım kolaylığı nedeniyle bu projede FTDI cihazı kullanılmıştır.

PC Uygulaması - Python

Kullanıcı arayüzlerinin ve hızlı inşa edilen projelerin geliştirilmesi söz konusu olduğunda, Python mükemmel bir çözümdür. UI uygulamasının amacı, bateri kitimiz için MIDI özelliklerini yeniden tanımlamayı, bilgileri saklamayı, cihazı programlamayı ve tekrar tekrar kod derlemeye gerek kalmadan sistemler arasında iletişim kurmayı çok daha uygun hale getirmektir. Bateri seti ile iletişim kurmak için seri arayüz kullandığımız için, internetin her yerinde her türlü seri iletişimi destekleyen birçok ücretsiz modül bulunmaktadır. Ayrıca, daha sonra tartışılacağı gibi, UART arayüzü toplam üç pinden oluşmaktadır: RXD, TXD ve DTR. DTR, Arduino modülünde sıfırlama yapmak için kullanılır, bu nedenle MIDI uygulamasını çalıştırmak veya UI'yi program cihazına bağlamakla ilgilendiğimizde, kesinlikle USB kablosunu veya herhangi bir şeyi yeniden takmaya gerek yoktur.

Adım 2: Parçalar ve Enstrümanlar

Parçalar

  • Roll-Up Davul Seti
  • 2 x Sürdürme Pedalı (Genellikle DK paketine dahildir).
  • FTDI - USB'den Seri Dönüştürücüye
  • Arduino Pro Mikro
  • Mikro USB Kablosu

Enstrümanlar

  • Havya/İstasyon
  • Lehimleme Kalay
  • İnce Çaplı Tek Çekirdekli tel
  • Cımbız
  • Kesici
  • pense
  • Bıçak
  • Tornavida
  • 3D Yazıcı (Opsiyonel - özelleştirilmiş pedal platformları için)

Yazılım

  • Arduino IDE'si
  • Python 3 veya Üzeri
  • JetBrains Pycharm
  • Tüysüz MIDI arayüzü
  • döngüMIDI

Adım 3: Lehimleme ve Montaj

Lehimleme ve Montaj
Lehimleme ve Montaj
Lehimleme ve Montaj
Lehimleme ve Montaj
Lehimleme ve Montaj
Lehimleme ve Montaj

Birleştirilmesi gereken üç modül olduğundan, lehimleme ve montaj işlemi kısa ve basittir:

  • Arduino Pro-Micro'yu FTDI cihazıyla birbirine bağlayın, bağlantıların her cihazda tanımlanan G/Ç ile uyumlu olduğundan emin olun:

    • VBUS-VBUS
    • GND-GND
    • DTR-DTR
    • RXD-TXD
    • TXD-RXD
  • Tambur plastik muhafazasındaki tüm vidaları çıkarın, pedden karta kabloya ve çekme dirençlerine odaklanabildiğinizden emin olun.
  • Daha önce oluşturduğumuz Arduino-FTDI modülü için ince telleri lehimleyin:

    • Dijital girişler: D[2:11]
    • VBUS
    • D+
    • NS-
    • GND
  • Modülü pil kutusunun içine yerleştirin, böylece teller pedlerin çekme dirençleri ile aynı tarafta yüzer.
  • Son şekilde gösterildiği gibi tüm dijital girişleri bateri pedi terminallerine lehimleyin.
  • Mikro-USB veri yolunu (VBUS, D+, D-, GND) FTDI cihazına lehimleyin, bu kabloları izlerken herhangi bir hata olmadığından emin olun.
  • Arduino-FTDI modülünü sıcak tutkalla pil kutusuna takın
  • Cihazı uygun vida ataşmanı ile monte edin

Yaptık, cihaz monte edildi. Kodlamaya devam edelim…

Adım 4: Programlama A: Arduino

Programlama A: Arduino
Programlama A: Arduino

Çizimimizi adım adım açıklayalım:

Her şeyden önce, düzgün çalışması için gerekli iki kütüphaneyi içermesi gerekir. EEPROM, Arduino IDE'de önceden kuruludur, ancak kick davul için geri dönüş modülünün ayrı olarak kurulması gerekir

#include #include

Bu anahtarlar çoğunlukla hata ayıklama dizilerinde kullanılır. Arduino terminallerinin bateri pedlerine bağlantısını denemek ve tüm dijital girişleri belirlemek istiyorsanız, bu anahtarlar tanımlanmalıdır

/* Geliştirici Anahtarları: Hata ayıklama veya başlatma için istenen modun yorumunu kaldırın *///#define LOAD_DEFAULT_VALUES // EEPROM yerine sabit değerleri yükleyin //#define PRINT_PADS_PIN_NUMBERS // Seri port üzerinden vurulan bir pede bağlı pin numarasını yazdırın

Sabit alanlar, bateri pedi numaralandırması dahil tüm varsayılan değerleri temsil eder. Cihazı ilk kez çalıştırabilmek için Hi-Hat ve Kick pedallarının tam olarak bağlantısının bilinmesi gerekmektedir

/* Davul tipi numaralandırma */

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

/* Varsayılan değerler */

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

/* Tekme davulunun geri tepme süresi */

const uint8_t KICK_DB_DURATION = 30;

EEPROM, PC uygulamasından gelen tüm verileri depolamak/yüklemek için kullanılır. Yukarıda açıklanan adres aralığı, her bateri pedi için MIDI bilgisinin tam yerini gösterir

/* EEPROM Adres eşlemesi

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

Pinler: |0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13| Hızlar |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;

Global değişkenler, her pedin durumunu belirlemek ve buna göre MIDI iletişimini gerçekleştirmek için kullanılır

/* Global Değişkenler */

uint8_t drumNotes[10], drumVelocities[10], drumPins[10]; // MIDI Değişkenleri

uint8_t uartBuffer[64]; // MIDI Veri Engelleyicisi kick(DRUM_PINS[KICK], KICK_DB_DURATION) toplamak ve depolamak için UART Tamponu; // Kick drum volatile bool için geri tepme nesnesi öncekiState[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Davul pedi önceki mantık durumları volatile bool currentState[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // Davul pedinin geçerli mantık durumları

EEPROM İşlevleri

/* Ayarları EEPROM'da saklayın*/

void storeEEPROM() {

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

/* EEPROM'dan ayarları yükle*/

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

Pedallar ve Arduino önyüklemesi durumunda değişkenlerin ve programlama modunun başlatılması aynı anda etkinleştirilir

geçersiz enterProgrammingMode() {

bool ConfirmBreak = false; uint8_t lineCnt = 0; uint8_t charCnt = 0; karakter okumaChar = 0; while(!confirmBreak) { if (Serial.available()) { uartBuffer[charCnt] = Serial.read(); if (charCnt >= 29) ConfirmBreak = true; yoksa charCnt++; } } Serial.println("Tamam"); mağazaEEPROM(); }

geçersiz initValues() {

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

1 ms not tutma süresi gecikmeli MIDI İletişim işleyicileri

/* MIDI nota işlevini çal */

void midiOut(enum DRUM_POSITION drumIn) {

if (drumIn == HIHAT) { // HI-HAT'a basıldıysa, pedala basılıp basılmadığının kontrol edilmesi gerekir if (!digitalRead(drumPins[HIHAT_PEDAL])) { noteOn(0x90, drumNotes[HIHAT_PEDAL], drumVelocities [HIHAT_PEDAL]); gecikme(1); noteOn(0x90, drumNotes[HIHAT_PEDAL], 0); } else { noteOn(0x90, drumNotes[HIHAT], drumVelocities[HIHAT]); gecikme(1); noteOn(0x90, drumNotes[HIHAT], 0); } } else { // Normal davul MIDI aktarım noteOn(0x90, drumNotes[drumIn], drumVelocities[drumIn]); gecikme(1); noteOn(0x90, drumNotes[drumIn], 0); } }

void noteOn(int cmd, int adım, int hız) { Serial.write(cmd); Serial.write(perde); Serial.write(hız); }

sonsuz cihaz işlem döngüsü ile setup() ve loop() işlevleri:

geçersiz kurulum() {

Seri.başla(115200);

for (uint8_t i = 0; i < 10; i++) { pinMode(i + 2, INPUT); } #ifdef PRINT_PADS_PIN_NUMBERS while(true) { // Sonsuz hata ayıklama döngüsü for (uint8_t i = 0; i < 10; i++) { if (!digitalRead(i + 2)) { Serial.print("Pin No: D"); Serial.print(i + '0'); // Sayıyı ASCII karakterine çevir } } } #else initValues(); /* Programlama modu: Önyükleme sırasında iki pedala basılırsa - mod etkinleştirilir */ if (!digitalRead(drumPins[KICK]) && !digitalRead(drumPins[HIHAT_PEDAL])) enterProgrammingMode(); #endif }

void loop() { for (uint8_t i = 1; i < 9; i = i + 1) { currentState = digitalRead(drumPins); if (!currentState && öncekiState) midiOut(i); // Durumları karşılaştır ve düşen kenarı tespit et öncekiState = currentState; } kick.güncelleme(); // Kick davul özel geri dönme algoritması kullanır if (kick.edge()) if (kick.falling()) midiOut(KICK); }

Adım 5: Programlama B: Python ve Kullanıcı Arayüzü

Programlama B: Python ve Kullanıcı Arayüzü
Programlama B: Python ve Kullanıcı Arayüzü
Programlama B: Python ve Kullanıcı Arayüzü
Programlama B: Python ve Kullanıcı Arayüzü
Programlama B: Python ve Kullanıcı Arayüzü
Programlama B: Python ve Kullanıcı Arayüzü

Python Kullanıcı Arayüzü ilk bakışta anlaşılması biraz karmaşıktır, bu nedenle temellerini, nasıl kullanılacağını, her düğmenin hangi işlevi olduğunu ve Arduino cihazının nasıl düzgün programlanacağını açıklamaya çalışacağız.

Kullanıcı Arayüzü - Uygulama

UI, bateri seti programlayıcımız için grafiksel bir temsil olup, Arduino cihazını herhangi bir zamanda programlamayı gerçekten kolay ve kullanışlı hale getirir. Kullanıcı arabirimi, önerilen işlemlerine bağlı birkaç grafik modülden oluşur. bunları tek tek gözden geçirelim:

  1. Drum Set Image: Python UI, hangi davul tipinin seçildiğini belirlemek için X-Y görüntü koordinatlarını kullanır. Geçerli tambur bölgesi seçildiyse, nota alanları, hız ve özel bateri pedi için Arduino terminali ile birlikte ikincil IO mesajı görüntülenir. Bu parametreler kullanıcı tarafından doğrulanıp onaylandıktan sonra bu değerler doğrudan Arduino cihazına iletilebilir.
  2. Harici Kontrolör Görüntüsü: MIDI bateri kitini VST/Müzik oluşturma ortamı ile kullanabilmek için Seri-MIDI yorumlayıcısını çalıştırmaya ihtiyaç vardır. Ücretsiz olarak sunulan ve sadece görüntüsüne basarak doğrudan kullanıcı arayüzümüzden çalıştırılabilen Hairless'ı kullandım.
  3. COM Port Listesi: Arduino ile haberleşebilmek için bağlı olduğu COM portunu belirtmeniz gerekmektedir. Yenile butonuna basılarak liste yenilenmektedir.
  4. Konfigürasyonu Yükle/Kaydet: Kodda tanımlanan, kullanıcı tarafından UI ile etkileşim yoluyla değiştirilebilen varsayılan MIDI değerleri vardır. Yapılandırma, config.txt dosyasında, kullanıcı tarafından kaydedilebilen veya yüklenebilen belirli bir biçimde tanımlanır.
  5. Program Cihaz Düğmesi: Modifiye edilmiş tüm MIDI değerlerini Arduino EEPROM'da saklamak için iki ayak pedalına (Kick davul ve Hi-hat pedalı) basmak ve ardından veri aktarımının tamamlanmasını beklemek gerekir. Herhangi bir iletişim sorunu varsa, uygun açılır pencere gösterilecektir. İletim başarılı olursa, kullanıcı arayüzü başarılı mesajını gösterecektir.
  6. Çıkış Düğmesi: Kullanıcının izniyle uygulamadan çıkmanız yeterlidir.

Python Kodunda Öne Çıkanlar

Kodda pek çok şey oluyor, bu yüzden kodun tamamından ziyade yazılı fonksiyonları genişleteceğiz.

Her şeyden önce, UI'yi kullanmak için, kodun çalışması için birkaç modül indirmeniz gerekir:

osimport iş parçacığını içe aktar tkinter'ı tk olarak içe aktar tkinter'dan ileti kutusunu içe aktar PIL'den içe aktar * ImageTk, Görüntü numpy'yi np olarak içe aktar seri içe aktarma globunu içe aktar

Bazı modüller varsayılan Python paketine dahil edilmiştir. PIP aracı aracılığıyla birkaç modül kurulmalıdır:

pip yükleme Yastık

pip kurulumu numpy pip kurulumu ScreenInfo

Uygulamayı PyCharm aracılığıyla çalıştırmanız şiddetle tavsiye edilir. Gelecekteki sürümlerde, proje için bir yürütülebilir dosyayı dışa aktarmayı planlıyorum.

Kısa Kod Açıklaması

Satırlarına işlevler ve sınıflar açısından bakarsak, kodu anlamak çok daha kolay olacaktır:

1. Ana işlev - burada kod başlar

if _name_ == '_main_': drumkit_gui()

2. Bateri Kiti sabitleri, koordinatlar ve varsayılan MIDI bilgileri

sınıf Davullar: DRUM_TYPES = ["Kick", "Hihat", "Snare", "Crash 1", "Crash 2", "Tom High", "Tom Mid", "Tom Low", "Ride", "Hihat Pedal ", "Kontrolör"]

KOORDİNATLAR_X = [323, 117, 205, 173, 565, 271, 386, 488, 487, 135, 79]

KOORDİNATLAR_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", "Tuzak", "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_HIZLAR = [110, 100, 100, 110, 110, 110, 110, 110, 110, 110] DRUM_PINS = [8, 6, 4, 3, 11, 9, 5, 10, 2, 7]

3. UI İşlevleri - Kullanıcı arabiriminin ve grafik nesnelerin işlenmesi

def set_active(ui)

def ikincil_ui(davul_türü)

sınıf SelectionUi(tk. Frame)

sınıf Uygulama(tk. Frame)

def drumkit_gui()

def event_ui_clicked(event)

def getorigin(kendi, olay)

4. Seri iletişim

def get_serial_ports()

def iletişim_with_arduino(bağlantı noktası)

5. Dosyalarla çalışma: Ayarları txt dosyasından saklayın/yükleyin

def save_config()

def load_config()

6. Python Threading yeteneklerini kullanarak harici bir uygulama hairless.exe'yi koddan çalıştırma

sınıf ExternalExecutableThread(threading. Thread)

def run_hairless_executable()

Kodu çalıştırmak için proje klasörüne eklenmesi gereken dosyaların bir listesi vardır:

  • config.txt: Ayarlar dosyası
  • hairless.exe: Tüysüz MIDI dönüştürücü
  • drumkit.png: Kullanıcı arayüzümüzdeki tıklanabilir tüm bateri pedlerini tanımlayan resim (Bu adımdan indirilmelidir' resim setinden)
  • drumgui.py: Proje kodu

Çalışması için vurgulamamız gereken her şey bu. Projeye dosya eklemek çok önemlidir: davul seti görüntüsü, hairless.exe yürütülebilir dosyası ve ayarlar dosyası config.txt.

Ve.. İşte başardık!:)

Umarım bu talimatı faydalı bulursunuz.

Okuduğunuz için teşekkürler!:)

Önerilen: