Регулятор громкости M62429 + OLED 128×32 (Arduino)

M62429 — двухканальный цифровой регулятор громкости с последовательным управлением. Микросхема заменяет традиционные механические потенциометры и позволяет точно настраивать уровень  звука в аудио аппаратуре.

Основные возможности

  • Два независимых канала — можно раздельно регулировать громкость левого и правого каналов.
  • Широкий диапазон регулировки — от 0 до −83 дБ с шагом 1 дБ.
  • Низкие искажения — коэффициент нелинейных искажений (THD) составляет около 0,01 % при уровне сигнала 0,5 Vrms.
  • Минимальное шумовое воздействие — выходной шум около 5 мкВ rms при максимальной громкости.
  • Простое управление — данные передаются по двухпроводной последовательной шине (DATA и CLOCK).

Электрические параметры

  • Напряжение питания: 4,5–5,5 В (номинальное — 5 В), максимально допустимое — 6 В.
  • Ток потребления: типовое значение — 8 мА, максимальное — 16 мА.
  • Рабочий температурный диапазон: от −20 °C до +75 °C.

Цоколёвка (8‑выводной корпус DIP‑8 / SOP‑8)

  1. VIN1 — вход канала 1.
  2. VOUT1 — выход канала 1.
  3. GND — общий провод (земля).
  4. DATA — вход данных последовательной шины.
  5. CLOCK — тактовый вход для передачи данных.
  6. VCC — напряжение питания.
  7. VOUT2 — выход канала 2.
  8. VIN2 — вход канала 2.

Ключевые особенности

  • Встроенная опорная схема — не требует дополнительных внешних цепей смещения.
  • Независимая регулировка каналов — каждый канал управляется отдельно.
  • Минимальные внешние компоненты — для работы достаточно развязывающего конденсатора (0,1 0,33 мкФ) и входного электролитического конденсатора (2,2 мкФ).
  • Низкий уровень шума — подходит для высококачественного аудио.

Рекомендации по применению

  • Стабилизация питания. Подключите развязывающий конденсатор (0,1-0,33 мкФ) между VCC и GND для подавления помех.
  • Фильтрация входного сигнала. Установите электролитический конденсатор 2,2 мкФ на вход каждого канала для улучшения качества звука.
  • Качество питания. Минимизируйте пульсации напряжения — они могут повысить уровень шума на выходе.

Ранее в http://rcl-radio.ru/?p=63039 описывался регулятор громкости на базе ИМС M62429 с дисплеем LCD1602 на базе контроллера HD44780. В этой статье будет аналогичный пример но с использованием дисплея OLED 128×32.

Регулятор громкости и тембра на M62429 содержит следующие компоненты:

  • Плата Arduino Nano (или аналог)
  • Энкодер KY-040
  • IR — датчик
  • Две кнопки управления
  • Дисплей OLED 128×32
  • ИМС M62429

Основные параметры компонентов схемы:

  • 0,91″ I2C 128×32 OLED — это компактный дисплей, который использует технологию OLED (Organic Light Emitting Diode) для отображения изображений. Дисплей имеет интерфейс I2C, который обеспечивает простое подключение к микроконтроллерам и другим устройствам.

Основные характеристики дисплея:

    •  Разрешение 128×32 пикселей.
    • Размер дисплея 0,91 дюйма (около 2,3 см).
    • Яркость до 150 кд/м².
    • Контрастность 2000:1.
    • Угол обзора 160 градусов.
    • Поддержка интерфейса I2C с адресом 0x3C.
  • Arduino Nano:

    • Микроконтроллер: ATmega328P
    • Напряжение питания: 5 В
    • Тактовая частота: 16 МГц
    • Память Flash: 32 КБ
    • Оперативная память (RAM): 2 КБ
    • Постоянная память (EEPROM): 1 КБ
    • Количество цифровых выводов: 14
    • Количество аналоговых входов: 8
    • Размеры платы: приблизительно 45 x 18 мм
  • Технические характеристики ИК-модуля VS1838B:
    • Потребляемый ток: 0,5 мА
    • Рабочая частота: 38 КГц
    • Расстояние приема сигнала: 20 м
    • Эффективный угол приема сигнала: 90˚
    • Рабочее напряжение (приемник): 2,7 — 5,5 В
    • Рабочее напряжение (модуль): 2,7 — 5,5 В

Основные параметры KY-040:

  • Принцип работы:
    • Инкрементальный энкодер с механическим переключателем.
    • Интерфейс: Сигнал передается по трем линиям:

      • CLK (Clock Line) — импульсный сигнал, определяющий направление вращения.
      • DT (Data Line) — второй импульсный сигнал, синхронизируется с CLK.
      • SW (Switch) — механический выключатель, срабатывающий при нажатии на вал энкодера.
    • Напряжение питания: 3.3–5 В постоянного тока.
    • Рабочий ток: Очень маленький (<1 мА).
    • Размеры: Миниатюрный модуль, удобен для установки на печатные платы.
    • Материал вала: Металлический или пластиковый, чувствителен к касанию пальцами.
    • Кол-во импульсов на оборот: Обычно 20–30 шагов на полный оборот, точнее указывается производителем конкретного экземпляра.
    • Совместимость: Совместим с большинством микроконтроллеров (Arduino, ESP32, STM32 и т.п.).

Основные параметры регулятора громкости

  • Регулировка громкости 0 … 67 дБ
  • Регулировка баланса от -8 до +8 дБ
  • Режим MUTE
  • Режим STANDBY
  • Дополнительный цифровой выход D12 для управления режимом STANDBY УМЗЧ
  • Управление энкодер, ИК пульт и две кнопки (MUTE, POWER)

ИК пульт дублирует работу энкодера и кнопок. Для управления регулятором подойдет практически любой пульт ИК, для поддержки Вашего пульта необходимо прописать коды кнопок в скетч:

// коды кнопок ИК пульта
#define MENU 0x2FDB24D // button encoder
#define UP 0x2FDD02F // >>>
#define DW 0x2FD32CD // <<<
#define POWER_IR 0x2FD00FF // POWER
#define MUTE_IR 0x2FDB04F // MUTE

Для получения кодов кнопок Вашего пульта загрузите скетч и откройте монитор порта, при нажатии кнопки пульта его код будет отображен в мониторе порта.

Схема блока управления

Схема регулятора громкости

Регулировка громкости происходит при помощи энкодера KY-040, ИК пульт дублирует работу энкодера, информация выводится на OLED 128×32 на базе контроллера SSD1306.

Кнопка энкодера позволяет переключать режимы настроек между громкостью и балансом. Уровень громкости и баланса сохраняются в энергонезависимой памяти.

Скетч

// энкодер
#define ENC_DT       9
#define ENC_CLK      8
#define ENC_SW       10

// ИК датчик
#define IR           5

// кнопки управления
#define POWER_BUTTON    3
#define MUTE_BUTTON     4

// выход управления standby
#define STANDBY_OUT     13

// M62429 
#define CLK        11
#define DATA       12

// коды кнопок ИК пульта
#define MENU      0x2FDB24D // button encoder
#define UP        0x2FDD02F // >>>
#define DW        0x2FD32CD // <<<
#define POWER_IR  0x2FD00FF // POWER
#define MUTE_IR   0x2FDB04F // MUTE

#include <Wire.h> 
#include <U8glib.h>             // https://github.com/olikraus/u8glib/
#include <Encoder.h>            // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip    
#include <EEPROM.h>
#include <MsTimer2.h>           // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip       
#include <boarddefs.h>          // входит в состав библиотеки IRremote
#include <IRremote.h>           // http://rcl-radio.ru/wp-content/uploads/2019/06/IRremote.zip
#include <M62429.h>             // http://rcl-radio.ru/wp-content/uploads/2026/01/M62429.zip

 U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);  // I2C / TWI 
 IRrecv irrecv(IR);
 Encoder myEnc(ENC_DT, ENC_CLK);
 decode_results ir; 
 

 extern uint8_t SmallFont[],BigNumbers[];
 long times,oldPosition  = -999,newPosition;
 int vol,balans,bass,treb,in,menu;
 bool mute=0,gr1,gr2,w,w1,power=0;

 void setup(){
  Wire.begin();
  irrecv.enableIRIn();
  Serial.begin(9600);
  MsTimer2::set(3, to_Timer);MsTimer2::start();
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении  
  pinMode(POWER_BUTTON,INPUT_PULLUP);
  pinMode(MUTE_BUTTON,INPUT_PULLUP);
  pinMode(STANDBY_OUT,OUTPUT); 

 u8g.firstPage(); do {
  u8g.setFont(u8g_font_profont29r);u8g.drawStr(5,25,"M62429"); 
  }while( u8g.nextPage() );

  delay(3000);
  digitalWrite(STANDBY_OUT,LOW);
  vol = EEPROM.read(0);balans = EEPROM.read(3)-8;
  audio(); 
 }

 void loop(){
  // IR ////////////////////////////////////////
  if ( irrecv.decode( &ir )) {Serial.print("0x");Serial.println( ir.value,HEX);irrecv.resume();times=millis();w=1;}// IR приемник - чтение, в мониторе порта отображаются коды кнопок
  if(ir.value==0){gr1=0;gr2=0;}// запрет нажатий не активных кнопок пульта  
  
 if(power==0){ 
 if(digitalRead(ENC_SW)==LOW || ir.value==MENU){menu++;cl();delay(200);times=millis();w1=1;w=1;if(menu>1){menu=0;}} // меню


 if((digitalRead(MUTE_BUTTON)==LOW || ir.value==MUTE_IR)&& mute==0){mute=1;cl();times=millis();w1=1;w=1;mute_conf();
 u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(25,25,"MUTE");}while( u8g.nextPage() );delay(300);menu=100;} // mute on 

 if((digitalRead(MUTE_BUTTON)==LOW || ir.value==MUTE_IR)&& mute==1){mute=0;cl();times=millis();w1=1;w=1;audio();
 delay(300);menu=0;} // mute off 
 }

 if((digitalRead(POWER_BUTTON)==LOW || ir.value==POWER_IR)&& power==0){power=1;cl();times=millis();w1=1;w=1;mute_conf();digitalWrite(STANDBY_OUT,HIGH);
 u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(10,25,"STANDBY");}while( u8g.nextPage() );delay(2000);menu=100;
 u8g.firstPage(); do {}while( u8g.nextPage() );} // power on 

 if((digitalRead(POWER_BUTTON)==LOW || ir.value==POWER_IR)&& power==1){power=0;cl();times=millis();w1=1;w=1;audio();digitalWrite(STANDBY_OUT,LOW);delay(300);menu=0;} // power off 
 
  
//////// VOLUME //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==0){
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
   vol=vol+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;vol_func();audio();}
 
   if(ir.value==UP){vol++;gr1=1;gr2=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){vol++;gr2=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка >>>>>>
   if(ir.value==DW){vol--;gr1=0;gr2=1;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){vol--;gr1=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка <<<<<<
 
  if(w==1){w=0;
 // Serial.println(63-vol+balans);
  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,"VOLUME");
  u8g.setFont(u8g_font_profont29r); u8g.setPrintPos(95, 24);u8g.print(vol-8);
  for(int v_pos=0; v_pos<(75-8)*1.3;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);}
  for(int v_pos=0; v_pos<(vol-8)*1.3;v_pos+=4){u8g.drawBox(v_pos+0,18, 2, 9);}
  for(int v_pos=0; v_pos<(75-8)*1.3;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);}
   } while( u8g.nextPage() );
  }}

///////// BALL /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if(menu==1){
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
   balans=balans+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;ball_func();audio();}

   if(ir.value==UP){balans++;gr1=1;gr2=0;ir.value=0;times=millis();w=1;w1=1;ball_func();audio();}// кнопка > 
   if(ir.value==DW){balans--;gr1=0;gr2=1;ir.value=0;times=millis();w=1;w1=1;ball_func();audio();}// кнопка <
 
  if(w==1){w=0;
 // Serial.println(83-vol+balans);
 // Serial.println(83-vol-balans);
  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,"BALANCE");
  u8g.setFont(u8g_font_profont29r); 
  if(balans>=0){u8g.setPrintPos(112, 24);u8g.print(balans);u8g.drawStr(95,24,"+");}
  else{u8g.setPrintPos(95, 24);u8g.print(balans);}

  for(int v_pos=0; v_pos<(12-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);}
  const int SCREEN_WIDTH = 84; 
  u8g.drawBox(43,18, 1, 9);// 0 dB
  if(balans >= 0){for(int v_pos=0; v_pos<(balans*4);v_pos+=4){u8g.drawBox(v_pos+48,18, 2, 9);}} 
  else{for(int v_pos=SCREEN_WIDTH-48; v_pos>(SCREEN_WIDTH-(abs(balans)*4)-48); v_pos-=4){u8g.drawBox(v_pos,18, 2, 9);}}
  for(int v_pos=0; v_pos<(12-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);}
  
   } while( u8g.nextPage() );
  }}
  

////////////// EEPROM /////////////////////////////////////////////////////////////////////  
  if(millis()-times>5000 && w1==1 && power==0 && mute==0){
     EEPROM.update(0,vol);EEPROM.update(3,balans+8);
     menu=0;w1=0;w=1;myEnc.write(0);}
  }

 
void to_Timer(){newPosition = myEnc.read()/4;} 
void audio(){
setVolume (CLK,DATA,0,0,83-vol+balans); 
setVolume (CLK,DATA,0,1,83-vol-balans);
/* pin CLK
   pin DATA
   0 - по одному каналу, 1 - оба вместе
   0 ПК 1 ЛК
   83 ... 0 громкость 83 = -83 дБ */  
}

void mute_conf(){
setVolume (CLK,DATA,0,0,84); 
setVolume (CLK,DATA,0,1,84);
  }


void vol_func(){if(vol>75){vol=75;}if(vol<=8){vol=8;}} // int 0 ... int 79 
void ball_func(){if(balans>8){balans=8;}if(balans<=-8){balans=-8;}}
void cl(){ir.value=0;delay(200);} 

Форум — http://forum.rcl-radio.ru/viewtopic.php?id=724

Даташит — m62429.pdf

Comments

  1. Питание на микросхему желательно подавать через П фильтр. Дросель и конденсатор. Опытным путём оказалось что конденсатор нужен 4700 мкф

Добавить комментарий

Войти с помощью: