이상하게 생각했을지도 모르지만 사실 모든 채널에 아두이노 프로 마이크로를 이용할 필요는 없었다. 사실 프로 마이크로는 HID 장치로 인시되어 PC와 미디 통신만 하면 되기 때문에 I2C 통신의 slave들은 일반적인 아두이노나 기타 다른 보드를 이용해도 무방했다. 프로 마이크로를 사용하게에는 보드의 성능의 너무 과분한 감이 있었다.
지금까지 미디 플레이어의 주된 코드는 2018/02/16 - [아두이노/프로젝트] - 아두이노 3채널 미디 오케스트라 의 글처럼 USBMIDI 라는 라이브러리를 기반으로 작동했다. 문제는 이 라이브러리가 HID 장비로 인식 가능한 레오나르도나 프로 마이크로에만 적용이 가능했기 때문에 slave들의 코드는 라이브러리를 사용하지 않고 새롭게 코드를 만들어야 했다.
미디신호를 tone()를 이용해 소리로 만들기 위해서는 미디 데이터를 주파수로 변환해야 한다. 이를 pitch to frequency라 하는데, 구글링을 해보니 자료를 어렵지 않게 구할 수 있었다.
음계가 수학적 규칙을 따르는 만큼 미디 데이터 또한 주파수로 어떠한 공식에 의해 변환이 가능할 것이고, 실제로 찾아보니 공식이 존재했다.
물론 위의 코드를 아두이노에 사용하기 위해서는 몇가지 수정이 필요하지만 직관적인 간단한 수식이다. 위 코드를 기반으로 제작한 코드는 아래와 같다.
[Mater(Pro micro)]
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 | /* 이 소스코드의 저작권은 http://diy-project.tistory.com/에 있습니다. 소스코드는 자유롭게 사용가능하지만 대회 및 상업적 목적으로 이용시에 반드시 출처를 밝혀야 합니다.*/ #include <Wire.h> #include <MIDIUSB.h> void setup() { Serial.begin(115200); Wire.begin(); } void loop() { midiEventPacket_t rx = MidiUSB.read(); byte buffer[4]; buffer[0]=rx.header; buffer[1]=rx.byte1 & 0xF; buffer[2]=rx.byte2; buffer[3]=rx.byte3; for (int i = 0; i <= 3; i++) { Serial.print(buffer[i]); Serial.print(" "); } Serial.println(" "); Wire.beginTransmission(Your slave address); Wire.write(buffer, 4); Wire.endTransmission(); /* Add more this code when you need. Wire.beginTransmission(Your slave address); Wire.write(buffer, 4); Wire.endTransmission(); */ } | cs |
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 | /* 이 소스코드의 저작권은 http://diy-project.tistory.com/에 있습니다. 소스코드는 자유롭게 사용가능하지만 대회 및 상업적 목적으로 이용시에 반드시 출처를 밝혀야 합니다.*/ #include <Wire.h> #include <math.h> #define BUZZ_PIN 4 int a = 440; void noteOn(byte channel, float pitch, byte velocity) { if (channel==your midi channel){ float Frequency = (a / 32) * pow(2, float((pitch - 9) / 12)); tone(BUZZ_PIN, Frequency); } } void noteOff(byte channel, byte pitch, byte velocity) { if (channel==your midi channel){ noTone(BUZZ_PIN); } } void controlChange(byte channel, byte control, byte value) { } byte Midi[4]; void setup() { Wire.begin(your midi address); Wire.onReceive(receiveEvent); Serial.begin(115200); } void loop() { } void receiveEvent(int howMany) { for (int i = 0; i < 4; i++) { Midi[i]=Wire.read(); } switch (Midi[0]) { case 0: break; case 0x9: noteOn( Midi[1], Midi[2], Midi[3] ); break; case 0x8: noteOff( Midi[1], Midi[2], Midi[3] ); break; case 0xB: controlChange( Midi[1], Midi[2], Midi[3] ); break; } } | cs |
코드에서 I2C 통신 주소나, MIDI 채널은 본인의 경우에 맞게 직접 수정하면 된다. 필자의 경우 slave 보드를 아두이노로 프로그래밍 가능한 제일 작은 보드에 속하는 Attiny85를 이용했다. Attiny85를 아두이노 스케치로 프로그래밍 하는 방법은 인터넷에 자세히 나와있으므로 일단은 생략한다. 다만 Attiny85에 올라갈 코어를 선택해야 하는데 몇몇 코어는 tone() 함수를 사용할 수 없어서 tone() 함수를 사용할 수 있는 코어를 찾아 부트로드 했다. 아래 링크를 참고하자.
https://github.com/SpenceKonde/ATTinyCore
우선 위의 github 링크에도 자세히 나와있듯
4번핀을 (소프트웨어적 4번 핀이다.) tone() 출력으로 사용이 가능하다고 한다.
이 코어를 추가하려면 아두이노 스케치에 http://drazzy.com/package_drazzy.com_index.json
를 추가하여 보드매니저를 통해 설치하면 된다. 나머지 부트로드 방식이나 설정은 일반적인 Attiny85를 아두이노에서 사용하는 방식을 그대로 따랐다.
연결은 아래의 핀맵을 참고했다.
이제 아래와 같이 회로를 꾸미면 된다. 꼭 Attiny85를 사용할 필요 없이 아두이노 IDE로 프로그래밍 가능한 다양한 보드를 이용할 수 있다.
slave로 사용된 Attiny85(또는 기타 보드들)는 필요한 개수만큼 같은 방법으로 추가하면 된다.
필자의 경우 채널 확인용 LED를 추가했다. 참고로 채널수는 5채널 이상은 별로 좋지 않다. 우선 전력이 매우 부족해지고 I2C 통신속도의 한계로 음악의 퀄리티도 별로이다. (실제로 10채널까지 테스트 해봤다.) 작동 영상은 아래를 참고하자.
현재는 PCB 발주를 위해 EasyEDA로 PCB를 제작하는 중이다. (2018/02/20 - [강좌] - PCB 제작 기초강좌 #1 [EasyEDA 소개] 글을 참고하자)
제작에 도움이 되는 글들은 아래와 같다.
2018/02/15 - [아두이노/기초] - 미디파일을 tone()으로 변환하기 [아두이노]
2018/02/16 - [아두이노/프로젝트] - 아두이노 3채널 미디 오케스트라
2018/08/27 - [아두이노/프로젝트] - 아두이노 다채널 미디 플레이어 제작 #1 - I2C 통신 테스트
2018/10/10 - [아두이노/프로젝트] - 아두이노 다채널 미디 플레이어 제작 #2 - 중간점검
2018/10/28 - [분류 전체보기] - 아두이노 다채널 미디 플레이어 제작 #3 - 5채널 테스트
'프로젝트 > 다채널 미디 플레이어' 카테고리의 다른 글
아두이노 다채널 미디 플레이어 연주 (0) | 2020.03.27 |
---|---|
아두이노 다채널 미디 플레이어 제작 #5 - PCB 발주 및 완성 (1) | 2019.01.10 |
아두이노 다채널 미디 플레이어 제작 #3 - 5채널 테스트 (0) | 2018.10.28 |
아두이노 다채널 미디 플레이어 제작 #2 - 중간점검 (3) | 2018.10.10 |
아두이노 다채널 미디 플레이어 제작 #1 - I2C 통신 테스트 (0) | 2018.08.27 |