아두이노 우노 : LED Matrix Spectrum Effect
8x8 LED Matrix 에서 기본적인 스펙트럼 효과
를 만드는 코드를 소개합니다.오디오 스펙트럼 구현
Audio Spectrum Visualizer 를 만들기 위해 아래의 단계가 필요하다고 예상하고 진행하면서 포스트를 진행해 나갈 예정입니다. 최대한 가능한한 아두이노의 코드만으로 구현을 하려고 합니다. 직장과 육아로 언제 할 수 있을지 모르겠지만, 천천이라고 관련 포스트를 작성해서 올릴 예정입니다. 최종적으로는 RGB LED Matrix 로 구현해보고 싶지만, 진행 상황을 보고 결정해야 할 것 같습니다.
Audio Spectrum Visualizer
구현 단계
- 8x8 LED Matrix 에서 기본적인 Spectrum 효과 구현
- 32x8 LED Matrix 로 확장 후 동작 테스트
- 32x8 LED Matrix 에서 Spectrum 효과 구현 및 퍼포먼스 체크
- 마이크 또는 오디오 입력 데이터 신호 수집
- 오디오 신호 FFT 처리
- 오디오 신호 FFT 처리 값을 32x8 LED Matrix 의 Spectrum 효과로 반영
예상 되는 문제점
- Arduino Uno 보드에서 Arduino Code 로만 작성할 경우 구현 할 수 있는 한계
- 직장 생활과 육아로 부족한 시간이 없음, 아기가 잘 때만 작업을 할 수 있어 오디오를 틀 수가 없음
Hardware
준비물
본 예제의 구성품은 아래와 같습니다.
- Arduino Uno x 1 EA
- 8x8 LED Matrix x 1 EA
- Resistor x 8EA
- Bread Board x 1EA
- Jumper WIres
회로도 및 연결
아두이노 8x8 LED Matrix 연결 회로도
회로도 참고사항은 아래와 같습니다.
- Arduino Uno 와 LED Matrix 연결 핀은 모두 출력 포트로 설정
- 저는 LED Matrix 출력 방법을 한 행(Row)씩 출력하는 방법을 사용하고 있어, Column 핀에 저항을 연결
예제1 : Spectrum Effect basic
예제1은 오디오가 FFT 처리되어 오디오의 각 주파수 대역별로 진폭 처리한 데이터가 있다고 가정하고, LED Matrix 에 스펙트럼 효과를 만드는 예제입니다. 스펙트럼의 높이 값은 Random() 함수를 사용하여 구현 하였습니다.
코드
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 | #define SCROLLTIME 100 // 새로운 스펙트럼이 반영되는 스피드 /* 8x8 LED Matrix Pin Mapping */ #define C1 9 #define C2 12 #define C3 7 #define C4 13 #define C5 A2 #define C6 6 #define C7 3 #define C8 A5 #define R1 2 #define R2 11 #define R3 10 #define R4 A4 #define R5 8 #define R6 A3 #define R7 4 #define R8 5 /* 8x8 LED Pin 출력 코드 작성을 간단하게 하기 위해 배열로 처리 */ int colPin[8] = {C1, C2, C3, C4, C5, C6, C7, C8}; int rowPin[8] = {R1, R2, R3, R4, R5, R6, R7, R8}; /* 8x8 LDM 출력 버퍼 */ byte displayData[8][8]; /* 새로운 스펙트럼이 반영되는 스피드 */ int scrollTime = SCROLLTIME; void setup() { /* GPIO Init */ for(int i = 0 ; i < 8 ; i++) { pinMode(colPin[i], OUTPUT); digitalWrite(colPin[i], LOW); // Column 핀은 LOW 로 초기화 pinMode(rowPin[i], OUTPUT); digitalWrite(rowPin[i], HIGH); // Row 핀은 HIGH 로 초기화 } } void loop() { unsigned long now = millis(); static unsigned long pastTime; /* 새로운 스펙트럼이 반영 되는 시간에 호출 되는 함수*/ if(now - pastTime >= scrollTime){ pastTime = now; makeSpectrum(); } /* 8x8 LDM 출력 버퍼의 데이터를 LDM으로 출력 */ for(int i = 0 ; i < 8 ; i++) { for(int j = 0 ; j < 8 ; j++) { digitalWrite(colPin[j], displayData[i][j]); // Column 핀에 데이터 쓰기 } digitalWrite(rowPin[i], LOW); // i LOW 켜기 delayMicroseconds(100); // LED ON 시간 조정 digitalWrite(rowPin[i], HIGH); // i LOW 끄기 -> 모든 LED 끄기 } } /* 새로운 스펙트럼 데이터를 출력 버퍼에 저장 */ void makeSpectrum(){ byte temp; for(int i = 0; i < 8 ; i++){ temp = random(7); for(int j = 0; j < 8 ; j++){ displayData[7-j][i] = 0; if(j <= temp) displayData[7-j][i] = 1; } } } | cs |
코드 설명
대부분의 코드는 하단에 링크한 8x8 LED Matrix 관련 포스트의 내용과 비슷하며, Spectrum 효과를 만들기 위해 66 Line 이후 스펙트럼 데이터를 만드는 함수를 작성하였습니다.
- 69 Line :
temp변수는 0 ~ 6 사이의 랜덤 값을 저장합니다. - 71 Line : 이전에 저장된 8x8 LED Matrix 출력버퍼인
displayData[]배열의 값을 '0'으로 초기화 합니다. - 72 Line :
7-j행의 에서 0~7열(Column) 중에 temp 값보다 낮는 열(Column)의 좌표 값이 1을 저장합니다.
실행 결과
Random 값으로 추출한 결과라서 정신없어 보이긴 하지만, 의도한 대로 LED Matrix 가 정상적으로 동작합니다.
예제2 : 스펙트럼 Max Hold 기능 추가
예제1의 스펙트럼에서 Max Hold 기능을 추가하였습니다. Max Hold는 일정 시간 동안 각 주파수 밴드의 최고 값을 저장하는 기능입니다. Max Hold 라는 명칭은 따로 없고, 제가 설명하기 위해 만들어낸 용어 입니다.
코드
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 | #define SCROLLTIME 100 // 새로운 스펙트럼이 반영되는 스피드 #define MAXHOLDTIME 3 // Maxhold 를 유지하는 간격 /* 8x8 LED Matrix Pin Mapping */ #define C1 9 #define C2 12 #define C3 7 #define C4 13 #define C5 A2 #define C6 6 #define C7 3 #define C8 A5 #define R1 2 #define R2 11 #define R3 10 #define R4 A4 #define R5 8 #define R6 A3 #define R7 4 #define R8 5 /* 8x8 LED Pin 출력 코드 작성을 간단하게 하기 위해 배열로 처리 */ int colPin[8] = {C1, C2, C3, C4, C5, C6, C7, C8}; int rowPin[8] = {R1, R2, R3, R4, R5, R6, R7, R8}; /* 8x8 LDM 출력 버퍼 */ byte displayData[8][8]; /* 새로운 스펙트럼이 반영되는 스피드 */ int scrollTime = SCROLLTIME; int maxHoldTime = MAXHOLDTIME; void setup() { /* GPIO Init */ for(int i = 0 ; i < 8 ; i++) { pinMode(colPin[i], OUTPUT); digitalWrite(colPin[i], LOW); // Column 핀은 LOW 로 초기화 pinMode(rowPin[i], OUTPUT); digitalWrite(rowPin[i], HIGH); // Row 핀은 HIGH 로 초기화 } } void loop() { unsigned long now = millis(); static unsigned long pastTime; /* 새로운 스펙트럼이 반영 되는 시간에 호출 되는 함수*/ if(now - pastTime >= scrollTime){ pastTime = now; makeSpectrum(); } /* 8x8 LDM 출력 버퍼의 데이터를 LDM으로 출력 */ for(int i = 0 ; i < 8 ; i++) { for(int j = 0 ; j < 8 ; j++) { digitalWrite(colPin[j], displayData[i][j]); // Column 핀에 데이터 쓰기 } digitalWrite(rowPin[i], LOW); // i LOW 켜기 delayMicroseconds(100); digitalWrite(rowPin[i], HIGH); // i LOW 끄기 -> 모든 LED 끄기 } } /* 새로운 스펙트럼 데이터를 출력 버퍼에 저장 */ void makeSpectrum(){ static int count; byte temp; static byte maxHold[8]; // 최대 값을 저장하기 위한 배열 for(int i = 0; i < 8 ; i++){ temp = random(7); if(maxHold[i] < temp) maxHold[i] = temp; // 최대 값을 저장 for(int j = 0; j < 8 ; j++){ displayData[7-j][i] = 0; if(j == maxHold[i]) displayData[7-j][i] = 1; // 최대 갑과 같은 행의 데이터만 1로 설정 } } count++; /* makeSpectrum 이 3번 실행 될떄마다 maxHold 의 값을 초기화 */ if(count == maxHoldTime){ count = 0; for(int i = 0;i < 8;i++) maxHold[i] = { 0, }; } } | cs |
코드 설명
지난 코드에서 주요하게 추가되 내용은 68 Line 이하의 makerSpectrum() 함수 내부 입니다.
- 71 Line : 각 주파수 밴드의 최대 값을 저장할 배열을 선언
- 75 Line :
Random()함수로 생성된 수의 최대 값을 저장 - 77 Line : 8x8 LED Matrix 출력 버퍼 0으로 초기화
- 78 Line : 8x8 LED Matrix 출력 버퍼의 각 열에서 최대값과 일치하는 행만 1로 초기화
실행 결과
위 코드를 실행하면 아래와 같이 최대 값만 LED 매트릭스에 출력됩니다.
마무리
32x8 LED Matrix 사용법, Audio 신호 입력 방법, Audio 신호 FFT 처리
를 추가적으로 진행하면서 후속 포스트를 이어 나갈 예정입니다.끝까지 읽어 주셔서 감사합니다.😊
'Embedded > Arduino' 카테고리의 다른 글
아두이노 강좌 #28 2차원 배열 PROGMEM 매크로 사용 방법 (0) | 2020.08.26 |
---|---|
아두이노 강좌 #27 동적 메모리 용량 부족 문제 PROGMEM F() 메크로로 해결 (1) | 2020.08.25 |
아두이노 강좌 #26 8x8 LED 매트릭스 문자열 스크롤 하기 (0) | 2020.08.22 |
아두이노 강좌 #25 8x8 LED Dot Matrix Scroll 문자 스크롤 하기 (0) | 2020.08.21 |
아두이노 강좌 #24 8x8 LED Dot Matrix 내부 구성과 기본 동작 방법 (0) | 2020.08.17 |