[088] Przejmowanie kontroli nad urządzeniami - multiefekt gitarowy - cz. 1

[088] Przejmowanie kontroli nad urządzeniami - multiefekt gitarowy - cz. 1

Kontynuując temat przejmowania kontroli nad urządzeniami, które nie posiadają żadnych interfejsów z wyjątkiem panela użytkownika, czas na coś bardziej użytecznego, acz może nie dla każdego: będziemy się włamywać do multiefektu gitarowego. Na wstępie – czym jest multiefekt? Urządzenia do modyfikowania dźwięku gitar, ale też głosu, syntezatorów czy czegokolwiek, co podłączymy do wejścia, są bardzo popularne wśród muzyków i w zasadzie obowiązkowe, poza sytuacjami uprawiania muzyki „unplug”. Postęp techniczny sprawił, że multiefekty są dziś doskonałe i generalnie tanie, ale markowe, a do tego z wygodnym interfejsem – niekoniecznie. W tym systemie jest furtka: wszyscy czołowi producenci mają w ofercie urządzenia naprawdę tanie, o brzmieniu przyzwoitym, ale niewygodne w użytkowaniu. W zasadzie da się je programować w domowym zaciszu, na scenie nie ma na to warunków ze względu na skromny interfejs.


Rzućmy okiem – tutaj wszystko jest pod ręką i jeden ruch dłonią wprowadza korektę. Ale to kosztuje. W kilkukrotnie tańszym odpowiedniku pozbawionym gałek mamy podobne brzmienia, ale już ich zmiana wymaga klikania trwającego wieki. Czy da się coś z tym zrobić?

Owszem. I nie tylko po to, by robić z bieda-efektów urządzenia udające profesjonalne. Brać muzyczna lubi dłubać sobie własne wersje wspomagaczy talentu i tam tuning jest co najmniej równie popularny jak w innych branżach. Toteż takie przeróbki wykonuje się na porządku dziennym, niekoniecznie po to, by mieć coś droższego w cenie niskiej, ale też by mieć coś unikatowego. Pozostawmy więc sens czynienia takich układów otwartym, bo zastosowań może być multum i przeprowadźmy proces przejmowania kontroli na przykładzie prościutkiego multiedektu DigiTecha, który wciąż jest produkowany, choć ma już kilka lat. Dodam od razu, że cały ten cykl nie ma na celu dokonania przeróbek tego konkretnie efektu, a poznania metod i przyjrzenia się, jak je implementować w konkretnych przypadkach.

Urządzenie nie ma ani jednej gałki, a wszelkie edycje wykonuje się za pomocą czterech przycisków. Jedna para (EDIT) porusza się po menu oznaczonym na górze diodami świecącymi, druga (VALUE) – zmienia wartość parametrów, wyświetlając ją na prostym wyświetlaczu z dwoma ósemkami. Czasem są to cyfry, czasem jakieś mało zrozumiałe znaki, które trzeba tłumaczyć z instrukcji. Poza tym mamy tutaj możliwość zapisania wszystkich nastaw (STORE) i przycisk obsługujący perkusyjny metronom (DRUMS) oraz duże przyciski, zmieniające zapisane wcześniej programy. Zapis pozostawimy w spokoju, podobnie jak maszynę perkusyjną. Zajmiemy się stworzeniem baterii gałek, które będą się odwoływać bezpośrednio do wybranych elementów multiefektu.

Co to może? Mamy następujące elementy: głośność ogólną, głośność zapisanego programu (PRESET LEVEL), symulator przystawki i efektu kaczki (PICKUP WAH), kompresor (COMPRESSOR), symulator pieca gitarowego (AMP MODEL), bramkę szumów (NOISE GATE), trójpasmowy korektor (EQ), baterię efektów modulacyjnych (CHORUS MOD), przy czym możemy wybrać jeden, echo (DELAY) – tutaj wybieramy typ oraz czas między powtórzeniami i pogłos (REVERB). Czyli razem 10 elementów, nie licząc głośności ogólnej i zapisanej z programem.

W wersji maksimum możemy więc stworzyć panel 11 gałek (nie widzę sensu dublować głośności). Problem w tym, że Arduino Uno ma tylko sześć wejść analogowych. Na końcu powiększę baterię do ośmiu gałek, używając modułu Nano. Kto chce mieć więcej, musi sięgnąć po moduł Mega bądź inne mikrokontrolery zgodne z Arduino albo będzie musiał rozmnożyć kanały za pomocą np. układu 4067, o którym kiedyś napiszę. Postanowiłem na razie pozostać w wersji minimum, czyli wybierzemy sobie sześć parametrów: będą to: korekcja basów, korekcja sopranów, wybór modulatora, typ echa, czas odbić i typ pogłosu. Potem dołożymy jeszcze kompresor i przestery.

Zastanówmy się nad „logiką minimum”: co będziemy musieli obsługiwać? Na pewno parę przycisków VALUE, gdyż one umożliwiają zmianę parametrów, jeden w górę, drugi – w dół. A także parę EDIT, bo pozwala zmianę elementu, któremu zmienia się parametry. Spójrzmy jednak jak działają te ostatnie: trzymając dowolny z nich bez końca, będziemy przeskakiwać z ostatniego parametru na pierwszy i odwrotnie (diody wskazujące wybrany efekt będą się przesuwać bez końca w prawo bądź w lewo). Znaczy to, że moglibyśmy zrezygnować z jednego z tych przycisków, przeskakując do wybranych pozycji zawsze w jednym kierunku. Co prawda może się zdarzyć, że skok do parametru sąsiadującego może wymagać aż dwanaście wciśnięć, ale jeśli będziemy to robić szybko, nie będzie to problemem. To znaczy jeśli będzie to robić Arduino, a nie my. Podejmujemy więc decyzję: podkradamy się pod przyciski regulujące nastawy (VALUE) i jeden z wybierających parametr (EDIT). Wybrałem ten, który się cofa, czyli lewy.

Na temat realizacji sprzętowej tego rozwiązania pisałem w poprzednich artykułach. W skrócie: zwarcia przycisków będę realizował transoptorami. Tym razem nie było żadnych problemów, użyłem miniaturowych transoptorów w obudowach czteronóżkowych.

Prawdę powiedziawszy, wygląda to jak wygląda, ponieważ projekt ten zrealizowałem siedem lat temu, a potem zastąpił go inny, więc efekt wraz z tak podłączonymi transoptorami przezimował w szufladzie, lecz dzięki temu miałem teraz mniej pracy. Najważniejsze, że całość zmieściła się pod klapką baterii i z efektu będzie teraz wychodzić tylko wiązka czterech przewodów: wspólnej masy i trzech połączeń prowadzących do diod świecących transoptorów. Oczywiście to jest wersja doświadczalna wykonania, docelowo należałoby to zorganizować w sposób niezawodny i estetyczny.

Jak poprzednio, wypada teraz podać tu napięcie pięć woltów i sprawdzić, czy za każdym razem zmieniają się parametry i element z menu. Jeśli wszystko jest w porządku – połowę części sprzętowej mamy załatwioną. Podłączamy się pod płytkę edukacyjną TME na piny: 10, 11 i 12

Ale to nie koniec. Na płytce mam jeden potencjometr, a potrzebuję sześciu. Cóż, trzeba zbudować kolejną pomoc naukową. I tutaj taka moja dygresja. Tymczasowość rządzi w świecie elektroników, dlatego dobrze wypracować umiejętność projektowania takich tymczasowych rozwiązań, by się nie narobić, ale nie obcować z bylejakością. Wbrew pozorom karton może być przyjacielem elektronika.

Z tegoż wyciąłem sobie taki kształt w ten sposób, by ujarzmił baterię potencjometrów, czyniąc nastawy wygodnymi i jednocześnie był łatwy do wykonania. Szczegóły nie są skomplikowane: osiem potencjometrów (z zapasem na dodatki, o których wspominałem) łączymy w ten sposób, że skrajne wyprowadzenia mają połączenie „każde z każdym”, a ślizgacze wyprowadzamy osobnymi przewodami. Patrząc z tyłu potencjometów, prawe wyprowadzenia łączymy z masą, lewe – z pięcioma woltami. Warto dodać kondensatory gaszące szumy między ślizgacze, a masę i dodatkowy, na linii zasilającej. Dobrze też wykleić wnętrze folią aluminiową, by zredukować zbieranie zakłóceń i podłączyć ją do masy.

Manipulator ten, nota bene wygodny i zaskakująco trwały, łączymy z płytką, tym razem wstawiając wyjścia ze ślizgaczy na wejścia analogowe. Pierwsze dwa potencjometry na razie zostaną niepodłączone. Nie można także zapomnieć o podłączeniu zasilania. Trzeba teraz sprawdzić czy to działa. Napiszemy sobie prosty, tymczasowy szkic.

const byte potencjometrBAS = A0;  // Adresy portów potencjometrów.
const byte potencjometrTRE = A1;
const byte potencjometrMOD = A2;
const byte potencjometrDEL = A3;
const byte potencjometrTIM = A4;
const byte potencjometrREV = A5;

void setup() {
  Serial.begin(115200);  // Inicjacja obsługi monitora.
}
void loop() {
  Serial.print(analogRead(potencjometrBAS));  // Zmierz wartość napięcia ze ślizgacza potencjometru i wyślij ją do komputera.
  Serial.print("\t");                         // Wyślij tablulator.
  Serial.print(analogRead(potencjometrTRE));
  Serial.print("\t");
  Serial.print(analogRead(potencjometrMOD));
  Serial.print("\t");
  Serial.print(analogRead(potencjometrDEL));
  Serial.print("\t");
  Serial.print(analogRead(potencjometrTIM));
  Serial.print("\t");
  Serial.print(analogRead(potencjometrREV));
  Serial.println();
  delay(100);
}

Użyję nazw związanych z multiefektem, ograniczając się do trzech dużych liter. Da nam to przejrzystość podczas późniejszych działań. Deklarujemy wszystkie możliwe wejścia analogowe i aktywujemy działanie monitora. W głównej pętli po kolei będziemy sczytywać wartości z tych wejść i wysyłać je, formując w paczki dzielone tabulatorami. Dzięki temu zachowamy przejrzystość. Warto dodać funkcję delay celem wstrzymania potoku danych.

Spójrzmy na ów potok. Kręcąc gałkami uzyskamy wartości od zera do 1023 – zgodnie z oczekiwaniami. Problem w tym, że czasem nie będziemy niczego dotykać, a wartości będą się zmieniać same. To naturalne, jeśli potencjometr ustawi się blisko progu przełączenia przetwornika, będzie odczytywany raz niżej, raz wyżej i nie będzie żadnej reguły co do takiego działania. Bywa, że to nie ma znaczenia, ale częściej ma, a w naszym przypadku będzie mieć bardzo poważne, o czym przekonamy się później. Trzeba coś z tym zrobić.

const byte potencjometrBAS = A0;  // Adres portu potencjometru.
int wartoscBAS = 0;               // Wartość odczytanego napięcia pochodzącego ze ślizgacza potencjometru.
int zmianaBAS = 0;                // Tymczasowa wartość odczytanego napięcia do porównań.
bool aktywnyBAS = false;          // Wskaźnik ustawiany po wykryciu zmiany położenia potencjometru.

void setup() {
  Serial.begin(115200);  // Inicjacja obsługi monitora.
}
void loop() {

  // ODCZYT
  zmianaBAS = analogRead(potencjometrBAS);  // Odczytaj wartość napięcia ze ślizgacza potencjometru.
  if (abs(wartoscBAS - zmianaBAS) > 3) {    // Jeśli odczytana wartość jest większa od 3 od wartości poprzedniej...
    wartoscBAS = zmianaBAS;                 // Uaktualnij wartość napięcia dla pozostałych modułów programu.
    aktywnyBAS = true;                      // Ustaw wskaźnik zmiany położenia potencjometru.
  }

  // PRZESŁANIE NA WYŚWIETLACZ
  if (aktywnyBAS == true) {      // Jeśli wykryto zmianę położenia potencjometru...
    aktywnyBAS = false;          // Kasuj wskaźnik zmiany położenia potencjometru.
    Serial.println(wartoscBAS);  // Wyślij wartość napięcia pochodzącego ze ślizgacza potencjometru do komputera.
  }
}

Skasujmy na razie pozostałe potencjometry, zajmijmy się jednym. Gdy wszystko dopracujemy, powielimy algorytm na pozostałe gałki. Zadeklarujemy sobie trzy zmienne: wartoscBAS – będzie stanem potencjometru już oczyszczonym z drgań i niestabilności, która będzie nam potrzebna do dalszych działań. zmianaBAS to wartość sczytywana w każdym obrocie pętli do porównań ze stabilną wartością domyślną. W końcu aktywnyBAS oznacza, że wartość potencjometru uległa oficjalnej zmianie, z uwzględnieniem drgań, tj po ich odfiltrowaniu. To się zaraz wyjaśni.

Odtąd program będzie powstawał modułami, co znaczy że problematykę rozbijemy na kolejne etapy, nawet jeśli to i owo się powtórzy, ale to dlatego, by było przejrzyście i przede wszystkim żeby można było wszystko zmieniać i adaptować do zastanej sytuacji.

Pierwszym modułem (ODCZYT) jest ten, który zamieni niestabilne odczyty na stabilne. Już to kiedyś prezentowałem, tutaj znów jest okazja i o tyle inna, że potencjometrów będzie sześć – ale na razie zajmijmy się jednym. Zaczynamy od zmierzenia napięcia z wyjścia ślizgacza, którą załadujemy do zmiennej zmianaBAS. Porównamy teraz wartość zapamiętaną wcześniej (wartoscBAS, na początku wynosi ona zero) z właśnie odczytaną zmianaBAS. I tylko jeśli wartość bezwzględna różnicy jest większa od trzech, przejdziemy do dalszych czynności. Dlaczego tak? Otóż clou metody na tym właśnie polega: drgania potencjometru rejestrują się jako ciągi zmieniających się wartości o jeden. Zatem jeśli różnica jest mniejsza od dwóch, możemy taką sytuację zignorować. Kiepskie potencjometry mogą generować jeszcze większe rozrzuty. Wstawiłem trójkę, żeby zyskać jeszcze mocniejszą filtrację. Nie ma jednak nic za darmo, teoretycznie teraz zmiany zarejestrują się dopiero, gdy gałka zmieni położenie z dokładnością cztery razy mniejszą. Innymi słowy, zamiast 1024 pozycji gałki możemy ciągiem uzyskać tylko 256. Ale to i tak więcej niż potrzeba dla tego projektu. Tak na marginesie, nie znaczy to, że tylko co czwarta wartość będzie zapamiętywana. Jeśli między odczytami gałka przesunie się o 5 jednostek, taki wynik zostanie zapamiętany. Więc rozdzielczość nadal jest dziesięciobitowa, ale uzyskanie dowolnej wartości nie jest już takie proste i możliwe tylko ze skokiem większym od czterech.

Wracając do programu, jeśli nastąpi co opisałem, uznamy że potencjometr został obrócony przez człowieka, a nie elektroniczne duchy. Tak więc najpierw wstawimy zmierzoną wartość do obowiązującej dla reszty programu zmiennej wartoscBAS, a potem aktywujemy flagę aktywnyBAS mówiącą, iż właśnie ruszono potencjometrem. I to jest koniec obsługi gałki. Do tego już nigdzie w programie nie będziemy wracać i to jest ważne: w ten sposób zyskujemy czytelność, gdyż nie będziemy musieli się tym zajmować ani zastanawiać się, dlaczego coś nam się tu samo zmienia.

W drugim module (PRZESŁANIE NA WYŚWIETLACZ) na razie kontrolnie wyślemy sobie wartości na wyświetlacz komputera. Ale nie tak po prostu, a tylko wówczas, gdy flaga zmiany wartości aktywnyBAS zostanie ustawiona w pierwszym module. Ideą jest brak pustych przebiegów: cokolwiek robisz, rób tylko wtedy, gdy trzeba. Innymi słowy, wysyłanie wartości do monitora nastąpi tylko wtedy, gdy ta wartość się zmieni. Obsługa takiego zadania polega najpierw na skasowaniu flagi, czyli nadania jej wartości false. Znaczyć to będzie: gdy trafimy w te okolice, nie będziemy niczego wysyłać po raz drugi, chyba że wcześniejszy moduł znowu odwróci tę flagę. Dobrym zwyczajem jest kasowanie takich flag na początku ich obsługi. Nie jest to konieczne, ale często potem zapomina się o tym. Gdy już to zrobimy, wstawiamy wszystkie elementy obsługi zmienionej wartości potencjometru do końca nawiasu klamrowego. W tym przypadku mamy tylko wysyłkę wartości na komputer – w celach sprawdzenia czy wszystko działa. A działa znakomicie. Nie sposób ustawić gałkę tak, by coś tu „samo się działo”. Tak więc moduł zamiany gałek w stabilne wartości mamy załatwiony. Ciąg dalszy pracy pojawi się w kolejnym artykule.

Powiązane tematy

Płytka edukacyjna TME-EDU-ARD-2Płytka edukacyjna TME-EDU-ARD-2Sprawdź tutaj

Przeczytaj również

Nasi partnerzy

TMETech Master EventTME EducationPoweredby
Copyright © 2025 arduino.pl