MIDIXCV - konwerter MIDI do modułowego syntezatora analogowego

MIDIXCV - konwerter MIDI do modułowego syntezatora analogowego

Modułowy syntezator audio to rodzaj syntezatora muzycznego zbudowanego z oddzielnych modułów pełniących różne funkcje. Moduły te można ze sobą łączyć, układać i konfigurować według potrzeb użytkownika, co daje ogromną elastyczność w tworzeniu różnych dźwięków i efektów dźwiękowych. Moduły te są zazwyczaj montowane na specjalnych panelach przednich, które mają złącza i potencjometry do łączenia i regulacji sygnałów.

Napięcia sterujące w modułowych syntezatorach audio są używane do kontrolowania różnych parametrów dźwięku, takich jak wysokość, głośność, czas trwania obwiedni i inne. Są one przekazywane między modułami w celu zmiany lub modyfikacji parametrów dźwięku. Na przykład napięcie sterujące z klawiatury może kontrolować wysokość dźwięku, a napięcie sterujące generatorem obwiedni może regulować kształt dźwięku w czasie.

Modułowe syntezatory audio pozwalają na tworzenie niemal nieograniczonej liczby brzmień i efektów dźwiękowych, co sprawia, że są popularne wśród muzyków, producentów dźwięku i entuzjastów muzyki elektronicznej. Dzięki napięciu sterującemu (CV) różnymi modułami można eksperymentować z dźwiękiem, tworzyć niestandardowe brzmienia i kontrolować niemal każdy aspekt dźwięku za pomocą elektronicznych modułów. Dlatego też napięcia sterujące są tak ważne w modułowych syntezatorach audio - to one pozwalają na sterowanie działaniem całego systemu. Może ono pochodzić z różnych źródeł - z jednej strony zadawane może być manualnie - potencjometrem-dzielnikiem napięcia, ale może pochodzić również z klawiatur sterujących, sekwencerów czy bardziej zaawansowanych urządzeń. W 2021 roku autor zaprezentowanej konstrukcji opublikował pierwszy projekt dotyczący konwertera MIDI na CV, który jest zdolny generować do czterech napięć kontrolnych i cztery sygnały cyfrowe na podstawie wiadomości MIDI. Zbudowany był wokół mikrokontrolera Arduino Nano i przetwornika DAC MCP4728. Przez lata pełnił funkcję mózgu w jego własnym parafonicznym syntezatorze modułowym, który własnoręcznie zbudował.

Ostatnio dodał do niego kilka funkcji do oprogramowania i niespodziewanie pojawiły się nowe pomysły i wystarczająca motywacja, aby wyjąć ten projekt z szuflady i zacząć coś nowego. Efektem tych prac jest wielokanałowy moduł do generowania napięć kontrolnych z ośmioma wyjściami analogowymi, z dostateczną rozdzielczością, aby obsługiwać dźwięki w różnych skalach muzycznych.

Ale to nie wszystko. Sprzęt, który został opracowany, może być rozszerzony do obsługi aż 32 (trzydziestu dwóch!) sterujących napięć analogowych i czterech sygnałów cyfrowych. Zakres oktaw, który był wcześniej ograniczony do czterech w przypadku konwertera MIDI na CV, został teraz rozszerzony do ośmiu.

Ponieważ oprogramowanie jest w pełni otwarte, kod może być modyfikowany w taki sposób, aby obsługiwać dowolne rodzaje przychodzących wiadomości MIDI (nuta włącz/wyłącz, numer nuty, prędkość, pitch bend, aftertouch, zmiana kontrolna, zmiana programu i tak dalej) i przekształcać je w odpowiednie napięcie za pomocą funkcji definiowanych przez użytkownika.

W artykule opiszemy moduł z ośmioma wyjściami i jego budowę oraz oprogramowanie, a także opiszemy, w jaki sposób łatwo dodać dodatkowe wyjścia analogowe. W dalszej części znajduje się opis sprzętu, który umożliwia uruchomienie takiego systemu, a także opis procedury programowania i kalibracji, bez potrzeby wykorzystania dodatkowych, specjalnych urządzeń.

Na stronie z projektem autor udostępnia wszystkie niezbędne pliki, aby można było wyprodukować potrzebne płytki, które składają się na ten moduł. Udostępnia też wszystkie niezbędne pliki do programowania modułu.

Potrzebne elementy

Oprócz płytek drukowanych potrzebnych jest trochę dodatkowych elementów do wlutowania na nich. Są to głównie złącza i drobne elementy dyskretne. Poniżej wymieniono kluczowe elementy poszczególnych modułów.

Płytka główna

  • 4 × złącza jack np. PJ324M (stereo lub mono),
  • 1 × złącze MIDI DIN 5 (DS-5-01 do montażu na PCB lub DS-5-07A do montażu na panelu),
  • 1 × 12-bitowy DAC MCP4728,
  • 1 × transoptor 6N138,
  • 1 × wzmacniacz operacyjny TL074,
  • 1 × złącze IDC 08x2,
  • 1 × przełączniki DIP-4,
  • diody 1N4004 (1 sztuka) i 1N4148 (1 sztuka),
  • Oporniki: 5 × 1000 Ω, 1 × 220 Ω, 1 × 330 Ω, 2 × 4,7 kΩ, 8 × 10 kΩ,
  • Kondensatory:4 × 100 nF, 2 × 10 μF,
  • Złącza 8 pin i 11 pin.

Płytka analogowa

  • 4 × złącza jack np. PJ324M (stereo lub mono),
  • 1 × 12-bitowy DAC MCP4728,
  • 1 × wzmacniacz operacyjny TL074,
  • Oporniki: 4 × 1000 Ω, 8 × 10 kΩ,
  • Kondensator 100 nF,
  • Złącza i wtyki 8 pin i 11 pin,
  • Złącze 3 pin.

Płytka cyfrowa

  • 4 × złącza jack np. PJ324M (stereo lub mono),
  • 1 × wzmacniacz operacyjny TL074,
  • Oporniki: 4 × 1000 Ω, 8 × 10 kΩ,
  • Kondensator 100 nF,
  • Złącza i wtyki 8 pin i 11 pin (męskie i żeńskie).

Moduł kalibracyjny

  • 4 przyciski,
  • Złącza (męskie) 8 pin i 11 pin.

Hardware

Projekt składa się z trzech płytek drukowanych:

  • Płytka główna
  • Płytka analogowa
  • Płytka cyfrowa

Dodatkowym elementem jest panel przedni, który umożliwia montaż systemu w modułowym syntezatorze. Autor przygotował do tego specjlany panel, do którego dokumentacja jest udostępniona razem z dokumentacją pozostałych płytek drukowanych w tym systemie.

Płytka główna

Ta płytka stanowi serce projektu. Zawiera moduł mikrokontrolera (Arduino NANO 328p), układ wejścia interfejsu MIDI, sekcję filtracji zasilania, cyfrowy stopień przetwarzania sygnału na analogowy oraz stopień wzmocnienia i ochrony wyjść. Płytka ma cztery wyjścia CV. Jeśli nasz projekt nie wymaga więcej, to możemy poprzestać na montażu tylko tego PCB w module.

Złącze MIDI (DIN-5) można bezpośrednio przylutować do tej płytki, ale spowoduje to, że zaprojektowany przez autora panel przedni nie będzie pasował do PCB - autor używa MIDIXCV w ten sposób zamocowanego we własnej obudowie DIY (jest trochę wolnej przestrzeni na dole). Alternatywnie można zastosować zgodny z EuroRack panel przedni, ale konieczne jest użycie innego złącza MIDI (fotografia 1).

Fotografia 1. Płytka główna ze złączem na PCB do montażu w obudowie

Na tej płytce znajduje się wejście MIDI, zrealizowane w klasyczny sposób na pojedynczym transoptorze. Schemat tego wejścia pokazano na rysunku 1. Układ jest zgodny z specyfikacjami MIDI Association.

Rysunek 1. Schemat wejścia MIDI w układzie

Przychodzące wiadomości cyfrowe MIDI muszą zostać przekonwertowane na napięcia analogowe, aby mogły komunikować się w tym samym języku co moduły syntezatora. Funkcję takiego konwertera pełni mikrokontroler w module Arduino NANO328 i przetwornik cyfrowo-analogowy (DAC). Mikrokontroler odbiera wiadomości MIDI i przekształca je w zdefiniowane przez użytkownika informacje w postaci cyfrowej. Następnie są one przesyłane do przetworników DAC za pomocą protokołu komunikacji I²C.

Za konwersję cyfrowych sygnałów na napięcia analogowe odpowiada poczwórny przetwornik DAC MCP4728 o rozdzielczości 12 bitów. Rozdzielczość przetwornika DAC wynosi około 1 mV (z wewnętrznym napięciem odniesienia), a na ostatnim etapie toru sygnałowego za wzmacniaczem spada do 2 mV. To bardzo dobre rozwiązanie sprzętowe dla tego zastosowania, ale także ważna jest dostępność wielu różnych bibliotek do tego przetwornika, co znacząco zwiększa szanse na sukces projektu hobbystycznego (nie zapominajmy o tym).

Zupełnie odrzucono użycie wyjść PWM Arduino we współpracy z (tanimi i łatwymi do zaprojektowania) filtrami RC. Rozwiązanie takie jest wysoce niestabilne (potrzebuje PWM o częstotliwości co najmniej 1 kHz, aby uzyskać sensowną jakość sygnału, a Arduino NANO oferuje mniej niż połowę tej częstotliwości).

Przetwornik MCP4728 może być ustawiony programowo do korzystania z wewnętrznego napięcia odniesienia (stałe napięcie odniesienia 2,048 V) lub zewnętrznego (Vcc). Użycie wewnętrznego napięcia odniesienia ma zaletę stabilnego śledzenia napięcia, ale jest ograniczone do zakresu wyjściowego od 0 do 4,095 V. Oznacza to, że używając wewnętrznego napięcia odniesienia (bez wzmacniacza), mamy do dyspozycji zakres tylko czterech oktaw zamiast pięciu. Napięcie jest jednak bardziej powtarzalne i stabilniejsze przy użyciu wewnętrznego odniesienia. W tym projekcie DSC dla CV wysokości dźwięku używa wewnętrznego odniesienia napięcia DAC, a napięcia są podwajane przez końcowy wzmacniacz, co daje pełny zakres ośmiu oktaw.

Płytka analogowa

Napięcie analogowe - CV - to napięcie, które może przyjmować dowolną wartość w określonym zakresie napięcia (np. od 0 V do 10 V w przypadku typowych syntezatorów modułowych). Płytki analogowe (zauważcie, że jest tutaj liczba mnoga) służą do zwiększenia liczby wyjść analogowych.

Każda płytka analogowa dodaje cztery napięcia sterujące do całkowitej liczby wyjść modułu. Płytki analogowe oczywiście nie mogą działać same z siebie - są przeznaczone do montażu na głównej płytce. Im więcej wyjść analogowych potrzebuje użytkownik, tym więcej płytek analogowych należy ułożyć jedna na drugiej. Na przykład, jeśli w systemie potrzebne jest 8 wyjść CV, zostanie zmontowana i ułożona razem płytka bazowa i jedna płytka analogowa. Dla 12 wyjść trzeba zainstalować dwie płytki analogowe na płytce głównej.

W teorii można ułożyć na głównej płycie do siedmiu dodatkowych płytek analogowych, co oznacza ogólną liczbę trzydziestu dwóch napięć analogowych, ale autor informuje, że użycie więcej niż 12 wyjść nie zostało przetestowane. Konfiguracja 8 wyjść (płytka główna + jedna płytka analogowa) jest optymalną, zdaniem autora, konfiguracją, która była najczęściej testowana.

Każda z płytek analogowych ma kopię układu DAC z płytki głównej. Dzięki temu, że MCP4728 ma programowalny adres, można do pojedynczego interfejsu I²C w mikrokontrolerze podłączyć w teorii dowolną liczbę przetworników DAC.

Wyjścia DACa podłączone są do wzmacniaczy operacyjnych (TL074), które pozwalają na osiągnięcie napięcia 0..10 V (wyjście z DAC, osiąga maksymalnie 5 V). Wzmacniacz operacyjny zapewnia także zabezpieczenie przeciwzwarciowe wyjścia oraz zabezpieczenie przeciwprzepięciowe układu.

Na płytce znajdują się cztery przełączniki DIP. Jeden jest stałe podłączony do linii Rx Arduino i musi być używany do wgrywania nowego oprogramowania. Pozostałe trzy są bezpośrednio połączone z trzema cyfrowymi pinami Arduino i mogą być używane do konfiguracji modułu, np. do aktywacji dodatkowych funkcji i trybów zapisanych w kodzie źródłowym.

Płytka cyfrowa

Sygnały cyfrowe to sygnały używane do przesyłania wiadomości binarnych. Dwie wartości napięcia najczęściej reprezentują dwa stany - "0" i "1" - to 0 V i 5 V (lub 0 V i 3,3 V), ale w świecie modułowych syntezatorów napięcie stanu "1" może sięgać aż do 12 V. Mając to na uwadze, płytka cyfrowa nie była naprawdę konieczna, ponieważ napięcia analogowego można używać (w pewnym zakresie) do kontroli sygnałów cyfrowych. Jednakże płytka analogowa jest trudniejsza do zmontowania i droższa, więc autor zaprojektował osobną płytkę dla wyjść cyfrowych.

Płyta cyfrowa ma maksymalnie cztery niezależne wyjścia cyfrowe. Układanie więcej niż jednej płyty cyfrowej na płycie głównej płycie nie zapewni więcej niż czterech niezależnych wyjść. Wyjścia te również są buforowane za pomocą wzmacniaczy operacyjnych.

Panel przedni

Ten specjalny panel został zaprojektowany do montażu płytki głównej i jednej dodatkowej płytki, dając łącznie osiem wyjść. Większej liczby niż jeden dodatkowy moduł nie da się zmieścić z obecnym panelem przednim, ale teoretycznie można byłoby zaprojektować nowe panele dla większej liczby modułów.
Panel eksponuje osiem wyjść i złącze MIDI IN użytkownikowi pozwala na montaż modułu w typowym syntezatorze modułowym np. w EuroRacku.

Firmware

W swoim syntezatorze autor przyjął najprostszą konfigurację parafoniczną, jaką można sobie wyobrazić, z czterema oscylatorami bezpośrednio podłączonymi do wyjść CV konwertera MIDI. Unikalność tej konfiguracji polega na tym, jak obsługiwane są głosy:

  • Jeśli wciśnięto tylko jeden klawisz (sterowanie MIDI przesyła informacje o klawiszach), to wszystkie głosy mają tę samą wysokość dźwięku (podobnie jak w trybie unisono);
  • Jeśli zostanie wciśnięty dodatkowy klawisz, to dwa z czterech głosów są przypisywane do nowego klawisza;
  • Jeśli trzeci klawisz zostanie dodany, to dwa głosy są wygaszane i przypisywane do nowego klawisza;
  • Jeśli wciśnięte zostaną cztery klawisze, wszystkie oscylatory są niezależnie ustawiane na różne wysokości dźwięku.

Syntezator działa w trybie "ubogiego unisono", jak określa to autor, z zawsze aktywnymi oscylatorami audio. Za każdym razem, gdy naciśnięty zostanie nowy klawisz, sygnał bramki jest ponownie uruchamiany, a co za tym idzie, generowana jest kolejna obwiednia.

Podejście parafoniczne ma dwie zalety w porównaniu z konwencjonalnym:

  • pozwala uniknąć multipleksera / VCA w celu wyciszenia nieużywanych głosów,
  • pozwala używać pojedynczego sygnału bramki zamiast oddzielnych bramek, po jednej dla każdego VCA.
  • dźwięk jest pełniejszy w przypadku mniejszej liczby głosów niż cztery.

Oprogramowanie obsługuje osiem niezależnych wyjść analogowych. Wyjścia są poukładane w następujący sposób:

  • Cztery wyjścia główne płyty są używane do generowania napięć kontrolnych w zależności od otrzymanej wysokości dźwięku MIDI (format V/oktawę, co oznacza, że każdy półton dzieli napięcie 0,83 mV od kolejnego);
  • Wyjścia z płytki analogowej:
    • #1 wysyła sygnały bramki (pojedyncza brama - ustawienie parafoniczne "ubogie unisono"),
    • #2 wysyła napięcie proporcjonalne do ostatniej prędkości dźwięku,
    • #3 wysyła napięcie proporcjonalne do pozycji nuty na klawiaturze,
    • #4 wysyła napięcie proporcjonalne do aftertouch.

Obecne oprogramowanie obsługuje również pitchbend, jednakże nie jest ono przekazywane do CV w domyślnej konfiguracji.

Wszystkie wyjścia głównej płytki mają własną tabelę CV. Oznacza to, że procedura kalibracji (patrz opisany poniżej etap kalibracji) musi być powtórzona cztery razy, po jednym razie dla każdego wyjścia. Analogowe napięcia dla dodatkowych CV są programowo ograniczone do około 5 V, ale można zwiększyć zakres do 8 V, komentując linię:

#define LIMIT_CV w kodzie (co oznacza umieszczenie znaków "//" przed linią lub jej usunięcie).

Przełączniki DIP, w obecnej wersji firmware pozostawione, są nieużywane, z wyjątkiem DIP1. DIP1 jest połączony bezpośrednio z linią Rx Arduino i musi być używany do wgrywania nowego oprogramowania. Aby wgrać nowy program, należy przełączyć DIP1 w pozycję "OFF". Po zakończeniu wgrywania należy przełączyć go ponownie w pozycję "ON", aby odbierać wiadomości MIDI.

Istotne fragmenty firmware pokazane są na listingu 1, a kompletny kod programu znajduje się w repozytorium autora na GitHubie (link na końcu artykułu). Aby skompilować główny program, wymagane są następujące biblioteki zainstalowane w środowisku Arduino IDE:

  • Biblioteka MIDI od FortySevenEffects,
  • Biblioteka MCP4728 autorstwa Benoit Shillingsa.

Linki do pobrania i instalacji bibliotek znajdują się na końcu artykułu.

Należy zauważyć, że stworzony przez autora program jest tylko (w 100% działającym!) programem demonstracyjnym, który ma na celu pokazanie pewnych możliwości układu - takich jakich autor używa w swoim syntezatorze, ale  MIDIXCV ma oczywiście o wiele szersze możliwości i firmware może zostać dostosowane do ich używania.

Listing 1. Kod mikrokontrolera (fragmenty)

#include <MIDI.h>
#include <Wire.h>
#include "mcp4728.h"

// Inicjalizacja obiektu MCP4728, ID = 0
mcp4728 dac0 = mcp4728(0);
// Inicjalizacja obiektu MCP4728, ID = 1
mcp4728 dac1 = mcp4728(1);

#define MAX_VOICES 4
#define MAX_INT_V 97
#define MIDI_CHANNEL 1
#define MIDIOFFSET 24

#define GATE 0
#define VEL 1
#define KBTRACK 2
#define OPEN 2500
#define CLOSED 0
// Ograniczenie napięcia AUX do 5 V
#define LIMIT_CV

const byte LDAC0 = 2;
const byte DIP1 = 10;
const byte DIP2 = 11;
const byte DIP3 = 12;
bool DIP1State;
bool DIP2State;
bool DIP3State;

MIDI_CREATE_DEFAULT_INSTANCE();

int noteCount;
byte lowestNote;
byte highestNote;
int activeSlot;
int pitchbend = 0;
int noteOverflow;
int velVal;
int kbtVal;
int ATVoltage;

byte noteMem[MAX_VOICES];
bool busy[MAX_VOICES];

// Tabela napięć w mV/półton dla DAC #1 (powtarza się dla każdego DAC
const int cv0IntRef[MAX_INT_V] = {
0, 44, 88, 130, 172, 215, 257, 299, 342, 384, 426, 468,
508, 550, 592, 633, 675, 718, 759, 801, 843, 884, 926, 968,
1007, 1049, 1091, 1133, 1174, 1218, 1259, 1301, 1344, 1385, 1426, 1468,
1510, 1551, 1593, 1635, 1677, 1720, 1762, 1803, 1846, 1887, 1929, 1971,
2012, 2053, 2095, 2137, 2179, 2221, 2263, 2304, 2347, 2389, 2431, 2473,
2515, 2554, 2596, 2638, 2680, 2722, 2763, 2805, 2847, 2889, 2931, 2973,
3015, 3056, 3097, 3140, 3181, 3223, 3265, 3307, 3349, 3392, 3434, 3477,
3519, 3560, 3601, 3643, 3685, 3727, 3770, 3812, 3854, 3896, 3938, 3981,
4022
}; //4095 MAX

void setup(){
//DIP switche
pinMode(DIP1, INPUT_PULLUP);
pinMode(DIP2, INPUT_PULLUP);
pinMode(DIP3, INPUT_PULLUP);
DIP1State = digitalRead(DIP1);
DIP2State = digitalRead(DIP2);
DIP3State = digitalRead(DIP3);
//Inicjalizacja MIDI
MIDI.setHandleNoteOn(HandleNoteOn);
MIDI.setHandleNoteOff(HandleNoteOff);
MIDI.setHandlePitchBend(HandlePitchBend);
MIDI.setHandleAfterTouchChannel(HandleAfterTouch);
MIDI.begin(MIDI_CHANNEL);
//Inicjalizacja DAC
pinMode(LDAC0, OUTPUT);
digitalWrite(LDAC0, LOW);
dac0.begin(); // Inicjalizacja Interfejsu I²C
dac1.begin(); // Inicjalizacja Interfejsu I²C
dac0.setPowerDown(0, 0, 0, 0);
dac1.setPowerDown(0, 0, 0, 0);
// Wewnętrzne napięcie odniesienia
dac0.setVref(1,1,1,1);
dac1.setVref(1,1,1,1);
// Wzmocnienie dla napięcia odniesienia
// (0 = x1, 1 = x2)
dac0.setGain(1, 1, 1, 1);
dac1.setGain(1, 1, 1, 1);
// Wyzerowanie wszystkich wyjść
dac0.analogWrite(0, 0, 0, 0);
dac1.analogWrite(0, 0, 0, 0);
// Inicjalizacja zliczania dźwięków
noteCount = 0;
}

void HandleNoteOn(byte channel, byte note, byte velocity) {
noteCount++;
note = note-MIDIOFFSET;
if(note < MAX_INT_V && note>=0){
switch (noteCount){
case 0: //do nothing
break;
// jeden dźwięk - wszystkie głosy takie same,
// analogicznie dalsze przypadki
case 1:
for (int a = 0; a < MAX_VOICES; a++){
noteMem[a] = note;
busy[a] = true;
}
#ifdef LIMIT_CV
velVal = velocity << 3;

kbtVal = note << 3;
#else
velVal = velocity << 4;
kbtVal = note << 4;
#endif
dac1.analogWrite(OPEN, velVal, kbtVal, ATVoltage);
lowestNote = note;
break;
// ponad cztery dźwięki - przekroczona liczba głosów
default:
#ifdef LIMIT_CV
velVal = velocity << 3;
kbtVal = note << 3;
#else
velVal = velocity << 4;
kbtVal = note << 4;
#endif
dac1.analogWrite(CLOSED, velVal, kbtVal, ATVoltage);
for (int n = 0; n < MAX_VOICES; n++){
if (noteMem[n] == lowestNote){
switch(n){
case 0:
noteMem[0] = note;
busy[0] = true;
break;
case 1:
noteMem[1] = note;
busy[1] = true;
break;
case 2:
noteMem[2] = note;
busy[2] = true;
break;
case 3:
noteMem[3] = note;
busy[3] = true;
break;
}
}
}
NoteLowest();
noteCount = MAX_VOICES;
//GATE 1 OPEN to complete the retrigger routine
dac1.analogWrite(GATE, OPEN);
break;
}//switch close
}
dac0.analogWrite(cv0IntRef[noteMem[0]]
+ pitchbend, cv1IntRef[noteMem[1]]
+ pitchbend, cv2IntRef[noteMem[2]]
+ pitchbend, cv3IntRef[noteMem[3]]
+ pitchbend);
}

void HandlePitchBend(byte channel, int bend){
pitchbend = bend>>6;
dac0.analogWrite(cv0IntRef[noteMem[0]]
+ pitchbend, cv1IntRef[noteMem[1]]
+ pitchbend, cv2IntRef[noteMem[2]]
+ pitchbend, cv3IntRef[noteMem[3]]
+ pitchbend);
}

void HandleAfterTouch(byte channel, byte pressure){
#ifdef LIMIT_CV
ATVoltage = pressure << 3;// 255->2040
#else
ATVoltage = pressure << 4;// 255->4080
#endif
dac1.analogWrite(3, ATVoltage);
}

void loop(){
MIDI.read();
}

Kalibracja wyjścia

Chociaż w teorii napięcia do sterowania wysokością dźwięku można łatwo obliczyć, fizyka rzeczywistego świata sprawia, że sprawy stają się bardziej skomplikowane. Dodatkowo, ponieważ nie ma dwóch identycznych komponentów elektronicznych, proces kalibracji jest obowiązkowy, aby układ działał precyzyjnie.

Kalibracja polega na precyzyjnym dostrojeniu wszystkich pojedynczych napięć wyjściowych. W głównym szkicu są one przypisane do liczb od zera do 4095 (12-bitowa). Celem tego procesu jest znalezienie liczby, która zapewni jak najdokładniejsze dopasowanie rzeczywistego napięcia do idealnego napięcia dla każdej pojedynczej półtonacji w obszarze obsługiwanym przez całe oktawy. Kalibracja wymaga dobrego, skalibrowanego woltomierza oraz komputera PC z zainstalowanym Arduino IDE. Wyniki są wyświetlane na żywo przez monitor szeregowy.

Aby skalibrować układ do mikrokontrolera, należy wgrać specjalny szkic. Obsługuje on 4 niezależne wyjścia, z tabelą napięć dla każdego z nich. Oznacza to, że trzeba dostroić 96×4 wartości.

Procedura kalibracji

Aby rozpocząć kalibrację modułu, należy załadować do mikro-kontrolera szkic do kalibracji (MIDIXCV_outs_calibration.ino), dostępny w repozytorium na GitHubie. Następnie pozostawiając moduł podłączony do komputera, uruchamiamy monitor szeregowy w Arduino IDE i podłączamy woltomierz do wyjścia analogowego, które chcemy skalibrować, a następnie:

  1. Zwieramy do masy pole "N+" lub "N-" na głównej płycie, aby zwiększyć lub zmniejszyć numer głosi MIDI, który chcemy dostroić.
  2. Zwieramy do masy pole "V+" lub "V-" na głównej płycie, aby zwiększyć lub zmniejszyć napięcie bieżącego dźwięku MIDI o jeden krok (około 2 mV).
  3. Gdy wszystkie dźwięki zostaną dostrojone, naciskamy "N-", jednocześnie trzymając wciśnięte "N+" (dźwięk +): zostanie wyświetlona na porcie szeregowym pełna tablica.
  4. Należy skopiować i wkleić dane do szkicu MIDIXCV.ino (patrz listing 1), zastępując wartości w tablicy cv0IntRef[MAX_INT_V] dla kanału 0 i tak dalej.
  5. Operacja jest powtarzana dla wszystkich czterech wyjść.
  6. Finalnie wgrywamy zmodyfikowany MIDIXCV.ino z czterema zaktualizowanymi tablicami do Arduino.

Kalibrację należy przeprowadzać z obciążeniem - wejście sterujące modułu VCO to bardzo dobre rozwiązanie, a w razie potrzeby można użyć po prostu opornika 100 kΩ do masy (np. wartość obciążenia w module VCO autora, opartym na AS3340, wynosi 90 kΩ).

Ponieważ procedura kalibracji może być uciążliwa, autor przygotował prostą płytkę z przyciskami kalibracyjnymi w celu ułatwienia pracy. Jej użycie nie jest obowiązkowe, ale znacznie ułatwia pracę.

Domyślnie szkic kalibracji jest ustawiony do kalibracji wyjść urządzenia z identyfikatorem #0, ale można go łatwo dostosować do dowolnych innych możliwych urządzeń (ID# 1 do 7). Jest to unikalne ID dla każdego przetwornika DAC w systemie. W kolejnym kroku opisano sposób konfigurowania tych ID dla poszczególnych modułów.

Konfiguracja płytek analogowych

Aby nadać poszczególnym przetwornikom DAC w systemie unikalne ID, co upraszcza komunikację z mikrokontrolerem, konieczne jest przeprogramowanie ich z unikalnym adresem każdego z nich. Jak zawsze, tak i tutaj społeczność Arduino przychodzi z pomocą i umożliwia operacje takie jak ta, bez konieczności posiadania szerokiej wiedzy i wielkich umiejętności programistycznych. Autor zastosował nieco zmodyfikowany szkic do reprogramowania od Jana Knippera (patrz link na końcu artykułu), aby ułatwić sobie pracę. Wystarczy postępować zgodnie z poniższymi krokami:

  1. Zainstaluj bibliotekę SoftI²CMaster w swoim środowisku Arduino IDE (link do repozytorium z biblioteką na końcu artykułu).
  2. Uruchom szkic do reprogramowania (MIDIXCV_DAC_address_prog.ino) z repozytorium projektu.
  3. Zmień globalną stałą #NEW_ADDRESS na wartość, którą chcesz nadać danemu DAC (jeśli masz tylko jedną płytkę analogową, ustaw ją na "1", w przeciwnym razie użyj indywidualnych wartości dla każdej płyty analogowej).
  4. Połóż na płycie głównej płytę analogową, którą zamierzasz skonfigurować.
  5. Połącz pin "LX" i "L1" za pomocą przewodu połączeniowego (zworki).
  6. Wgraj szkic i uruchom szkic.
  7. Po wgraniu szkicu należy odłączyć zworkę i przywrócić połączenie na pinach "LX" i "L0".

Można przetestować, ile układów DAC o unikalnych adresach jest zainstalowanych, uruchamiając program I²C_Scanner. W monitorze szeregowym program powinien wyświetlić wszystkie informacje - pokazane zostaną unikalne adresy DAC, jakie wygenerowane zostały dla każdego z przetworników DAC.

Podsumowanie

MIDIXCV to ciekawa konstrukcja - konwerter MIDI na napięcie sterujące do modułowego syntezatora analogowego. Powyższy artykuł prezentuje to rozwiązanie, które pozwala na przekształcenie sygnałów MIDI na napięcia kontrolne, które są stosowane w modułowych syntezatorach audio do regulacji parametrów dźwięku. Syntezatory tego rodzaju pozwalają na elastyczne tworzenie różnych brzmień i efektów dźwiękowych poprzez łączenie i konfigurowanie różnych modułów. Dodanie sterowania z pomocą MIDI tylko zwiększa ich możliwości.

W artykule opisano wszystkie aspekty, potrzebne do budowy tego rodzaju urządzenia - hardware układu, z szczególnym naciskiem na przetwornik cyfrowo-analogowy i tor wyjściowy oparty o wzmacniacz operacyjny oraz oprogramowanie i zasada działania w syntezatorze parafonicznym. Dodatkowo dostarczono oprogramowanie do konfiguracji modułów oraz kalibracji poszczególnych kanałów wyjść analogowych.

To, że prezentowane oprogramowanie jest otwarte, pozwala w dowolny sposób je modyfikować i dostosowywać do różnych potrzeb, obsługując różne rodzaje przychodzących wiadomości MIDI i różnego rodzaju algorytmy sterowania syntezatorem. Dzięki temu projektowi entuzjaści muzyki i syntezatorów modułowych DIY mogą tworzyć własne, niestandardowe brzmienia za pomocą modułowego syntezatora audio.

Nikodem Czechowski, EP

Bibliografia:

Artykuł ukazał się w
Elektronika Praktyczna
listopad 2023

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik maj 2024

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio maj - czerwiec 2024

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje maj 2024

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna maj 2024

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich czerwiec 2024

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów