컴플리트 MIDI 북을 보고 MIDI데이터 규격에 맞춰 아날로그 입력을 노트온벨러서티로 출력하도록 스케치를 작성했다. 아날로그 0번에 압력 감지 센서를 달고 그 값을 건반 누른 세기로 바꿔주면 끝나는 간단한 구조다
압력 감지 센서를 이용했지만, 가속도 센서를 이용하면 탬버린 등을 만들 수도 있을 것이며 다양한 센서를 이용해서 여러가지 음악 입력장치를 만들 수 있다.
----
// Variables:
byte note = 35; // 재생될 MIDI NOTE값
int AnalogValue = 0; // 아날로그 입력값
byte noteOnVel = 0; // 노트온벨러서티 값
boolean lastPlay = 0; // 눌린상태 체크
void setup() {
// Set MIDI baud rate:
Serial.begin(31250);
}
void loop() {
AnalogValue = analogRead(0); // 아날로그 입력 체크
noteOnVel = AnalogValue/8; // 1024->128로 변환
if (noteOnVel > 0){ // 눌린 값이 있나?
if(lastPlay==0){ // 기존에 눌리지 않았다면
noteOn(0x90, note, noteOnVel); // 0채널 note값에 눌린값의 세기로 출력
lastPlay = 1; // 이미 눌렸다
}
} else { // 손을 뗐으면 다시 리셋
lastPlay = 0;
}
delay(5); //반응속도에 따라 값 조정 할 것.
}
// plays a MIDI note. Doesn't check to see that
// cmd is greater than 127, or that data values are less than 127:
void noteOn(byte cmd, byte data1, byte data2) {
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
}
흠 여러 조건을 넣으려고 if를 중복으로 썼는데, 하나 밖에 없으니 한 줄로 줄여도 되겠다. 그러고 보니 입력 종료 알리는 커맨드를 안 넣어줬네. 중복으로 놔둬야겠다.
기존에 구입한 CP2102 칩을 사용한 USB-UART 컨버터는 전원과 TX,RX만을 뽑아주게 되어있다. 하지만, 아두이노에 데이터를 업로드하곤 리셋을 걸어줄 필요가 있는데 이것을 담당하는 게 DTR이다. 칩셋에는 준비되어있지만, 실제로 사용하진 않고 있어서 직접 선을 뽑아주기로 결정했다.
아래는 데이터 시트에 나와있는 핀배치도. 28번 핀이 이번에 필요한 DTR이다.
적당한 선을 골라 납을 잘 먹이고 잘 구부린 다음 핀에 대놓고 인두로 살짝 눌러줬다.
이제 M168에서 리셋을 못 걸어줘서 에러가 뜨던 것이 제대로 동작하는지 테스트. 문제 없이 동작한다.
다이오드의 정류작용에서 콘덴서와 코일의 평활회로 쪽을 살펴보려면 교류->맥류를 만들어야한다. 그렇다고 220V를 연결할 수도 없고해서, 모터 2개를 서로 벨트로 묶어주고 한쪽에 전원을 연결해줬다. 반대쪽은 발전을 하게 된다. 결과적으로 모터가 돌면서 교류는 아니더라도 맥류는 나오게 되었다. 다이오드의 정류작용은 패스하고 바로 콘덴서와 코일로 테스트 하면 된다.
마이크로 컨트롤러에 큰 부하를 걸지 않고 외부 장치를 제어하려니 가장 간단한 방법은 트랜지스터를 이용하는 것이다. NPN 트랜지스터를 하나 빵판에 끼우고, 에미터와 콜렉터에 레이저 모듈을 전원 5V를 넣고 물려줬다. 그리곤 베이스와 에미터에 1.2V 전기를 넣었다 뺐다 하면 에미터와 콜렉터에 연결된 레이저 모듈이 켜졌다 꺼졌다 한다.
즉, 1.2V 전지로 5V로 돌아가는 녀석을 컨트롤할 수 있는 예다. (더 차이가 큰 전원도 가능하다)
TR의 어디를 공통 접지하느냐에 따라 입출력 임피던스 차/증폭 정도 차가 발생하니 회로에 맞춰 적절히 테스트 해보면 될듯하다.
BEEs실드가 두개가 동시에 불량이 나거나, xBEE가 두개가 동시에 불량이 날리는 없을테고.. 동작등은 들어오는데 직접 USB-UART로 RX-TX연결해서 터미널로 커맨드를 보내도 반응이 없는 것으로 봐서는... xBEE세팅을 해야 동작할 것으로 보인다.
그러려면 좀 좋은(?) USB-UART 변환장치가 필요하다. 예전에 멋도 모르고 사놓은 건 단순히 데이터 전송용으로 밖에 못쓰는 것이다. 하나사야하나 하고 이리저리 살펴보던 중 xBEE 수입처가 회사 근처에 있는 것을 발견했다. 낼 직접 들고가서 뭐가 문젠지 파악하고 와야겠다. 펌웨어도 최신으로 업데이트 하고, 이런 저런 자료나 받아와야겠다. 나중을 위해서라도 FTDI USB 시리얼 변환기는 하나 사야겠지만, 일단 급한 불은 끌 수 있을듯.
I2C (Inter Intergrated Circuit)를 이용하면 아무래도 2개의 데이터 케이블로 주변기기를 제어할 수 있으므로 여러가지 기능을 수행하는 장치를 만들 때 핀의 낭비가 없어서 유용하다. CuBLOC에서 I2C를 이용한 CLCD를 구해놓은 게 있어서 지난번에 직접 4bit모드로 연결했던 것을 I2C로 테스트 해봤다.
하지만, 아직까진 잘 모르겠다. 좀더 공부해 봐야할듯.
재밌는 것은 시리얼 통신에서도 드라이버에 따라 엉망인 데이터를 내던 JAPANINO는 I2C환경에서도 노이즈에 취약한 모습을 보이고 있다. PC측 마우스의 움직임이나 화면 스크롤에 따라 디스플레이에 노이즈가 발생하거나 리셋되는 모습을 보인다. 동일한 조건에서 Seedino에서는 외부 환경의 노이즈를 필터링해서 깔끔하게 동작하고 있다. 역시 번들은 한계가 있는듯.
아두이노를 ISP(In System Programmer)로 이용해 다른 아두이노에 부트로더를 심을 수 있다고 지난번에 소개했다. 문제는 타겟의 설정인데, 각켄 재패니노를 타겟으로 설정하고 부트로더를 심었더니 스케치를 업로드하고 약 10여초의 딜레이 후 동작하는 것을 발견했다.
그래서 개발환경의 hardware\arduino 폴더 안에 있는 boards.txt를 살펴보니 LilyPadBOOT_168.hex 를 불러오게 되어있었다.
이를 무시하고 Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168를 타겟으로 설정하고 부트로더를 심어줬더니 딜레이가 사라졌다.
아두이노와 CLCD를 연결하면 여러가지 내부 정보를 바로 눈으로 확인 할 수 있어서 편리하다. CuBLOC에서 사용하던 CLCD가 있어서 그것을 이용하기로 맘 먹었다. 모델명은 LC2042-SFLYH6다.
일단 스펙.
이전에 만든 것이 시리얼 통신 중에 오류가 났기 때문에 내부 문제인지, 전송 문제인지를 찾기 위해서 CLCD를 사용하는 것이 목적이었으므로, 가능한 아두이노와 CLCD를 연겨할 때 사용할 핀 수를 줄여야 유리하다. 데이터 전송에는 8bit모드와 4bit모드가 있는데 전자는 8개의 데이터를 보내서 표시하는 것, 후자는 4개의 데이터를 보내서 표시하는 것이다. 일단 4bit모드로 만들기로 하고 위의 것을 살펴보면 다음과 같이 나와있다.
DB0~DB3 : in 4-bit mod. open these terminals. (4bit 모드로 사용할 땐 연결하지 말라는 의미)
따라서 데이터 전송은 DB4~DB7 즉 11~14번 핀을 이용해야한다. 물론, 이번에 사용한 CLCD에 한한 내용이다. 메이커나 제품에 따라 핀 배열이나 성능이 다를 수 있으므로, 자신이 사용하는 CLCD 모델명을 확인하고 해당 데이터 시트를 찾아 확인해야 한다.
아두이노에는 LCD를 위한 명령어들이 준비되어있는데, #include <LiquidCrystal.h>를 스케치 상단에 적어 놓는 것으로 불러올 수 있다. 이 파일은 아두이노 개발환경(IDE)의 \libraries\LiquidCrystal 폴더에 들어있다.
무엇을 의미하냐면, 아두이노 스케치에 LiquidCrystal(rs해당 핀 번호, rw해당 핀 번호, enable해당 핀 번호, D0해당 핀번 호,~,D3해당 핀 번호); 를 써 주면 된다는 것이고, 거기에 적은대로 아두이노와 CLCD를 직접 전선으로 연결해주면 된단 의미다.
이전 구성에서 A0, A1, D2, D3를 사용하고 있었으므로 이것을 피해서 연결해주기로 맘 먹고 그 외의 핀을 할당했다..
LiquidCrystal lcd(5, 6, 7, 9, 10, 11, 12);
와 같이 아두이노 5, 6,7, 9, 10, 11, 12번 핀과 CLCD 해당 핀을 서로 연결해 준다.
여기서 CLCD 3번 핀은 LCD의 컨트라스트를 조정하는 것인데, 일단 GND에 연결해 준다. 3번 핀을 가변저항 중간 단자에 붙이고 나머지 양 옆의 단자를 +,-에 연결해 주면 가변 저항을 돌리는 것으로 컨트라스트를 조절하게 만들 수도 있다. 아니라면 아날로그 출력을 이용해서 아두이노에서 컨트롤 할 수도 있을 것 같다.
15, 16번 핀은 백라이트이므로 전원에 바로 물려줬다.
사용법은 간단하다.
lcd.print(변수, 변수 형태); lcd.print("직접입력");
과 같이 이용하면 된다. 그 외에도 여러 명령이 준비되어 있는데, 이것은 LiquidCrystal.h를 살펴보면 잘 나와 있다.
예를 들자면 화면을 지우려면 lcd.clear(); 화면의 맨 위로 이동시키려면 lcd.home();라고 쓰면 된다.
감이 잡히는가? lcd.setCursor(가로, 세로); 명령으로 원하는 위치에 커서를 이동시켜 놓고, 그 위치에서 글자를 나오게 할 수 있다. 여기서 가로, 세로 값은 맨 왼쪽 위가 (0,0)이고, 맨 오른쪽 아래가 (19,3)이므로 그에 따라 적절히 값을 넣으면 된다.