Poniższy projekt to pierwsze urządzenie zrealizowane przez autora z wykorzystaniem modułu Arduino. Układ ten służy do obróbki sygnałów MIDI tak, aby możliwe było granie w skalach mikrotonalnych, to znaczy odrobinę odstrojonych od podstawowej skali z wykorzystaniem dodatkowej funkcjonalności sygnałów MIDI - oprócz nuty może on wysyłać dodatkową wartość związaną z odstrojeniem.
Poniższy projekt pokazuje, krok po kroku, w jaki sposób autor zestawił i oprogramował opisywane urządzenie. Układ odczytuje dźwięki wysyłane poprzez MIDI i wysyła komunikaty z odstrojeniami w skali n-TET, do tego projektu dodał następujące funkcje:
* Enkodery wykorzystywane do ustawiania wartości kroków na oktawę (od 0 do 99) i podstawową nutę (od 0 do 99).
* Wyświetlacze siedmiosegmentowe pozwalające na prezentację ustawionych enkoderami wartości.
* Podświetlony diodą LED przycisk zmieniający dźwięk z monofonicznego na polifoniczny.
* Porty MIDI (wejściowy i wyjściowy) zestawione z elementów dyskretnych, a nie gotowego shielda.
* Program z kompletną implementacją interfejsu MIDI.
Lista potrzebnych elementów:
* Sparkfun Redboard
* Prototypowy shield Arduino
* Obudowa Hammonda
* 2 x gniazdo MIDI
* Podświetlany przycisk
* 2 x enkoder obrotowy Bourns
* 2 x przycisk
* Czterocyfrowy wyświetlacz siedmiosegmentowy ze wspólną anodą
* Transoptor 6N138
* Oporniki: 10 k? (1 szt), 220 ? (8 szt).
* Kondensator 100 pF
* Dioda 1N914
* Gniazda do podłączenia prototypowego shielda do Redboearda
* Gniazdo 2 x 6 pin
* Gniazdo DIP8 dla transoptopra
* Kable do podłączenia enkoderów etc
Krok 1: Podłączenie MIDI do Arduino
Autor rozpoczął programowanie urządzenia od nauki odbierania i wysyłania komunikatów MIDI z wykorzystaniem Arduino. Pierwszym z problemów, jakie napotkał autor, podczas projektowania oprogramowania, było obrabianie komunikatów pochodzących z interfejsu MIDI w czasie rzeczywistym.
Autor napisał prosty kod w C na Arduino, który monitoruje wejście MIDI i przepisuje je do monitora transmisji szeregowej. Autor zmuszony był wykorzystać programowy port szeregowy, ponieważ interfejs MIDI działa z prędkością 31250 - nieobsługiwaną przez wspierany sprzętowo układ transmisji szeregowej. Zamieszczony poniżej program filtruje wszystkie komendy i reaguje tylko na te komendy poniżej 160 informujące o włączeniu i wyłączeniu nuty. Można oczywiście przedefiniować program, by reagował na wszystkie komendy.
Kolejnym elementem układanki jest koncepcja związana z przesyłaniem danych w czasie rzeczywistym dalej. Chodzi o to, że komendy, takie jak np. o załączeniu dźwięku, mogą być pomijane, ale jednocześnie przesyłane są dane. Oznacza to, że dla akordu trzech dźwięków zamiast przesyłać trzy komendy o załączeniu dźwięku, wraz z informacjami o jego wysokości i prędkości narastania (łącznie 9 bajtów) przesyła się jedną komendę i trzy pary danych wysokość-prędkość (łącznie 7 bajtów). Dodatkowo, zamiast komendy wyłączenia dźwięku można wysłać informacje o jego włączeniu, ale z prędkością równą zero - także jako parę za jedną komendą załączającą dźwięki. To rozwiązanie pozwala na wydajniejszą i szybszą komunikację szeregową z wykorzystaniem MIDI i zmniejsza opóźnienia.
Ostatnią rzeczą, jaką zrobił autor, aby usprawnić komunikację z modułem Arduino, było wykorzystanie interfejsu (strony sprzętowejk) zbudowanej samodzielnie, zamiast wykorzystywania np. modułu Linksprite MIDI. Pozwala to na dobudowanie na płytce uniwersalnej dodatkowych elementów, nie tylko interfejsu MIDI, na przykład przycisków, enkoderów do sterowania urządzeniem etc.
Krok 2: Odczytywanie wyjść kwadraturowych z enkoderów
Autor dodał do urządzenia pokrętła - enkodery - do kontroli wartości w czasie pracy układu. Pokrętła sterują ilością kroków na oktawę oraz centralnym tonem dźwięku. Autor zastosował enkodery obrotowe firmy Bourns. Enkodery te wyposażone są w wyjście kwadraturowe pozwalające na odczytywanie ilości obrotów i ich kierunku,
Implementacja tego elementu w układzie nie jest prosta dla kogoś nowego w ekosystemie Arduino. Każdy z enkoderów ma dwa wyjścia cyfrowe, podczas obracania zgodnie z kierunkiem wskazówek zegara przyjmują one wartości 00, 10, 11 i 01. Kolejność jest odwrócona, jeśli odwróci się kierunek obrotu. Zamieszczony poniżej program pozwala na analizę sygnału kwadraturowego. Zmienna old_AB przechowuje 4 bity - poprzedni odczyt z enkodera (00, 01, 11 lub 01) oraz aktualny odczyt (00, 01, 11 lub 01). Macierz enc_states[] zawiera w sobie trzy możliwe zachowania enkodera w danej chwili czasu - 0 = brak ruchu 1 = ruch zgodnie z kierunkiem obrotu wskazówek zegara, -1 = ruch przeciwnie do kierunku obrotu wskazówek zegara.
Zatem na przykład, jeśli poprzednia pozycja dawała odczyt 00, a nowa daje 10, to binarne 0010 daje nam enc_state[2] = 1, co oznacza ruch w kierunku wskazówek zegara. Z kolei jeśli pierwotna pozycja daje odczyt 00, a kolejna 11, to musiał nastąpić jakiś błąd w odczycie, gdyż binarne 0011 nie daje poprawnego odczytu, co program interpretuje jako enc_state[b0011] = 0, brak ruchu. W ramach macierzy enc_state[] zaimplementowano także pozostałe 14 możliwych kombinacji.
Krok 3: Wyświetlacz siedmiosegmentowy i manipulacje portem
Do układu dodano czterocyfrowy wyświetlacz siedmiosegmentowy, który pozwala na wyświetlanie danych zmienianych z wykorzystaniem enkoderów. Dwie pierwsze cyfry wyświetlają liczbę kroków na oktawę, a dwie ostatnie reprezentują podstawowy ton sygnału.
Autor zakupił odpowiedni wyświetlacz. Anody diod w poszczególnych cyfrach są ze sobą połączone i wyprowadzone na zewnątrz - są to piny 6, 9, 10 i 12. Pozwalają one na wybranie aktualnie wykorzystywanej cyfry. Na tych pinach autor włączył rezystory ograniczające prąd tak, aby zmniejszyć ilość potrzebnych do wykorzystania oporników - wejść sterujących segmentami jest więcej - osiem (siedem segmentów plus kropka dziesiętna). Prąd ograniczono opornikami o rezystancji równej 220 ?. Wartość ta została wyliczona z maksymalnego prądu segmentu - 25 mA i typowego spadku napięcia na diodzie LED - 2,2 V. Przy oporniku takim, jak wykorzystany prąd ograniczony jest do (5-2,2) V / 220 ? = 12,7 mA, co bardzo dobrze mieści się w ograniczeniu. (Chociaż powodować będzie przygasanie segmentów, jeśli będzie ich zapalone więcej niż jeden w obrębie danej cyfry, bo prąd będzie rozkładał się równo na wszystkie zapalone segmenty - przyp. red.).
Osiem pinów kontrolujących poszczególne segmenty podłączone jest do wyjść cyfrowych Arduino (piny od 2 do 13). Połączenia zostały zrealizowane tak, żeby było wygodnie, a całość została zmapowana programowo z pomocą #define w obrębie programu, jak pokazano poniżej. To o wiele prostsze rozwiązanie, niż podłączanie pinów wyświetlacza LED w kolejności segmentów.
Krok 4: Przycisk i jego filtracja plus zapalenie diody LED
Wstępne testy układu wykazały, że w trybie monofonicznym syntezator wymaga szczególnych zabiegów, jeśli chodzi o ponowne wyzwalanie ostatniej nuty, szczególnie gdy naciśnięte są dwa różne klawisze - zwłaszcza gdy odnoszą się do tej samej nuty jedynie z innymi wartościami odstrojenia. Dlatego też w urządzeniu zaimplementowano przełączanie pomiędzy monofonicznym a polifonicznym działaniem. Dioda LED została dodana, aby sygnalizować, jaki aktualnie załączony jest tryb pracy.
Wbudowany w system przycisk posiada zintegrowaną diodę LED. Układ zbudowany został na podstawie tej dokumentacji. Filtrowanie zakłóceń spowodowanych drżeniem styków zrealizowane jest sprzętowo w oparciu o filtr RC skonstruowany z opornika 10 k? i kondensatora 100 pF. Wartości te dobrze się sprawdziły w układzie, więc autor nic nie zmieniał.
Dioda LED podłączona została przez opornik 220 ?, zgodnie z rekomendacją Adafruit.
Krok 5: program główny
Poniżej znajduje się główny program układu. Wykorzystane biblioteki można ściągnąć ze strony projektu lub GitHuba.
Biblioteka dla wyświetlacza siedmiosegmentowego:
Biblioteka została wykorzystana w takiej formie, jak zaprezentowano powyżej. Musi być bardzo szybka, gdyż inaczej zwalnia przetwarzanie dźwięków MIDI i wprowadza opóźnienia w transmisji.
Biblioteka mikrotonów MIDI:
Biblioteka obsługująca interfejs MIDI zajmuje się dekodowaniem komend i zmianą tonów. Biblioteka, tak jak pokazano powyżej, filtruje komendy i skupia się jedynie na dźwiękach, co pozwala jej działać szybko.
Główny kod programu:
W głównym kodzie programu zawarto obsługę przerwań dla enkoderów i przycisku oraz inicjalizacje interfejsu MIDI i uruchomienie procedur obsługujących wyświetlacz LED i port MIDI.
Główna pętla programu składa się w zasadzie z wywoływania procedury obsługi interfejsu MIDI i odświeżania wyświetlacza.
Źródło: http://www.instructables.com/id/Super-Duper-Microtonal-MIDI-Converter/?ALLSTEPS
Poniższy projekt pokazuje, krok po kroku, w jaki sposób autor zestawił i oprogramował opisywane urządzenie. Układ odczytuje dźwięki wysyłane poprzez MIDI i wysyła komunikaty z odstrojeniami w skali n-TET, do tego projektu dodał następujące funkcje:
* Enkodery wykorzystywane do ustawiania wartości kroków na oktawę (od 0 do 99) i podstawową nutę (od 0 do 99).
* Wyświetlacze siedmiosegmentowe pozwalające na prezentację ustawionych enkoderami wartości.
* Podświetlony diodą LED przycisk zmieniający dźwięk z monofonicznego na polifoniczny.
* Porty MIDI (wejściowy i wyjściowy) zestawione z elementów dyskretnych, a nie gotowego shielda.
* Program z kompletną implementacją interfejsu MIDI.
Lista potrzebnych elementów:
* Sparkfun Redboard
* Prototypowy shield Arduino
* Obudowa Hammonda
* 2 x gniazdo MIDI
* Podświetlany przycisk
* 2 x enkoder obrotowy Bourns
* 2 x przycisk
* Czterocyfrowy wyświetlacz siedmiosegmentowy ze wspólną anodą
* Transoptor 6N138
* Oporniki: 10 k? (1 szt), 220 ? (8 szt).
* Kondensator 100 pF
* Dioda 1N914
* Gniazda do podłączenia prototypowego shielda do Redboearda
* Gniazdo 2 x 6 pin
* Gniazdo DIP8 dla transoptopra
* Kable do podłączenia enkoderów etc
Krok 1: Podłączenie MIDI do Arduino
Autor rozpoczął programowanie urządzenia od nauki odbierania i wysyłania komunikatów MIDI z wykorzystaniem Arduino. Pierwszym z problemów, jakie napotkał autor, podczas projektowania oprogramowania, było obrabianie komunikatów pochodzących z interfejsu MIDI w czasie rzeczywistym.
Autor napisał prosty kod w C na Arduino, który monitoruje wejście MIDI i przepisuje je do monitora transmisji szeregowej. Autor zmuszony był wykorzystać programowy port szeregowy, ponieważ interfejs MIDI działa z prędkością 31250 - nieobsługiwaną przez wspierany sprzętowo układ transmisji szeregowej. Zamieszczony poniżej program filtruje wszystkie komendy i reaguje tylko na te komendy poniżej 160 informujące o włączeniu i wyłączeniu nuty. Można oczywiście przedefiniować program, by reagował na wszystkie komendy.
Code: c
Kolejnym elementem układanki jest koncepcja związana z przesyłaniem danych w czasie rzeczywistym dalej. Chodzi o to, że komendy, takie jak np. o załączeniu dźwięku, mogą być pomijane, ale jednocześnie przesyłane są dane. Oznacza to, że dla akordu trzech dźwięków zamiast przesyłać trzy komendy o załączeniu dźwięku, wraz z informacjami o jego wysokości i prędkości narastania (łącznie 9 bajtów) przesyła się jedną komendę i trzy pary danych wysokość-prędkość (łącznie 7 bajtów). Dodatkowo, zamiast komendy wyłączenia dźwięku można wysłać informacje o jego włączeniu, ale z prędkością równą zero - także jako parę za jedną komendą załączającą dźwięki. To rozwiązanie pozwala na wydajniejszą i szybszą komunikację szeregową z wykorzystaniem MIDI i zmniejsza opóźnienia.
Ostatnią rzeczą, jaką zrobił autor, aby usprawnić komunikację z modułem Arduino, było wykorzystanie interfejsu (strony sprzętowejk) zbudowanej samodzielnie, zamiast wykorzystywania np. modułu Linksprite MIDI. Pozwala to na dobudowanie na płytce uniwersalnej dodatkowych elementów, nie tylko interfejsu MIDI, na przykład przycisków, enkoderów do sterowania urządzeniem etc.
Krok 2: Odczytywanie wyjść kwadraturowych z enkoderów
Autor dodał do urządzenia pokrętła - enkodery - do kontroli wartości w czasie pracy układu. Pokrętła sterują ilością kroków na oktawę oraz centralnym tonem dźwięku. Autor zastosował enkodery obrotowe firmy Bourns. Enkodery te wyposażone są w wyjście kwadraturowe pozwalające na odczytywanie ilości obrotów i ich kierunku,
Implementacja tego elementu w układzie nie jest prosta dla kogoś nowego w ekosystemie Arduino. Każdy z enkoderów ma dwa wyjścia cyfrowe, podczas obracania zgodnie z kierunkiem wskazówek zegara przyjmują one wartości 00, 10, 11 i 01. Kolejność jest odwrócona, jeśli odwróci się kierunek obrotu. Zamieszczony poniżej program pozwala na analizę sygnału kwadraturowego. Zmienna old_AB przechowuje 4 bity - poprzedni odczyt z enkodera (00, 01, 11 lub 01) oraz aktualny odczyt (00, 01, 11 lub 01). Macierz enc_states[] zawiera w sobie trzy możliwe zachowania enkodera w danej chwili czasu - 0 = brak ruchu 1 = ruch zgodnie z kierunkiem obrotu wskazówek zegara, -1 = ruch przeciwnie do kierunku obrotu wskazówek zegara.
Code: c
Zatem na przykład, jeśli poprzednia pozycja dawała odczyt 00, a nowa daje 10, to binarne 0010 daje nam enc_state[2] = 1, co oznacza ruch w kierunku wskazówek zegara. Z kolei jeśli pierwotna pozycja daje odczyt 00, a kolejna 11, to musiał nastąpić jakiś błąd w odczycie, gdyż binarne 0011 nie daje poprawnego odczytu, co program interpretuje jako enc_state[b0011] = 0, brak ruchu. W ramach macierzy enc_state[] zaimplementowano także pozostałe 14 możliwych kombinacji.
Krok 3: Wyświetlacz siedmiosegmentowy i manipulacje portem
Do układu dodano czterocyfrowy wyświetlacz siedmiosegmentowy, który pozwala na wyświetlanie danych zmienianych z wykorzystaniem enkoderów. Dwie pierwsze cyfry wyświetlają liczbę kroków na oktawę, a dwie ostatnie reprezentują podstawowy ton sygnału.
Autor zakupił odpowiedni wyświetlacz. Anody diod w poszczególnych cyfrach są ze sobą połączone i wyprowadzone na zewnątrz - są to piny 6, 9, 10 i 12. Pozwalają one na wybranie aktualnie wykorzystywanej cyfry. Na tych pinach autor włączył rezystory ograniczające prąd tak, aby zmniejszyć ilość potrzebnych do wykorzystania oporników - wejść sterujących segmentami jest więcej - osiem (siedem segmentów plus kropka dziesiętna). Prąd ograniczono opornikami o rezystancji równej 220 ?. Wartość ta została wyliczona z maksymalnego prądu segmentu - 25 mA i typowego spadku napięcia na diodzie LED - 2,2 V. Przy oporniku takim, jak wykorzystany prąd ograniczony jest do (5-2,2) V / 220 ? = 12,7 mA, co bardzo dobrze mieści się w ograniczeniu. (Chociaż powodować będzie przygasanie segmentów, jeśli będzie ich zapalone więcej niż jeden w obrębie danej cyfry, bo prąd będzie rozkładał się równo na wszystkie zapalone segmenty - przyp. red.).
Osiem pinów kontrolujących poszczególne segmenty podłączone jest do wyjść cyfrowych Arduino (piny od 2 do 13). Połączenia zostały zrealizowane tak, żeby było wygodnie, a całość została zmapowana programowo z pomocą #define w obrębie programu, jak pokazano poniżej. To o wiele prostsze rozwiązanie, niż podłączanie pinów wyświetlacza LED w kolejności segmentów.
Code: c
Krok 4: Przycisk i jego filtracja plus zapalenie diody LED
Wstępne testy układu wykazały, że w trybie monofonicznym syntezator wymaga szczególnych zabiegów, jeśli chodzi o ponowne wyzwalanie ostatniej nuty, szczególnie gdy naciśnięte są dwa różne klawisze - zwłaszcza gdy odnoszą się do tej samej nuty jedynie z innymi wartościami odstrojenia. Dlatego też w urządzeniu zaimplementowano przełączanie pomiędzy monofonicznym a polifonicznym działaniem. Dioda LED została dodana, aby sygnalizować, jaki aktualnie załączony jest tryb pracy.
Wbudowany w system przycisk posiada zintegrowaną diodę LED. Układ zbudowany został na podstawie tej dokumentacji. Filtrowanie zakłóceń spowodowanych drżeniem styków zrealizowane jest sprzętowo w oparciu o filtr RC skonstruowany z opornika 10 k? i kondensatora 100 pF. Wartości te dobrze się sprawdziły w układzie, więc autor nic nie zmieniał.
Dioda LED podłączona została przez opornik 220 ?, zgodnie z rekomendacją Adafruit.
Krok 5: program główny
Poniżej znajduje się główny program układu. Wykorzystane biblioteki można ściągnąć ze strony projektu lub GitHuba.
Code: c
Biblioteka dla wyświetlacza siedmiosegmentowego:
Biblioteka została wykorzystana w takiej formie, jak zaprezentowano powyżej. Musi być bardzo szybka, gdyż inaczej zwalnia przetwarzanie dźwięków MIDI i wprowadza opóźnienia w transmisji.
Biblioteka mikrotonów MIDI:
Biblioteka obsługująca interfejs MIDI zajmuje się dekodowaniem komend i zmianą tonów. Biblioteka, tak jak pokazano powyżej, filtruje komendy i skupia się jedynie na dźwiękach, co pozwala jej działać szybko.
Główny kod programu:
W głównym kodzie programu zawarto obsługę przerwań dla enkoderów i przycisku oraz inicjalizacje interfejsu MIDI i uruchomienie procedur obsługujących wyświetlacz LED i port MIDI.
Główna pętla programu składa się w zasadzie z wywoływania procedury obsługi interfejsu MIDI i odświeżania wyświetlacza.
Źródło: http://www.instructables.com/id/Super-Duper-Microtonal-MIDI-Converter/?ALLSTEPS
Cool? Ranking DIY