프로젝트 소개
친구들, 오늘은 Ultimate Arduino 및 74HC595 IC를 사용하는 부드러운 VU 미터를 만들어보겠습니다. 이 스테레오 VU 미터는 두 개의 아날로그 입력을 통해 작동하며, 각각의 스테레오 채널(왼쪽 및 오른쪽)에 대한 아날로그 값에 따라 반응합니다. 각각의 LED는 특정 아날로그 값에 대응합니다. Studio 장비처럼 작동하며, 피크 앤 홀드 기능으로 실시간 피크를 보여줍니다.
필요한 부품
- Arduino 마이크로컨트롤러 (Nano 또는 Uno 등)
- 8x 10 LED 세그먼트 막대 그래프 LED
- 10x 74HC595 IC 시리얼 시프트 레지스터
- 40x 220옴 레지스터
- 1x PCB 보드
- 3x 2 핀 커넥터
- 1x 104J 커패시터
- 1x 1000uF 또는 470uF 커패시터 (25V)
- 일부 전선
- 납땜 스테이션 및 도구
작동 방식
VU(Volume Unit) 미터는 오디오 장비의 신호 레벨을 표시하는 오디오 측정 장치입니다. 오디오 신호의 음량을 시각적으로 나타내며, 일관된 오디오 신호를 모니터링하는 데 적합합니다.
구성 요소 설명
- 오디오 입력: 오디오 소스에서 직접 오디오 신호를 가져옵니다. 각 채널의 오디오 신호는 별도의 아날로그 핀(A0 및 A1)에 공급됩니다.
- 신호 컨디셔닝: 각 오디오 입력은 노이즈 감소를 위해 아날로그 필터 회로에 연결됩니다.
- 아날로그 읽기: Arduino는 A0 및 A1 핀의 아날로그 입력 값을 읽습니다.
- 피크 감지: 피크 감지 기능은 주어진 기간 동안 가장 높은 값을 캡처하여 "피크 홀드" 기능을 에뮬레이트합니다.
- 스케일링 및 매핑: 아날로그 값은 LED 디스플레이를 구동하기에 적합한 범위로 매핑됩니다.
- LED 디스플레이: 처리된 값은 LED의 켜짐 상태를 결정합니다. Arduino는 74HC595 시프트 레지스터를 사용하여 LED를 제어합니다.
- 피크 홀드: 가장 높은 LED가 짧은 시간 동안 켜져서 가장 높은 오디오 레벨을 시각적으로 표시합니다.
회로 다이어그램
회로도를 만드는 것은 두 부분으로 나뉩니다. 첫 번째 부분은 메인 VU 미터 드라이버 회로이고, 두 번째 부분은 원치 않는 소음을 줄이는 조정 가능한 오디오 필터 회로입니다.
연결 방법
- Arduino와 74HC595 연결:
- 데이터 핀 (DS) -> Arduino 핀 11
- 시계 핀 (SH_CP) -> Arduino 핀 12
- 저장 레지스터 시계 핀 (ST_CP) -> Arduino 핀 8
- LED 및 저항 연결:
- 각 LED에 220옴 저항을 연결하여 전류를 제한
소스 코드 예시
#include <ShiftOut.h>
const int dataPin = 11;
const int clockPin = 12;
const int latchPin = 8;
void setup() {
pinMode(latchPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
int leftChannel = analogRead(A0);
int rightChannel = analogRead(A1);
// 피크 감지 및 매핑 로직 추가
int peakLeft = map(leftChannel, 0, 1023, 0, 255);
int peakRight = map(rightChannel, 0, 1023, 0, 255);
updateVU(peakLeft, peakRight);
}
void updateVU(int left, int right) {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, left);
shiftOut(dataPin, clockPin, right);
digitalWrite(latchPin, HIGH);
}
이 Arduino 기반 VU 미터 프로젝트는 시각적으로 매력적이고 기능적인 오디오 모니터링 방법을 제공합니다. 리얼타임 피드백을 통해 오디오 신호의 진폭을 정확하게 시각화할 수 있습니다.
이 블로그 게시물에서 친구, 저는 Ultimate를 만들고 있습니다. Arduino 및 74HC595 IC(집적 회로) 또는 시리얼을 사용하는 부드러운 VU 미터 시프트 레지스터 IC. 두 개의 아날로그 입력과 함께 작동하는 스테레오 VU 미터입니다. 스테레오 채널(왼쪽 및 오른쪽) 모두에 대해 아날로그 값으로 응답합니다. Arduino의 데시벨 값에 대한 적절한 Map 기능. 응답하는 40개의 LED가 있습니다. 각 LED에 해당하는 아날로그 값으로. 나는 많은 VU 미터를 보았고 시도한다. 모든 VU 미터가 효율적이고 매끄럽고 언젠가는 깜박이는 것은 아닙니다. 그리고 헤이즈 효과, 그래서 나는 Studio처럼 작동하는 것을 직접 만들기로 결정했습니다. 장비 유형 및 실제 스튜디오 오디오 장비와 같은 시각화 앰프, 오디오 믹싱 콘솔, 마이크 튜너, 오디오 인터페이스, MIDI 컨트롤러 및 더 많은 것 (나는 또한 여기에서 아이디어를 얻고 그것에 대해 매우 궁금합니다. 나는 오디오 DIY 물건을 너무 좋아해서 나도 나와 함께 조정하고 내 구독을 유지하십시오. 채널). 그것은 피크 앤 홀드 기능으로 이어지며 실시간 피크를 보여줍니다. 각 LED에서 1초 동안 값을 느리게(1초 시간에 따라 다름) 진행합니다. 시작 LED까지.
당신은 또한 당신과 함께 즐길 수 있습니다 홈 시어터 또는 홈 DJ 시스템이지만 볼륨을 너무 많이 높이지 마십시오. 흥분; 그렇지 않으면 다른 사람의 집 유리를 깨뜨릴 수 있습니다(만약 당신이 집에 DJ가 있음). 그러니 만들어 봅시다 1.
내 YouTube 비디오 여기 - 피크 앤 홀드가있는 스테레오 VU 미터 , 당신은 여기에서 볼 수 있으며 문제가있는 경우 내 채널도 댓글을 구독하십시오.
이 프로젝트에 필요한 부품
1x Arduino 마이크로 컨트롤러 (Nano 또는 Uno 등) 나는 Arduino 공통에서 동일한 IC 사용인 ATMEGA328P-PU IC를 추가하는 것이 좋습니다. 보드, 회로 기판에서 많은 공간을 절약하고 프로그래밍하기 쉽습니다).
8x 10 LED 세그먼트 막대 그래프 LED(다음 항목 선택) 내가 사용하는 색상 중 2x 녹색은 하단에 20 LED를 의미하고 1x 노란색은 10 LED를 의미합니다. 중간 부분과 1x 빨간색은 상단용 10개의 빨간색 LED를 의미하며, 선택할 수 있습니다. 당신이 선택하고 싶은 색상).
10x 74HC595 IC 직렬 시프트 레지스터(항상 향후 문제 해결 또는 업그레이드를 위한 IC 베이스가 있는 납땜)
40x 220옴 레지스터
1x PCB 보드(성능 보드)
3x 2 핀 커넥터
1x 104J 커패시터
1x 1000uF 또는 470uF 커패시터 25V (전압에 따라 선택 변동 필요)
일부 전선
납땜 스테이션 및 도구
작동 방식
VU(Volume Unit) 미터는 오디오 장비의 신호 레벨을 표시하는 오디오 측정 장치입니다. 그것이 일반적으로 오디오 신호의 음량을 나타내는 데 사용되어 시각적 효과를 제공합니다. 오디오 레벨의 표현. VU 미터는 평균 수준을 측정하여 일관된 오디오 신호를 모니터링하는 데 적합합니다. 오디오 엔지니어에게 도움이 됩니다. 오디오 신호가 최적의 범위 내에 유지되도록 하여 왜곡을 방지하고 오디오 품질 유지.
VU 미터는 여러 개로 구성됩니다. 구성 요소:
- 입력 단계: 이것은 오디오 신호를 수신합니다. 소스에서.
- 정류기와 여과기: 오디오 신호는 다음으로 수정됩니다. AC 신호를 측정 가능한 DC 신호로 변환합니다. 필터가 매끄럽게 급격한 변동을 제거하는 신호입니다.
- 미터 이동: 처리된 신호는 신호 레벨을 나타내는 바늘 또는 LED 디스플레이.
Arduino 기반 VU레벨메터 만들기 브레드보드용
이 프로젝트는 스테레오를 만듭니다. Arduino 및 74HC595 시프트 레지스터를 사용하여 80-LED를 구동하는 VU 미터 디스플레이(각 채널당 40개의 LED). 작동 방식은 다음과 같습니다.
1. 오디오 입력: 오디오 신호는 다음에서 직접 가져옵니다. 오디오 소스(왼쪽 및 오른쪽 채널). 각 채널의 오디오 신호가 공급됩니다. 별도의 아날로그 핀(왼쪽은 A0, 오른쪽은 A1)에 넣습니다. 아두이노.
2. 신호 컨디셔닝: 신호를 안정시키고 감소시키기 위하여 노이즈, 각 오디오 입력은 아날로그로 필터 회로에 연결됩니다. 입력.
3. 아날로그 읽기: Arduino는 아날로그 입력을 읽습니다. A0 및 A1의 값입니다. 이 값은 오디오의 진폭에 해당합니다 신호.
4. 피크 감지: 코드에는 피크 감지가 포함됩니다. 기구. 주어진 기간 동안 가장 높은 값을 캡처하여 에뮬레이트합니다. 기존 VU 미터에서 볼 수 있는 "피크 홀드" 기능.
5. 스케일링 및 매핑: 아날로그 값이 스케일링되고 매핑됩니다. LED 디스플레이를 구동하기에 적합한 범위로. 이렇게 하면 LED가 레벨은 오디오 신호 레벨과 정확하게 일치합니다.
6. LED 디스플레이: 처리된 값은 다음과 같이 사용됩니다. 얼마나 많은 LED가 켜져야 하는지 결정합니다. Arduino는 74HC595 시프트를 사용합니다. 레지스터를 사용하여 LED를 제어합니다. 각 시프트 레지스터는 8개의 LED를 제어하여 다음을 허용합니다. 40-LED 디스플레이의 효율적인 제어를 위해. LED가 순서대로 켜지고, 오디오 레벨의 시각적 표현을 제공합니다.
7. 피크 홀드 : 피크 홀드 기능은 가장 높은 것을 유지합니다. LED가 짧은 시간 동안 켜져 가장 높은 오디오를 시각적으로 표시합니다. 수준에 도달했습니다.
이 Arduino 기반 VU 미터 Project는 시각적으로 매력적이고 기능적인 오디오 모니터링 방법을 제공합니다 레벨, 실시간 피드백을 제공하여 오디오 경험을 향상시킵니다. 오디오 신호의 진폭.
회로 다이어그램
이 회로도를 만드는 것은 쉽지만 많은 사람들이 그것을 어려워합니다. 찾고 있지만 실제로는 그렇지 않은 이유도 회로도의 두 부분으로 나뉘어져 있습니다. - 하나는 메인 VU 미터 드라이버 회로용이며 LED 실행 및 두 번째 부분은 원치 않는 소음을 줄이는 조정 가능한 오디오 필터 회로입니다.
첫 번째 부분은 다음과 같습니다.
그리고 두 번째 부분은 다음과 같습니다.
항상 볼륨을 확인하십시오.tag전자 수준 오디오 앰프 또는 기타 음향 장비의 입력에서 이로 인해 화상을 입을 수 있습니다. Arduino 또는 지속적으로 재설정하여 손상을 일으키고 적절한 커패시터를 추가하십시오. 입력 사양 및 Arduino 5V 전력선으로. 완료 후 회로를 열고 모든 것을 다시 확인하면 이제 전원용 코드나 전선을 추가할 수 있습니다. 및 입력.
설정 및 코드
이제이 모든 단계가 끝나면 Arduino를 열어야합니다. IDE 또는 그렇지 않은 경우 여기에서 다운로드 www.Arduino.cc 다음 설치하십시오.
여기에서 전체 코드를 복사하여 붙여 넣으십시오. 아두이노 IDE를 선택하고 com 포트와 보드를 선택합니다.
/*
MIT License
Copyright (c) 2024 Akash Sharma
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OLED display parameters
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Heart symbol bitmap (16x16 pixels)
const unsigned char heartBitmap[] PROGMEM = {
0b00001100, 0b00110000,
0b00011110, 0b01111000,
0b00111111, 0b11111100,
0b01111111, 0b11111110,
0b01111111, 0b11111110,
0b11111111, 0b11111111,
0b11111111, 0b11111111,
0b11111111, 0b11111111,
0b01111111, 0b11111110,
0b01111111, 0b11111110,
0b00111111, 0b11111100,
0b00011111, 0b11111000,
0b00001111, 0b11110000,
0b00000111, 0b11100000,
0b00000011, 0b11000000,
0b00000001, 0b10000000
};
const int latchPinLeft = 9; // Pin connected to ST_CP of 74HC595 for left channel
const int clockPinLeft = 8; // Pin connected to SH_CP of 74HC595 for left channel
const int dataPinLeft = 7; // Pin connected to DS of 74HC595 for left channel
const int latchPinRight = 4; // Pin connected to ST_CP of 74HC595 for right channel
const int clockPinRight = 3; // Pin connected to SH_CP of 74HC595 for right channel
const int dataPinRight = 2; // Pin connected to DS of 74HC595 for right channel
const int analogPinLeft = A0; // Pin connected to the audio input for left channel
const int analogPinRight = A1; // Pin connected to the audio input for right channel
const size_t nb_LEDs = 40;
const float decayRate = 0.95; // Decay rate for peak detection
float peakValueLeft = 0; // Variable to store the peak value for left channel
float peakValueRight = 0; // Variable to store the peak value for right channel
int peakLevelLeft = 0;
unsigned long peakHoldTimeLeft = 0;
const unsigned long peakHoldDuration = 500; // Duration to hold the peak in milliseconds
int peakLevelRight = 0;
unsigned long peakHoldTimeRight = 0;
void setup() {
pinMode(latchPinLeft, OUTPUT);
pinMode(clockPinLeft, OUTPUT);
pinMode(dataPinLeft, OUTPUT);
pinMode(analogPinLeft, INPUT);
pinMode(latchPinRight, OUTPUT);
pinMode(clockPinRight, OUTPUT);
pinMode(dataPinRight, OUTPUT);
pinMode(analogPinRight, INPUT);
// Initialize OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.display();
}
void loop() {
processChannel(analogPinLeft, latchPinLeft, clockPinLeft, dataPinLeft, peakValueLeft, peakLevelLeft, peakHoldTimeLeft, "L");
processChannel(analogPinRight, latchPinRight, clockPinRight, dataPinRight, peakValueRight, peakLevelRight, peakHoldTimeRight, "R");
updateOLED();
delay(20); // Adjust the delay for smoother or faster response
}
void processChannel(int analogPin, int latchPin, int clockPin, int dataPin, float &peakValue, int &peakLevel, unsigned long &peakHoldTime, const char* channel) {
// Read the analog input
float rawValue = analogRead(analogPin);
// Apply peak detection
if (rawValue > peakValue) {
peakValue = rawValue;
} else {
peakValue *= decayRate;
}
// Scale the peak value to ensure it can reach full peak
float scaledValue = peakValue * 2.0; // Increase sensitivity
// Clip the scaled value to avoid exceeding the maximum range
scaledValue = constrain(scaledValue, 0, 1023);
// Map the scaled value to the number of LEDs
int ledLevel = map(scaledValue, 0, 1023, 0, nb_LEDs);
ledLevel = constrain(ledLevel, 0, nb_LEDs); // Ensure the value stays within 0 to nb_LEDs
// Create the bit pattern for the LEDs, reversed direction
uint64_t ledPattern = 0;
for (int i = 0; i < ledLevel; i++) {
ledPattern |= ((uint64_t)1) << (nb_LEDs - 1 - i); // Reversing the bit order
}
// Update peak level
if (ledLevel > peakLevel) {
peakLevel = ledLevel;
peakHoldTime = millis(); // Reset peak hold timer
} else if (millis() - peakHoldTime > peakHoldDuration) {
peakLevel = max(0, peakLevel - 1); // Gradually decrease peak level
peakHoldTime = millis(); // Reset peak hold timer
}
// Add peak LED to the bit pattern
if (peakLevel < nb_LEDs) {
ledPattern |= ((uint64_t)1) << (nb_LED); // Adjust for reversed bit order
}
// Output the bit pattern to the shift registers
digitalWrite(latchPin, LOW);
shiftOut64(dataPin, clockPin, MSBFIRST, ~ledPattern);
digitalWrite(latchPin, HIGH);
// Store values for display update
storeDisplayValues(channel, rawValue, ledLevel, peakLevel);
}
// Template function for shifting out 64-bit data
void shiftOut64(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint64_t val) {
if (bitOrder == LSBFIRST) {
for (int i = 0; i < 64; i++) {
digitalWrite(dataPin, !!(val &));
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
} else {
for (int i = 63; i >= 0; i--) {
digitalWrite(dataPin, !!(val &));
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}
}
struct DisplayValues {
const char* channel;
float analogValue;
int ledLevel;
int peakLevel;
};
DisplayValues leftChannelValues;
DisplayValues rightChannelValues;
void storeDisplayValues(const char* channel, float analogValue, int ledLevel, int peakLevel) {
if (strcmp(channel, "L") == 0) {
leftChannelValues = {channel, analogValue, ledLevel, peakLevel};
} else if (strcmp(channel, "R") == 0) {
rightChannelValues = {channel, analogValue, ledLevel, peakLevel};
}
}
void updateOLED() {
static unsigned long lastUpdate = 0;
const unsigned long updateInterval = 200; // Update interval in milliseconds
if (millis() - lastUpdate >= updateInterval) {
lastUpdate = millis();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Left Channel");
display.setCursor(0, 10);
display.print("VU Level: ");
display.print(leftChannelValues.ledLevel);
display.setCursor(0, 20);
display.print("Peak Level: ");
display.print(leftChannelValues.peakLevel);
display.setCursor(0, 30);
display.print("Right Channel");
display.setCursor(0, 40);
display.print("VU Level: ");
display.print(rightChannelValues.ledLevel);
display.setCursor(0, 50);
display.print("Peak Level: ");
display.print(rightChannelValues.peakLevel);
// Draw the heart symbol based on the left channel analog value
if (leftChannelValues.analogValue > 150) { // Adjust the threshold as needed
display.drawBitmap(100, 0, heartBitmap, 16, 16, SSD1306_WHITE);
}
if (rightChannelValues.analogValue > 150) { // Adjust the threshold as needed
display.drawBitmap(100, 40, heartBitmap, 16, 16, SSD1306_WHITE);
}
display.display();
}
}
음악을 즐기다
이제 당신은 모두를 흔들고 충격시킬 수 있습니다! 당신이 큰 가지고 있다면 ampliifier(예: 50W, 100W, 150W, 2000W 등), 항상 확인하십시오. 입력 전압 레벨입니다. 정확한 조정을 위해 입력 변수를 조정합니다. 오디오 또는 음악과 완벽하게 동기화되는 LED 레벨메터 였습니다.
'아두이노' 카테고리의 다른 글
데스크 매트에서 MIDI 드럼으로 (0) | 2024.11.22 |
---|---|
혁신과 지속 가능성을 위한 프로젝트: PET 플라스틱 재활용 필라멘트 기계 (1) | 2024.10.18 |
DIY 아두이노 OLED 스펙트럼 분석기 (1) | 2024.10.17 |
DIY Arduino MPPT 태양광 충전 컨트롤러 (1) | 2024.10.17 |
아두이노 러닝맨 만들기 (5) | 2024.10.07 |