Czołem majsterkowicze! W tym artykule postaram się Wam przedstawić sposób na wykonanie dotykowego pianinka z kartki papieru, ołówka i arduino.
Artykuł podzielę na cztery części:
- Generowanie dźwięku z głośniczka,
- Generowanie dźwięku za pomocą aplikacji napisanej w processingu,
- Generowanie dźwięku przez protokół MIDI w GarageBand.
Robimy pianinko
Potrzebne materiały:
- 12x spinacz
- 12x odcinek kabla
- kartka papieru
- ołówek
Pobieramy i drukujemy poniższą klawiaturę. (najlepiej na papierze technicznym)
Po wydrukowaniu przyda się kilka ołówków i temperówka. Najpierw naostrzmy ołówki :D a potem starannie pokolorujmy wydrukowaną klawiaturę. Ważne jest aby klawisze się nie stykały!
Jak już widać na powyższym zdjęciu do połączenie klawiaturki z arduino użyłem spinacza biurowego zlutowanego z kabelkiem.
- Obierz końcówki kabla z izolacji.
- Zlutuj jedną końcówkę kabla z spinaczem.
Połączenia Arduino
Potrzebne materiały:
W miejscu żółtych kabelków podpinamy każdy klawisz klawiaturki za pomocą spinaczy i kabli, które wcześniej przygotowaliśmy.
Generowanie dźwięku za pomocą programu w processingu
Program arduino:
Instalujemy bibliotekę CapacitiveSensor do pobrania tutaj. Więcej informacji na temat biblioteki tutaj
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
#include <CapacitiveSensor.h> CapacitiveSensor capSensor = CapacitiveSensor(4,2); CapacitiveSensor capSensor1 = CapacitiveSensor(4,3); CapacitiveSensor capSensor2 = CapacitiveSensor(4,5); CapacitiveSensor capSensor3 = CapacitiveSensor(4,6); CapacitiveSensor capSensor4 = CapacitiveSensor(4,7); CapacitiveSensor capSensor5 = CapacitiveSensor(4,8); CapacitiveSensor capSensor6 = CapacitiveSensor(4,9); CapacitiveSensor capSensor7 = CapacitiveSensor(4,10); CapacitiveSensor capSensor8 = CapacitiveSensor(4,11); CapacitiveSensor capSensor9 = CapacitiveSensor(4,12); CapacitiveSensor capSensor10 = CapacitiveSensor(4,13); CapacitiveSensor capSensor11 = CapacitiveSensor(4,14); int k1 = 2; int k2 = 3; int k3 = 5; int k4 = 6; int k5 = 7; int k6 = 8; int k7 = 9; int k8 = 10; int k9 = 11; int k10 = 12; int k11 = 13; int k12 = 14; int val1 = 0; int val2 = 0; int val3 = 0; int val4 = 0; int val5 = 0; int val6 = 0; int val7 = 0; int val8 = 0; int val9 = 0; int val10 = 0; int val11 = 0; int val12 = 0; void setup() { Serial.begin(9600); } void loop(){ val1 = digitalRead(k1); val2 = digitalRead(k2); val3 = digitalRead(k3); val4 = digitalRead(k4); val5 = digitalRead(k5); val6 = digitalRead(k6); val7 = digitalRead(k7); val8 = digitalRead(k8); val8 = digitalRead(k9); val10 = digitalRead(k10); val11 = digitalRead(k11); val12 = digitalRead(k12); pianino(); delay(100); } void pianino(){ if(val1 > 1){ Serial.write(1); } if(val2 > 0){ Serial.write(2); } if(val3 > 0){ Serial.write(3); } if(val4 > 0){ Serial.write(4); } if(val5 > 0){ Serial.write(5); } if(val6 > 0){ Serial.write(6); } if(val7 > 0){ Serial.write(7); } if(val8 > 0){ Serial.write(8); } if(val9 > 0){ Serial.write(9); } if(val10 > 0){ Serial.write(10); } if(val11 > 0){ Serial.write(11); } if(val12 > 0){ Serial.write(13); } } |
Kod processing:
Wymaga zainstalowania biblioteki serial i soundcipher. Aby zainstalować bibliotekę otwieramy okno processingu wchodzimy w menu sketch/import Library../Add Library… w otwartym oknie wpisujemy nazwe biblioteki i klikamy install.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
import processing.serial.*; import arb.soundcipher.*; SoundCipher sc = new SoundCipher(this); Serial myPort; void setup() { size(200, 200); String portName = Serial.list()[10]; myPort = new Serial(this, portName, 9600); } void draw() { int val=0; if ( myPort.available() > 0) { delay(100); val = myPort.read(); } if (val == 1) { sc.playNote(60, 100, 2.0); } if (val == 2) { sc.playNote(61, 100, 2.0); } if (val == 3){ sc.playNote(62, 100, 2.0); } if (val == 4) { sc.playNote(63, 100, 2.0); } if (val == 5) { sc.playNote(64, 100, 2.0); } if (val == 6) { sc.playNote(65, 100, 2.0); } if (val == 7){ sc.playNote(66, 100, 2.0); } if (val == 8){ sc.playNote(67, 100, 2.0); } if (val == 9){ sc.playNote(68, 100, 2.0); } if (val == 10){ sc.playNote(69, 100, 2.0); } if (val == 11){ sc.playNote(70, 100, 2.0); } if (val == 12){ sc.playNote(71, 100, 2.0); } if (val == 13){ sc.playNote(72, 100, 2.0); } println(val); } |
Generowanie dźwięku za pomocą głośniczka piezo
Aby generować dźwięki musimy podpiąć głośniczek pod pin 16 czyli A1.
Połączenia arduino:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
#include <CapacitiveSensor.h> CapacitiveSensor capSensor = CapacitiveSensor(4,2); CapacitiveSensor capSensor1 = CapacitiveSensor(4,3); CapacitiveSensor capSensor2 = CapacitiveSensor(4,5); CapacitiveSensor capSensor3 = CapacitiveSensor(4,6); CapacitiveSensor capSensor4 = CapacitiveSensor(4,7); CapacitiveSensor capSensor5 = CapacitiveSensor(4,8); CapacitiveSensor capSensor6 = CapacitiveSensor(4,9); CapacitiveSensor capSensor7 = CapacitiveSensor(4,10); CapacitiveSensor capSensor8 = CapacitiveSensor(4,11); CapacitiveSensor capSensor9 = CapacitiveSensor(4,12); CapacitiveSensor capSensor10 = CapacitiveSensor(4,13); CapacitiveSensor capSensor11 = CapacitiveSensor(4,14); int k1 = 2; int k2 = 3; int k3 = 5; int k4 = 6; int k5 = 7; int k6 = 8; int k7 = 9; int k8 = 10; int k9 = 11; int k10 = 12; int k11 = 13; int k12 = 14; byte val[13]; byte oldval[13]; int speakerPin = 16; int numTones = 10; int tones[] = {262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494}; // mid C C# D D# E F F# G G# A a# h c void setup() { } void loop(){ val[0] = digitalRead(k1); val[1] = digitalRead(k2); val[2] = digitalRead(k3); val[3] = digitalRead(k4); val[4] = digitalRead(k5); val[5] = digitalRead(k6); val[6] = digitalRead(k7); val[7] = digitalRead(k8); val[8] = digitalRead(k9); val[9] = digitalRead(k10); val[10] = digitalRead(k11); val[11] = digitalRead(k12); pianino(); } void pianino(){ if (oldval[0] != val[0]){ oldval[0] == HIGH; tone(speakerPin, tones[1]); delay(100); } else{ oldval[0] == LOW; } if (oldval [0] == HIGH){ Serial.write(0); } if (oldval[1] != val[1]){ oldval[1] == HIGH; tone(speakerPin, tones[2]); delay(100); } else{ oldval[1] == LOW; } if (oldval [1] == HIGH){ Serial.write(0); } if (oldval[2] != val[2]){ oldval[2] == HIGH; tone(speakerPin, tones[3]); delay(100); } else{ oldval[2] == LOW; } if (oldval [2] == HIGH){ Serial.write(0); } if (oldval[3] != val[3]){ oldval[3] == HIGH; tone(speakerPin, tones[4]); delay(100); } else{ oldval[3] == LOW; } if (oldval [3] == HIGH){ Serial.write(0); } if (oldval[4] != val[4]){ oldval[4] == HIGH; tone(speakerPin, tones[5]); delay(100); } else{ oldval[4] == LOW; } if (oldval [4] == HIGH){ Serial.write(0); } if (oldval[5] != val[5]){ oldval[5] == HIGH; tone(speakerPin, tones[6]); delay(100); } else{ oldval[5] == LOW; } if (oldval [5] == HIGH){ Serial.write(0); } if (oldval[6] != val[6]){ oldval[6] == HIGH; tone(speakerPin, tones[7]); delay(100); } else{ oldval[6] == LOW; } if (oldval [6] == HIGH){ } if (oldval[7] != val[7]){ oldval[7] == HIGH; tone(speakerPin, tones[8]); delay(100); } else{ oldval[7] == LOW; } if (oldval [7] == HIGH){ } if (oldval[8] != val[8]){ oldval[8] == HIGH; tone(speakerPin, tones[9]); delay(100); } else{ oldval[8] == LOW; } if (oldval [8] == HIGH){ } if (oldval[9] != val[9]){ oldval[9] == HIGH; tone(speakerPin, tones[10]); delay(100); } else{ oldval[9] == LOW; } if (oldval [9] == HIGH){ } if (oldval[10] != val[10]){ oldval[10] == HIGH; tone(speakerPin, tones[11]); delay(100); } else{ oldval[10] == LOW; } if (oldval [10] == HIGH){ } if (oldval[11] != val[11]){ oldval[6] == HIGH; tone(speakerPin, tones[12]); delay(100); } else{ oldval[11] == LOW; } if (oldval [11] == HIGH){ } if (oldval[12] != val[12]){ oldval[12] == HIGH; tone(speakerPin, tones[13]); delay(100); } else{ oldval[12] == LOW; } if (oldval [12] == HIGH){ } noTone(speakerPin); } |
Generowanie dźwięków za pomocą protokołu MIDI
MIDI skrót od Musical Instrument Digital Interface to protokół służący do przekazywania informacji pomiędzy elektronicznymi instrumentami a np. komputerem. Informacje są przesyłane za pomocą specjalnych komend:
Kod arduino:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
#include <CapacitiveSensor.h> #include <MIDI.h> CapacitiveSensor capSensor = CapacitiveSensor(4,2); CapacitiveSensor capSensor1 = CapacitiveSensor(4,3); CapacitiveSensor capSensor2 = CapacitiveSensor(4,5); CapacitiveSensor capSensor3 = CapacitiveSensor(4,6); CapacitiveSensor capSensor4 = CapacitiveSensor(4,7); CapacitiveSensor capSensor5 = CapacitiveSensor(4,8); CapacitiveSensor capSensor6 = CapacitiveSensor(4,9); CapacitiveSensor capSensor7 = CapacitiveSensor(4,10); CapacitiveSensor capSensor8 = CapacitiveSensor(4,11); CapacitiveSensor capSensor9 = CapacitiveSensor(4,12); CapacitiveSensor capSensor10 = CapacitiveSensor(4,13); CapacitiveSensor capSensor11 = CapacitiveSensor(4,14); int k1 = 2; int k2 = 3; int k3 = 5; int k4 = 6; int k5 = 7; int k6 = 8; int k7 = 9; int k8 = 10; int k9 = 11; int k10 = 12; int k11 = 13; int k12 = 14; int val1 = 0; int val2 = 0; int val3 = 0; int val4 = 0; int val5 = 0; int val6 = 0; int val7 = 0; int val8 = 0; int val9 = 0; int val10 = 0; int val11 = 0; int val12 = 0; const int channel = 1; void setup() { MIDI.begin(); Serial.begin(115200); } void loop(){ val1 = digitalRead(k1); val2 = digitalRead(k2); val3 = digitalRead(k3); val4 = digitalRead(k4); val5 = digitalRead(k5); val6 = digitalRead(k6); val7 = digitalRead(k7); val8 = digitalRead(k8); val8 = digitalRead(k9); val10 = digitalRead(k10); val11 = digitalRead(k11); val12 = digitalRead(k12); pianino(); delay(100); } void pianino(){ if(val1 > 1){ MIDI.sendNoteOn(60, 100, channel); } if(val2 > 0){ MIDI.sendNoteOn(61, 100, channel); } if(val3 > 0){ MIDI.sendNoteOn(62, 100, channel); } if(val4 > 0){ MIDI.sendNoteOn(63, 100, channel); } if(val5 > 0){ MIDI.sendNoteOn(64, 100, channel);; } if(val6 > 0){ MIDI.sendNoteOn(65, 100, channel); } if(val7 > 0){ MIDI.sendNoteOn(66, 100, channel); } if(val8 > 0){ MIDI.sendNoteOn(67, 100, channel); } if(val9 > 0){ MIDI.sendNoteOn(68, 100, channel); } if(val10 > 0){ MIDI.sendNoteOn(69, 100, channel); } if(val11 > 0){ MIDI.sendNoteOn(70, 100, channel); } if(val12 > 0){ MIDI.sendNoteOn(71, 100, channel); } } |
Arduino wysyła sygnał midi przez serial port teraz potrzebujemy jeszcze program, który zamieni sygnał z serial portu na sygnał midi. W tym celu pobieramy program Hairless MIDI. Teraz przedstawię działanie programu pod mac osx ponieważ chcemy wysyłać sygnał do GarageBand.
Klikamy dwukrotnie sterownik IAC
W właściwościach sterownika IAC zaznaczamy Urządzenie jest aktywne.
Otwieramy Garage Band i tworzymy nowy projekt. I teraz pozostaje nam się ciszyć pianinkiem MIDI. Opisany projekt jest na Mac’a ponieważ według mnie Garage Band to fajny i intuicyjny program. Mam dostęp do Mac’a w szkole i niestety nie znalazłem darmowego i tak rozbudowanego programu obsługującego MIDI pod Windowsa.
Poniżej wstawiam demo arduina z processingiem. Film został nakręcony wcześniej, niestety w chwili pisania artykułu nie mam możliwości nagrania finalnych urządzeń ale obiecuje że wstawię filmy w przyszłym tygodniu.
No super poradnik :) Widziałem w sieci taki projekt ale miałem na niego inny pomysł bo chciałem go zintegrować z WAV playerem aby poszczególne dźwięki wydawał prosto z plików z karty pamięci ale nie miałem jakoś ochoty w tym miesiącu się tak wysilać jak w poprzednim :D no i czasu :)
Chyba na filmiku widać lekkiego buga w połączeniu z processingiem ale i tak jest GIT ;)
* ;)
Stary komp i czasami zlaguje.
Aha :) No bywa :D
Dzięki za dobre słowo:D Teraz pracuje nad tym aby pianinko działało z garage band na ios (bluetooth) ale to jak na razie idzie opornie.
iOS? nie żartuj :D Lepiej się za Androida weź bo Apple to burżuazja :D sorry ale musiałem
Według mnie w Polsce ceny są absurdalne ale na zachodzie to już inna bajka :D. Jeśli chodzi o ios to jest on skrojony pod konkretne urządzenie a nie pod setki jak w androidzie dlatego przynajmniej mi nie laguje. Andrida na tę chwile nie posiadam więc pozostaje mi próbować z ios.
Przyczepię się: za bardzo wejściożerne. Zobacz na poradnik jak zrobić keypad na forum (mojego autorstwa zresztą). Wtedy wystarczy Ci jedno wejście analogowe (trzeba tylko będzie posprawdzać przez Serial jaki sygnał daje przyciśnięcie którego klawisza, pozmieniać kod i nieznacznie budowę, ale chyba warto, bo stracimy tylko jedno wejście, a nie prawie wszystkie I/O Arduino, co jest dość dużym ciosem.
Wtedy by nie było możliwości zrobienia w przyszłości akordów.
Ojej, ojej, co za kod. Może lepiej napisać go przy pomocy dodatkowego wektora i kilku pętli? Będzie krótszy (walka o komórki pamięci, w przypadku rozszerzenia funkcjonalności), łatwiejszy w utrzymywaniu i czytelniejszy.
Dlaczego po poprawnym (Sprawdzane 3 razy) podłączeniu wszystkiego i wgraniu do arduino kodu z midi, Hairless midi nie czyta tego co powinien (Same errory) a w serial monior mam jakieś dziwnie losowo generowane znaki:
http://i.imgur.com/KbVvxfq.png
Pomoże ktoś?
Masz źle ustawioną predkość
zmień 9600 baud na 115200.
Powinno być 115200 a i znaki są kodowane w ascii
Czy dało by radę odpalić to w ableton’ie ? Widziałem gdzieś taki program który zamienia z midi na serial czy coś takiego… Wtedy można by zrobić beatpad’a ;)
Czemu w 65 linijce kodu jest (val1 > 1) a nie tak jak we wszystkich innych ?
Witam!
Super to działa ale jestem zielony więc się pytam czy tem poradnik a klawiatora http://techtrendy.pl/title,Klawiatura-Bluetooth-wydrukowana-na-kartce-papieru,wid,16421053,wiadomosc.html?ticaid=5123e5 mogła by działać na tej zasadzie co pianinko? Może działa ale przy tych samych urządzeniu Arduino?
Pingback: Ron
Pingback: lee
Pingback: jesse
Pingback: Raymond
Witam, jestem początkującym użytkownikiem Andurino, po podłączeniu wszystkiego zgodnie ze schematem oraz załadowaniu programu dla głośniczka piezo nic się nie dzieje po dotknięciu przewodów odpowiedzialnych za klawisze. Proszę o pomoc
Czemu są tam są rezystory i dlaczego 1 MOhm
Witam, generowanie dźwięku z głośniczka piezo nie działa, cały układ dobrze zmontowany i głośnik sprawny, problem w źle napisanym programie. Prosiłbym o poprawkę