프로젝트 소개
오늘은 아두이노를 이용해 OLED 스펙트럼 분석기를 만들어보겠습니다. 이 분석기는 0-3.3V 아날로그 입력으로 작동하며 매우 부드럽고 선명한 오디오 주파수를 시각화합니다. DVD 음악 플레이어, 아이팟, MP3 플레이어 등 다양한 오디오 장치에서 사용할 수 있는 이 분석기는 모든 종류의 음악을 시각적으로 표현할 수 있습니다. 이 프로젝트는 브레드보드에서 간단하게 만들 수 있습니다.
필요 부품
- 아두이노 나노 또는 아두이노 우노
- 128x64 I2C OLED 디스플레이
- 점퍼 와이어
- 브레드보드
SSD1306 OLED 디스플레이
이 디스플레이는 I2C 2선식 인터페이스를 사용하여 아두이노와 연결됩니다. 크기는 0.96인치로, 128x64 픽셀 해상도를 가지고 있습니다. OLED는 유기 발광 다이오드를 의미하며, 백라이트 핀이 필요하지 않습니다.
연결 방법
Vin | 5V (전원) |
GND | GND (접지) |
SCL | A5 (I2C 핀) |
SDA | A4 (I2C 핀) |
아두이노 모델에 따른 I2C 핀 배치:
- Arduino Uno/Nano: SDA (A4), SCL (A5)
- Arduino Leonardo/Mega: SDA (20), SCL (21)
사용 라이브러리
- Adafruit SSD1306 라이브러리
- Adafruit GFX 라이브러리
이 라이브러리들은 Github에서 다운로드할 수 있으며, Arduino IDE의 라이브러리 매니저를 통해 설치할 수 있습니다.
연결 방법
브레드보드를 이용해 간단하게 OLED와 아두이노를 연결합니다.
소스 코드
아래는 SSD1306 OLED 디스플레이를 사용한 전체 코드입니다.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
// 초기화
if(!display.begin(SSD1306_I2C_ADDRESS, OLED_RESET)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.display();
delay(2000); // 디스플레이 부팅 딜레이
// 디스플레이 클리어
display.clearDisplay();
// 텍스트 설정
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,0);
display.print(F("Hello, world!"));
display.display();
}
void loop() {
// 스펙트럼 분석 코드 추가 예정
}
이 코드에서는 기본적인 OLED 초기화 및 텍스트 출력을 포함하고 있습니다. 여기서 추가적으로 오디오 주파수 시각화 코드를 작성하면 됩니다.
참고: 이 프로젝트는 다음을 위한 것입니다. 간단한 오디오 장치, 실제 스펙트럼 분석기 장치는 전자 레인지에 사용됩니다. 신호, 레이더 신호, 접시 안테나 신호, 케이블 주파수 신호 등 하다 Arduino가 영구적으로 타거나 충돌할 것이라고 제안하는 이러한 것을 사용하려고 하지 마십시오.
이 블로그에서는 Arduino Spectrum에 대해 배웁니다 다음과 같은 분석기:
>>SSD1306 OLED 디스플레이
>>필요한 부품
>>우리가 사용해야 하는 라이브러리
>>매우 쉬운 브레드보드 연결
>>전체 코드
SSD1306 OLED 디스플레이 :
Arduino를 위한 이 매우 일반적이고 간단한 OLED 디스플레이 I2C 2선식이라고 하는 arduino에서 연결할 핀의 수가 매우 적습니다. I2C는 인터페이스(I2C=IIC=Inter-Integrated Circuit)이고 OLED는 약자입니다. 유기 발광 다이오드용. 이 OLED 디스플레이의 크기는 0.96인치입니다. 너무 작게 만들고 총 픽셀은 128X64 픽셀 해상도입니다. 사진을 비트맵으로 변환하고 이 디스플레이에 표시할 프로그램을 프로그래밍합니다. 16X2 LCD에서 디스플레이 백라이트 핀이 필요하지만 OLED에서는 이 핀이 필요하지 않습니다.
OLED 핀 : 아두이노 핀
Vin | 5V는 전원 핀
GND입니다 | GND //이것은 GND 핀
SCL입니다 | A5 이것은 I2C 핀
SDA입니다 | A4 이것은 I2C 핀입니다.
Arduino 핀의 종류 사용하는 경우 :
Arduino Uno : SDA (A4), SCL (A5)
아두이노 나노: SDA (A4), SCL (A5)
아두이노 레오나르도: SDA (20), SCL (21)
아두이노 메가: SDA (20), SCL (21)
필요한 부속:
아두이노 우노
128x68 I2C OLED 디스플레이
점퍼 와이어
브레드보드
이 프로젝트에 사용된 라이브러리:
이 프로젝트의 초보자라면 다음을 수행해야 합니다. Github에서 사용할 수 있는 Adafruit SSD1306 Master zip Library SSD1306 다운로드 또한 다음에서도 사용할 수 있는 Adafruit GFX 라이브러리 master.zip 하나 더 필요합니다. 깃허브. Arduino IDE 소프트웨어를 열고 스케치 탭으로 이동 한 다음 여기에서 포함을 클릭하십시오. 라이브러리를 클릭하고 Add Zip Library(Zip 라이브러리 추가)를 클릭하면 다운로드한 라이브러리를 추가할 수 있습니다. 또한 Manage Library Option에서 다운로드하여 설치할 수 있습니다. 이 상자의 라이브러리.
이제 이 프로젝트를 위해 FIX_FFT.h를 다운로드해야 합니다. fix_fft.h 및 nano_engine.h 라이브러리의 마스터 zip 여기 나노 엔진 (이것은 SSD1306의 내장 헤더 파일입니다).
브레드보드 연결:
오디오 입력:
전체 코드:
// Copyright [2019] [colonelwatch]
#include <fix_fft.h> // 8-bit FFT library modified for Arduino
#include <ssd1306.h> // library for OLED
#include <nano_engine.h> // library for nanoengine (which draws sector-by-sector on OLED because the ATtiny85 can't hold a full buffer)
// To get this program to operate, the SDA and SCL pins must be reassigned to 0 and 2 respectively in the library header file
// The file is located in libraries\ssd1306\src\intf\i2c\ssd1306_i2c_conf.h
// Make sure to undo this if the library will be used again in the future
// These are user-adjustable
//#define LOG_OUTPUT // Uncomment to enable logarithmic output (exchanges absolute resoluton for more readable output; may require different below params)
#define SAMPLING_FREQUENCY 15000 // Sampling frequency (Actual max measured frequency captured is half)
#define TIME_FACTOR 3 // Smoothing factor (lower is more dynamic, higher is smoother) ranging from 1 to 10+
#define SCALE_FACTOR 12 // Direct scaling factor (raise for higher bars, lower for shorter bars)
#ifdef LOG_OUTPUT
const float log_scale = 64./log(64./SCALE_FACTOR + 1.); // Attempts to create an equivalent to SCALE_FACTOR for log function
#endif
const float coeff = 1./TIME_FACTOR; // Time smoothing coefficients (used to factor in previous data)
const float anti_coeff = (TIME_FACTOR-1.)/TIME_FACTOR;
const unsigned int sampling_period_us = round(1000000 * (2.0 / SAMPLING_FREQUENCY)); // Sampling period (doubled to account for overclock)
int8_t data[64], buff[32]; // used to store FFT input/output and past data
unsigned long microseconds; // used for timekeeping
int summ, avg; // used for DC bias elimination
NanoEngine<TILE_32x32_MONO> engine; // declares nanoengine
void setup()
{
OSCCAL = 240; // Overclocks the MCU to around 30 MHz, set lower if this causes instability, raise if you can/want
ADCSRA &= ~(bit (ADPS0) | bit (ADPS1) | bit (ADPS2)); // clear ADC prescaler bits
ADCSRA |= bit (ADPS2); // sets ADC clock in excess of 10kHz
ADCSRA |= bit (ADPS0);
ssd1306_128x64_i2c_init(); // initializes OLED
ssd1306_clearScreen(); // clears OLED
engine.begin(); // inititalizes nanoengine
};
void loop()
{
summ = 0;
for (int i = 0; i < 64; i++) {
microseconds = micros();
data[i] = ((analogRead(A0)) >> 2) - 128; // Fitting analogRead data (range:0 - 1023) to int8_t array (range:-128 - 127)
summ += data[i];
while (micros() < (microseconds + sampling_period_us)) { // Timing out uC ADC to fulfill sampling frequency requirement
}
}
// Eliminating remaining DC component (produces usable data in FFT bin #0, which is usually swamped by DC bias)
avg = summ/64;
for (int i = 0; i < 64; i++){
data[i] -= avg;
}
fix_fftr(data, 6, 0); // Performing real FFT
// Time smoothing by user-determined factor and user-determined scaling
for(int count = 0; count < 32; count++){
if(data[count] < 0) data[count] = 0; // Eliminating negative output of fix_fftr
#ifdef LOG_OUTPUT
else data[count] = log_scale*log((float)(data[count]+1)); // Logarithmic function equivalent to SCALING_FACTOR*log2(x+1)
#else
else data[count] *= SCALE_FACTOR; // Linear scaling up according to SCALE_FACTOR
#endif
data[count] = (float)buff[count] * anti_coeff + (float)data[count] * coeff; // Smoothing by factoring in past data
buff[count] = data[count]; // Storing current output as next frame's past data
if(data[count] > 63) data[count] = 63; // Capping output at screen height
}
// Output to SSD1306 using nanoengine canvas from library
engine.refresh(); // Mark entire screen to be refreshed
engine.canvas.clear(); // Clear canvas as previous data
for(int i = 0; i < 8; i++){
engine.canvas.drawVLine(i*4,31-(data[i]+1),31); // Draw to canvas data for lower-leftest sector (FFT bins 0 - 7, lower half)
}
engine.canvas.blt(0,32); // Outputs canvas to OLED with an offset (x pixels, y pixels)
engine.canvas.clear();
for(int i = 0; i < 8; i++){
if(data[i] > 31) engine.canvas.drawVLine(i*4,31-(data[i]-31),31); // Draw to canvas data for upper-leftest sector (FFT bins 0 - 7, upper half)
}
engine.canvas.blt(0,0);
engine.canvas.clear();
for(int i = 8; i < 16; i++){
engine.canvas.drawVLine((i-8)*4,31-(data[i]+1),31); // FFT bins 8 - 15, lower half
}
engine.canvas.blt(32,32);
engine.canvas.clear();
for(int i = 8; i < 16; i++){
if(data[i] > 31) engine.canvas.drawVLine((i-8)*4,31-(data[i]-31),31); // FFT bins 9 - 15, upper half
}
engine.canvas.blt(32,0);
engine.canvas.clear();
for(int i = 16; i < 24; i++){
engine.canvas.drawVLine((i-16)*4,31-(data[i]+1),31); // FFT bins 16 - 23, lower half
}
engine.canvas.blt(64,32);
engine.canvas.clear();
for(int i = 16; i < 24; i++){
if(data[i] > 31) engine.canvas.drawVLine((i-16)*4,31-(data[i]-31),31); // FFT bins 16 - 23, upper half
}
engine.canvas.blt(64,0);
engine.canvas.clear();
for(int i = 24; i < 32; i++){
engine.canvas.drawVLine((i-24)*4,31-(data[i]+1),31); // FFT bins 24 - 31, lower half
}
engine.canvas.blt(96,32);
engine.canvas.clear();
for(int i = 24; i < 32; i++){
if(data[i] > 31) engine.canvas.drawVLine((i-24)*4,31-(data[i]-31),31); // FFT bins 24 - 31, upper half
}
engine.canvas.blt(96,0);
}
'아두이노' 카테고리의 다른 글
혁신과 지속 가능성을 위한 프로젝트: PET 플라스틱 재활용 필라멘트 기계 (1) | 2024.10.18 |
---|---|
Arduino 및 시리얼 시프트 레지스터를 이용한 피크 앤 홀드 기능이 있는 최고의 스테레오 VU 미터 (9) | 2024.10.17 |
DIY Arduino MPPT 태양광 충전 컨트롤러 (1) | 2024.10.17 |
아두이노 러닝맨 만들기 (5) | 2024.10.07 |
컬러 실크스크린으로 맞춤형 Arduino Uno 만들기 (3) | 2024.10.04 |