PCCar.ru - Ваш автомобильный компьютер

Вернуться   PCCar.ru - Ваш автомобильный компьютер > MP3Car ТехИнфа > AndroidCar > Звук

Ответ
 
Опции темы Поиск в этой теме
Старый 06.10.2016, 20:20   #21
ali_vlad
Старший Пользователь
 
Регистрация: 21.06.2014
Возраст: 49
Регион: 05
Машина: Hyundai Accent II
Сообщений: 556
ali_vlad is on a distinguished road
По умолчанию

Цитата:
Сообщение от Kisel39 Посмотреть сообщение
Не в обиду Олег, можно намного правильнее сделать:
Как я понимаю приемом и управлением будет рулить приложение с андройда,
Так делай всю обработку в приложении, а атмега будет только шлюзом.
Я тоже пытался читать протокол cannyo , но на ардуино ничего не вышло, вернее читать получалось, а отправлять - никак, только на 32 битах ARM заработало и то на 96 Mhz. Андройду посилу многое, да и ресурсы другие, у меня сейчас тинси наполовину шлюз на вторую ( управление питанием и чтением данных ), если андройд тупонет...
Молодец, удачи в проекте !
Тыкать в экран во время езды чревато большими неприятностями.
Покрутить крутилку и потыкать кнопки можно и не отрывая глаз от дороги. Да и на руле бывают кнопки.
А что касаемо трансляции команд с андроида на ардуину, так это уже давно придумано. Сериал менеджер. Только добавить в скетч опрос ком-порта и вызов имеющихся функций.
ali_vlad вне форума   Ответить с цитированием
Старый 06.10.2016, 20:31   #22
yuriy m
Старший Пользователь
 
Регистрация: 13.11.2011
Возраст: 48
Город: Гомель BY
Регион: 03
Машина: Гольф2 -> Lancia Zeta
Сообщений: 376
yuriy m is a jewel in the roughyuriy m is a jewel in the roughyuriy m is a jewel in the rough
По умолчанию

Цитата:
Сообщение от ali_vlad Посмотреть сообщение
Тыкать в экран во время езды чревато большими неприятностями.
Покрутить крутилку и потыкать кнопки можно и не отрывая глаз от дороги. Да и на руле бывают кнопки.
А что касаемо трансляции команд с андроида на ардуину, так это уже давно придумано. Сериал менеджер. Только добавить в скетч опрос ком-порта и вызов имеющихся функций.
Не ну если просто громкость менять,то да. А как у меня, несколько десятков установок,то удобней с экрана выставить, ну и в параллелей с кнопок управление тоже будит. Да и информация должна как-то отображаться. Кнопками изменишь ,а на андрюше ползунок двигается и все сразу видно...
__________________
Управление под ANDROID ... http://www.pccar.ru/showthread.php?t=24001
Мой старый проект http://www.pccar.ru/showthread.php?t=18038
yuriy m вне форума   Ответить с цитированием
Старый 06.10.2016, 21:57   #23
oleg707
Гуру
 
Аватар для oleg707
 
Регистрация: 16.04.2014
Возраст: 42
Город: Gdynia
Регион: другой - для добавления сообщить ab
Сообщений: 2,548
oleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond repute
По умолчанию

tda7442
умеет регулировать громкость
_____ регулировать басы
_____ регулировать пищалки
ВСЁ.
Ну ещё выбор между 4 линейными входами с возможностью микширования основного канала и одного из этих 4х.

Зачем данной конкретной микрухе связь с андроидом то?! Только на экране ползунок показать?
Даже эквалайзер я не активировал в скетче ( во первых, меня устраивает акустика в машине, а во вторых и в плеере можно настроить, как раз в андроиде), хотя на плате детали для EQ распаял.

Когда я в дороге еду я очень редко смотрю на экран, когда делаю громче-тише. Ориентир - по нужной громкости на данный момент.
Дисплей для I2C можно прикрутить, и в него уже скидывать информацию от блока питания и звукового процессора.
oleg707 вне форума   Ответить с цитированием
Старый 18.10.2016, 00:25   #24
oleg707
Гуру
 
Аватар для oleg707
 
Регистрация: 16.04.2014
Возраст: 42
Город: Gdynia
Регион: другой - для добавления сообщить ab
Сообщений: 2,548
oleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond repute
По умолчанию пока я не полез в дебри

Нажмите на изображение для увеличения
Название: cxema.jpg
Просмотров: 1439
Размер:	92.1 Кб
ID:	45184
схема в диптрейсе - исходники12 2407+7808C+Atmega+ tda7442.zip

С удовольствием выслушаю критику и предложения


PHP код:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Скетч v22 i7442
// с подавлением дребезга кнопок 
// с динамическим увеличением/уменьшением громкости при удержании кнопок ( с УСКОРЕНИЕМ при удержании)
// с энкодером (код грея)
// с функцией MUTE
// дисплей по I2C
//без активации внутреннего эквалайзера TDA7442D 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// класс титановый велосипед для тактовой кнопки. (версия 1.0)http://arduino.ru/forum/programmirovanie/klass-titanovyi-velosiped-dlya-taktovoi-knopki
// фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick), нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени.

#include <Arduino.h>
#include <Wire.h> /*добавление библиотеки I2C шины*/
#include <LiquidCrystal_I2C.h>  /*добавление библиотеки для работы с дисплеем по I2C*/
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display для 0x27 - настройка экрана для библиотеки LiquidCrystal_I2C2004V1
//LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE);  // для newE  описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347



  


class BUTTON {
public:
//============================================================================================
// константы настроек класса.
static const byte bounce_            =   50; // длительность отслеживания дребезга.
static const byte doubleclick_       =  250; // длительность отслеживания двойного нажатия.
static const unsigned long timer_    = 5000; // длительность отслеживания неактивности.
static const unsigned int retention_ = 500; // длительность отслеживания нажатия и удержания.
//============================================================================================
unsigned long start; // старт отсчёта времени.
boolean p;           // состояние пина кнопки.
boolean s;           // программное состояние кнопки.
boolean b;           // состояние таймера фильтра дребезга.
byte    c;           // переменная счётчика двойного нажатия.
boolean t;           // состояние таймера неактивности.
boolean r;           // состояние таймера нажатия и удержания.
//============================================================
boolean click_down;  // событие нажатия.
boolean click_up;    // событие отпускания.
boolean doubleclick; // событие двойного нажатия.
boolean timer;       // событие неактивности.
boolean retention;   // событие нажатия и удержания.
//============================================================
byte _pb;
//============================================================
BUTTON(byte pb) {
_pb = pb;
pinMode(_pb, INPUT);
digitalWrite(_pb, 1);
//===================
start = millis();
p     = digitalRead(_pb);
// p     = !digitalRead(_pb); // отключить тихий старт.
s     = p;
b     = 0;
c     = 0;
t     = 0;
r     = 0;
//==============
click_down  = 0;
click_up    = 0;
doubleclick = 0;
timer       = 0;
retention   = 0;
//==============
}

void read() {
//==============================================================================
boolean np = digitalRead(_pb); // текущее состояние пина кнопки.
unsigned long stop = millis(); // стоп отсчёта времени.
//==============================================================================
click_down  = 0;
click_up    = 0;
doubleclick = 0;
timer       = 0;
retention   = 0;
//==============================================================================
if (np != p) {p = np; click(); start = stop; b = 1; t = 1; r = 1;} // состояние цифрового пина изменилось.
//==============================================================================
if (b != 0          ) {if (stop - start > bounce_     ) {b = 0; click();      }} // фильтр дребезга.
if (c != 0          ) {if (stop - start > doubleclick_) {c = 0;               }} // обнуление счётчика двойного клика.
if (t != 0 && s == 1) {if (stop - start > timer_      ) {t = 0; timer     = 1;}} // неактивность.
if (r != 0 && s == 0) {if (stop - start > retention_  ) {r = 0; retention = 1;}} // нажатие и удержание.
//==============================================================================
}

void click() {                       // нажатие, отпускание, двойное нажатие.
if (b == 0 && s != p) {s = p;
if (
s == 0) {click_down = 1; ++c; if (c == 2) {c = 0; doubleclick = 1;}}
if (
s == 1) {click_up   = 1;}
}
}

};
// конец class BUTTON
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//конец кода для чтения состояний кнопок ~
//=====================================================================================================================================================================================================================================================










//Подтяжку для кнопок на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм

//                 ТУТ НАЗНАЧАЕМ ИМЕНА НАШИХ КНОПОК И К КАКИМ ПИНАМ ОНИ ПОДКЛЮЧЕНЫ           (также сюда пишем имена переменных, то, что обычно пишется ДО void setup().
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//BUTTON REDbutton(31);     //назначаем красной кнопке ножку 31. То есть один конец конпки подключён на пин 31 ардуины меги, а второй  конец конпки подключён на массу (GND)     Подтяжку на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм
//BUTTON BLACKbutton (33);  //назначаем красной кнопке ножку 33. То есть один конец конпки подключён на пин 33 ардуины меги, а второй  конец конпки подключён на массу (GND)    Подтяжку на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм
BUTTON VOLUPbutton(6);   //назначаем кнопке ГРОМКОСТИ++ ножку D6
BUTTON VOLDNbutton(7);   //назначаем кнопке ГРОМКОСТИ-- ножку D7
BUTTON MUTEbutton(8);   //назначаем кнопке MUTE ножку D8
   // BUTTON pin_A(9);
   // BUTTON pin_B(10);
byte MasterVolume = 26; //СТАВИМ НАЧАЛЬНОЕ ЗНАЧЕНИЕ ГРОМКОСТИ ПРИ ПОДАЧЕ ПИТАНИЯ НА АРДУИНУ - переменная, хранящая в себе громкость выходного звука, 0 - макс громкость, 79- минимальная, 80-255 MUTE http://arduino.ru/Reference/Byte Тип данных byte 8-ми битное беззнаковое целое число, Если DEC - в диапазоне 0..255
#define  VOLUME_INTERVAL  100UL  // интервал(время) между изменениями уровня громкости (0,05 секунд)
boolean Vupupup = 0; //переменная, показывающая надо ли увеличивать громкость раз в #define  VOLUME_INTERVAL  100UL (0,1Сек)
boolean Vdndndn = 0; //переменная, показывающая надо ли уменьшать громкость раз в #define  VOLUME_INTERVAL  100UL (0,1Сек)
byte USCORENIE = 0; //переменная, ускорение изменения громкости при удержании кнопок VOL+ и VOL-
boolean MuteActiv = 0; // Признак включённого режима MUTE (временное отключение громкости)
byte MasterVolumeDoMUTE = 80; //Значение грмкости во время того, как включаем MUTE
//для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int stepVOLamount = 2; // шаг изменения громкости энкодером
unsigned long currentTimeVoumeControl;
unsigned long loopTimeVoumeControl;

enum {ENC_PIN1 = 9, ENC_PIN2 = 10};
// Преобразование значения Грея в двоичный код
// без изменений прямиком из wilipedia
unsigned graydecode(unsigned gray) {
  
unsigned bin;

  for (
bin = 0; gray; gray >>= 1)
    
bin ^= gray;

  return 
bin;
}

//  grayValue - Значение Грея
//  value     - Преобразованное значение Грея
//  oldValue  - Старое преобразованное значение Грея


//конец для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
//=====================================================================================================================================================================================================================================================





 
void setup()    
 { 
Serial.begin(9600); // ком порт     
pinMode(13, OUTPUT); // настройка пина встроенного светодиода на выход (чтоб моргать мог)        
Wire.begin(); // включение библиотеки I2C шины 
lcd.init();      // initialize the lcd занимает почти секунду

/*~~~~~~~~ для энкодера~~~~~~~~~~*/
pinMode(ENC_PIN1, INPUT); //настройка пинов энкодера
digitalWrite(ENC_PIN1, 1);       // включить подтягивающий резистор http://arduino.ru/Tutorial/DigitalPins
pinMode(ENC_PIN2, INPUT);
digitalWrite(ENC_PIN2, 1);
/*~~~~~~~~конец для энкодера~~~~~~~~~~*/
Serial.println("   S E T U P  ok   ");
Serial.println("   ver e22_testenc   ");
MasterVolume = 80;//mute
delay (2000);
MasterVolume = 26;
Serial.println("perexodim k osnovnoy programme ");
 } 
//=====================================================================================================================================================================================================================================================



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ЕСЛИ удерживаются кнопки регулировки громкости, то увеличиваем или уменьшаем громкость на один шаг (1dB) с периодичностью (interval - USCORENIE + 8)
void VOLFAST(unsigned long interval )
{
  static 
unsigned long prevTime = 0; // время когда последний раз увеличивали или уменьшали громкость
  
if(millis() - prevTime > interval-USCORENIE) {
                                       
prevTime = millis();  // если зажаты сразу две кнопки, приоритет будет на громкость вниз.
                                       
if (Vupupup == 1 && Vdndndn == 0) {if(interval-USCORENIE>8+20){USCORENIE = USCORENIE + 8;} if (MasterVolume==0){Serial.print ("I tak VOLUME MAX (0dB)  "); } else (MasterVolume--);  Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB");  digitalWrite(13,!digitalRead(13)); } // если зажата громкость вверх, то увеличиваем громкость на один шаг (1dB) с периодичностью interval.
                                       
if (Vdndndn == 1)                 {if(interval-USCORENIE>10+20){USCORENIE = USCORENIE + 10;} if (MasterVolume==80){Serial.print ("I tak VOLUME MIN (80dB-MUTE)   ");}  else (MasterVolume++);    Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); digitalWrite(13,!digitalRead(13)); }// если зажата громкость вниз, то уменьшаем громкость на один шаг (1dB) с периодичностью interval.
  
  
                                      
}
}
 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/* функция void tda7442 вызов управления по I2C ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void tda7442(byte subaddress, byte data)  //Вызов данных tda7442
{ 
Wire.beginTransmission(0x40); /*СТАРТ (посылается бит старта по I2C шине) и Адрес микросхемы  tda7442  (посылается 7бит адреса по I2C шине и еще один нолик)*/
/*после beginTransmission дуина ждёт по линии ДАТА ответа от tda7442 ( присаживание линии на землю во время 8 бита синхросигнала)и потом передает*/
Wire.write(subaddress);       //Подадрес команды 
Wire.write(data);             //Команда 
Wire.endTransmission();       //СТОП 
/* То есть когда есть связь с tda7442, то функция (void tda7442) посылает сначала первый пакет tda7442(0), потом данные этого пакета 0b01000000
   Потом функция (void tda7442) посылает  второй пакет tda7442(1), потом данные этого пакета 0b00000110
   и так до конца: tda7442(9, 0b00000110); */
}
/*конец void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/




 
void loop() //~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~

 
{ 
VOLUPbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки громкости 
VOLDNbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки громкости 
MUTEbutton.read();     // читаем фильтрованное значение СТАТУСА кнопки MUTE

                          /*               Примеры
                           REDbutton.read();      // читаем фильтрованное значение СТАТУСА кнопки
                           BLACKbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки
                           if (REDbutton.click_down) {Serial.println("REDbutton = najata"); }             //нажатие кнопки  
                           if (REDbutton.click_up) {Serial.println("REDbutton = otpustily"); }            //отпускание кнопки 
                           if (REDbutton.doubleclick) {Serial.println("REDbutton = doubleclick"); }       //двойной клик 
                           if (REDbutton.timer) {Serial.println("REDbutton = neaktivnost knopki"); }      //неактивность 
                           if (REDbutton.retention) {Serial.println("REDbutton = uderjanie");}            // нажатие и удержание  
                           */


 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обработка MUTE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
if (MasterVolume<80&&MuteActiv ==1){MuteActiv = 0;}
 if (
MUTEbutton.click_down)//если кнопка MUTE однократно нажата
        
{ 
       
// Serial.println("   M U T E     ");
        
if (MuteActiv == 0){MasterVolumeDoMUTE = MasterVolume;}
        
MuteActiv = (!MuteActiv); 
        if (
MuteActiv == 1){ MasterVolumeDoMUTE = MasterVolume; MasterVolume=80; }
        if (
MuteActiv==0 ) { MasterVolume = MasterVolumeDoMUTE; MuteActiv = 0; }
        
Serial.print("MuteActiv = " );Serial.print(MuteActiv);Serial.print("   MasterVolume = "); Serial.println(MasterVolume);
       
// Serial.println("   END M U T E     ");
        
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец обработки MUTE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


/*~~~~~~~~~~~~~~~~~~~~~~обработка нажатия кнопок громкости~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
if (VOLUPbutton.click_down) /*если кнопка VOL+ однократно нажата  то ДЕЛАЕМ ШАГ(1 РАЗ): включаем светик, уменьшаем переменную громкости (для увеличения звука)выводим значение громкости в порт.*/
        
{                                                       
           if (
MasterVolume==0){Serial.println ("I tak VOLUME MAX (0dB)"); } else (MasterVolume--);  Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); // выводим значение громкости в ком порт
           
digitalWrite(13,!digitalRead(13)); 
        }
  if (
VOLDNbutton.click_down) /*если кнопка VOL- однократно нажата то ДЕЛАЕМ ШАГ(1 РАЗ): увеличиваем переменную громкости (для уменьшения звука)выводим значение громкости в порт*/
        
{  
           if (
MasterVolume==80){Serial.println ("I tak VOLUME MIN (80dB-MUTE)");}  else (MasterVolume++);    Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); // выводим значение громкости в ком порт
           
digitalWrite(13,!digitalRead(13)); 
        }
/*===================================================================================================================*/

/*~~~~~~~~~~~~~~~~~~~~~~обработка удержания кнопок громкости~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if (VOLUPbutton.retention==1){Vupupup = 1;}//если кнопка нажата  и удерживается //надо бы увеличивать громкость по шагам
if (VOLDNbutton.retention==1){Vdndndn = 1; }     //если кнопка нажата  и удержмвается //надо бы уменьшать громкость по шагам
  
if (VOLUPbutton.click_up) { Vupupup = 0; USCORENIE = 0;}  //если отпустили кнопку, надо бы перестать увеличивать громкость по шагам
  
if (VOLDNbutton.click_up) { Vdndndn = 0; USCORENIE = 0;}       
VOLFAST(VOLUME_INTERVAL); //заходим в функцию VOLFAST, которая  ЕСЛИ удерживаются кнопки регулировки громкости, то увеличивает или уменьшает громкость на один шаг (1dB) с периодичностью VOLUME_INTERVAL.   
/*===================================================================================================================*/



/*для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
static uint8_t oldValue = 0;
  
uint8_t grayValue = digitalRead(ENC_PIN1) | (digitalRead(ENC_PIN2) << 1), value = graydecode(grayValue);

  if (
value == 0) // Энкодер вращается
      
{
    if (
oldValue == 3) { /*  вращение по часовой стрелке // увеличиваем громкость, не более чем до 80*/
                                                      
if(MasterVolume + stepVOLamount <= 80) {(MasterVolume += stepVOLamount); Serial.println(MasterVolume);}
                       }
    else if (
oldValue == 1) { // Влево
                             
if(MasterVolume - stepVOLamount >= 0){ (MasterVolume -= stepVOLamount); Serial.println(MasterVolume); }  /* уменьшаем громкость, но не ниже 0*/
                            
}
      }



  
oldValue = value;


/*конец для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

     



/*конфигурация void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

tda7442(0, 0b01000000);  //INPUT ATTENUATION    приглушение ВХОДНОГО (IN1-IN4) канала (0 ~ -31.5dB)(0db-макс громкость, без приглушения)
tda7442(1, 0b00000110);  //SURROUND & OUT & EFFECT CONTROL( -6 FIX OFF)
tda7442(2, 0b00000011);  //SURROUND PHASE RESISTOR( 37KOm)
tda7442(3, 0b00011111);  //BXXX0011 BASS SELECTION (0dB)-14dB  (0b0001100 = 14dB; 0b00011000 + 0b00000001 = 0b00011001 (+12dB) 
tda7442(4, 0b01111110);  //BXXX0100 TREBLE (0dB)
//tda7442(5, 0b00000000);  //BXXX0101 SPEAKER ATTENUATION "L" (0dB)( SPEAKER SELECTION = 0dB ~ -79dB) громкость правого канала
//tda7442(6, 0b00000000);  //BXXX0110 SPEAKER ATTENUATION "R" (0dB) громкость левого канала
// регулировку громкости можно делать  0dB ~ -79dB в DEC c шагом 1. если (80-255) - то MUTE  
tda7442(5,  MasterVolume); //0 - макс громкость, 80-255 - MUTE .  
tda7442(6,  MasterVolume);
tda7442(7, 0b00000000);  //BXXX0111 NOT ALLOWED
tda7442(8, 0b00000000);  //BXXX1000 NOT ALLOWED         
tda7442(9, 6/*0b00000110*/);  //BXXX1001 INPUT MULTIPLEXER выбор источника IN1-4 (6-in1 4-in4  2-in3 0-in2)
/*конец конфигурации void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/





  
lcd.backlight();
  
lcd.setCursor(0, 0);
  
lcd.print((millis() )/1000); // вывод кол-ва сек работы блока ( 1 строка 1 символ)
  
  
lcd.setCursor(7, 0);
  
/*lcd.print(flagAKB); // вывод флага AKB
  
  lcd.setCursor(8, 0);
  lcd.print(flagACC); // вывод флага АСС
  
  lcd.setCursor(9, 0);
  lcd.print(flagREM); // вывод флага rem
  lcd.setCursor(11, 0);
  lcd.print(U_acc_real); // вывод напряжения АСС
  
  //lcd.setCursor(5,1);
  */
  //-------------------2 строка---------------------------------
  
lcd.setCursor(0, 1);
  
lcd.print("VOLUME -");
  
lcd.setCursor(8, 1);
  
lcd.print(MasterVolume); 
  
lcd.setCursor(11, 1);
  
lcd.print("dB");


















}
//конец LOOP//~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~
//=====================================================================================================================================================================================================================================================
//__________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ 
вот еще для другой библиотеки для I2C дисплея
тут я вывел ползунок текущей громкости на дисплей, приведя его к удобному виду (больше полоска = громче)
PHP код:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Скетч v22 i7442
// с подавлением дребезга кнопок 
// с динамическим увеличением/уменьшением громкости при удержании кнопок ( с УСКОРЕНИЕМ при удержании)
// с энкодером (код грея - коррекция ошибок энкодера, но за счёт этого медленно) 
// с функцией MUTE
// дисплей по I2C
//с ползунком громкости
//без активации внутреннего эквалайзера TDA7442D 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// класс титановый велосипед для тактовой кнопки. (версия 1.0)http://arduino.ru/forum/programmirovanie/klass-titanovyi-velosiped-dlya-taktovoi-knopki
// фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick), нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени.

#include <Arduino.h>
#include <Wire.h> /*добавление библиотеки I2C шины*/
#include <LiquidCrystal_I2C.h>  /*добавление библиотеки для работы с дисплеем по I2C*/
//LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display для 0x27 - настройка экрана для библиотеки LiquidCrystal_I2C2004V1
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE);  // для newE  описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347



  


class BUTTON {
public:
//============================================================================================
// константы настроек класса.
static const byte bounce_            =   50; // длительность отслеживания дребезга.
static const byte doubleclick_       =  250; // длительность отслеживания двойного нажатия.
static const unsigned long timer_    = 5000; // длительность отслеживания неактивности.
static const unsigned int retention_ = 500; // длительность отслеживания нажатия и удержания.
//============================================================================================
unsigned long start; // старт отсчёта времени.
boolean p;           // состояние пина кнопки.
boolean s;           // программное состояние кнопки.
boolean b;           // состояние таймера фильтра дребезга.
byte    c;           // переменная счётчика двойного нажатия.
boolean t;           // состояние таймера неактивности.
boolean r;           // состояние таймера нажатия и удержания.
//============================================================
boolean click_down;  // событие нажатия.
boolean click_up;    // событие отпускания.
boolean doubleclick; // событие двойного нажатия.
boolean timer;       // событие неактивности.
boolean retention;   // событие нажатия и удержания.
//============================================================
byte _pb;
//============================================================
BUTTON(byte pb) {
_pb = pb;
pinMode(_pb, INPUT);
digitalWrite(_pb, 1);
//===================
start = millis();
p     = digitalRead(_pb);
// p     = !digitalRead(_pb); // отключить тихий старт.
s     = p;
b     = 0;
c     = 0;
t     = 0;
r     = 0;
//==============
click_down  = 0;
click_up    = 0;
doubleclick = 0;
timer       = 0;
retention   = 0;
//==============
}

void read() {
//==============================================================================
boolean np = digitalRead(_pb); // текущее состояние пина кнопки.
unsigned long stop = millis(); // стоп отсчёта времени.
//==============================================================================
click_down  = 0;
click_up    = 0;
doubleclick = 0;
timer       = 0;
retention   = 0;
//==============================================================================
if (np != p) {p = np; click(); start = stop; b = 1; t = 1; r = 1;} // состояние цифрового пина изменилось.
//==============================================================================
if (b != 0          ) {if (stop - start > bounce_     ) {b = 0; click();      }} // фильтр дребезга.
if (c != 0          ) {if (stop - start > doubleclick_) {c = 0;               }} // обнуление счётчика двойного клика.
if (t != 0 && s == 1) {if (stop - start > timer_      ) {t = 0; timer     = 1;}} // неактивность.
if (r != 0 && s == 0) {if (stop - start > retention_  ) {r = 0; retention = 1;}} // нажатие и удержание.
//==============================================================================
}

void click() {                       // нажатие, отпускание, двойное нажатие.
if (b == 0 && s != p) {s = p;
if (
s == 0) {click_down = 1; ++c; if (c == 2) {c = 0; doubleclick = 1;}}
if (
s == 1) {click_up   = 1;}
}
}

};
// конец class BUTTON
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//конец кода для чтения состояний кнопок ~
//=====================================================================================================================================================================================================================================================










//Подтяжку для кнопок на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм

//                 ТУТ НАЗНАЧАЕМ ИМЕНА НАШИХ КНОПОК И К КАКИМ ПИНАМ ОНИ ПОДКЛЮЧЕНЫ           (также сюда пишем имена переменных, то, что обычно пишется ДО void setup().
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//BUTTON REDbutton(31);     //назначаем красной кнопке ножку 31. То есть один конец конпки подключён на пин 31 ардуины меги, а второй  конец конпки подключён на массу (GND)     Подтяжку на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм
//BUTTON BLACKbutton (33);  //назначаем красной кнопке ножку 33. То есть один конец конпки подключён на пин 33 ардуины меги, а второй  конец конпки подключён на массу (GND)    Подтяжку на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм
BUTTON VOLUPbutton(6);   //назначаем кнопке ГРОМКОСТИ++ ножку D6
BUTTON VOLDNbutton(7);   //назначаем кнопке ГРОМКОСТИ-- ножку D7
BUTTON MUTEbutton(8);   //назначаем кнопке MUTE ножку D8
byte MasterVolume = 26; //СТАВИМ НАЧАЛЬНОЕ ЗНАЧЕНИЕ ГРОМКОСТИ ПРИ ПОДАЧЕ ПИТАНИЯ НА АРДУИНУ - переменная, хранящая в себе громкость выходного звука, 0 - макс громкость, 79- минимальная, 80-255 MUTE http://arduino.ru/Reference/Byte Тип данных byte 8-ми битное беззнаковое целое число, Если DEC - в диапазоне 0..255
#define  VOLUME_INTERVAL  100UL  // интервал(время) между изменениями уровня громкости (0,05 секунд)
boolean Vupupup = 0; //переменная, показывающая надо ли увеличивать громкость раз в #define  VOLUME_INTERVAL  100UL (0,1Сек)
boolean Vdndndn = 0; //переменная, показывающая надо ли уменьшать громкость раз в #define  VOLUME_INTERVAL  100UL (0,1Сек)
byte USCORENIE = 0; //переменная, ускорение изменения громкости при удержании кнопок VOL+ и VOL-
boolean MuteActiv = 0; // Признак включённого режима MUTE (временное отключение громкости)
byte MasterVolumeDoMUTE = 80; //Значение грмкости во время того, как включаем MUTE
//для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int stepVOLamount = 2; // шаг изменения громкости энкодером
unsigned long currentTimeVoumeControl;
unsigned long loopTimeVoumeControl;

enum {ENC_PIN1 = 9, ENC_PIN2 = 10};
// Преобразование значения Грея в двоичный код
// без изменений прямиком из wilipedia
unsigned graydecode(unsigned gray) {
  
unsigned bin;

  for (
bin = 0; gray; gray >>= 1)
    
bin ^= gray;

  return 
bin;
}

//  grayValue - Значение Грея
//  value     - Преобразованное значение Грея
//  oldValue  - Старое преобразованное значение Грея


//конец для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
//=====================================================================================================================================================================================================================================================





 
void setup()    
 { 
Serial.begin(9600); // ком порт     
pinMode(13, OUTPUT); // настройка пина встроенного светодиода на выход (чтоб моргать мог)        
Wire.begin(); // включение библиотеки I2C шины 
//lcd.init();      // initialize the lcd занимает почти секунду
lcd.begin(16, 2);//initialize the lcd newE

/*~~~~~~~~ для энкодера~~~~~~~~~~*/
pinMode(ENC_PIN1, INPUT); //настройка пинов энкодера
digitalWrite(ENC_PIN1, 1);       // включить подтягивающий резистор http://arduino.ru/Tutorial/DigitalPins
pinMode(ENC_PIN2, INPUT);
digitalWrite(ENC_PIN2, 1);
/*~~~~~~~~конец для энкодера~~~~~~~~~~*/
Serial.println("   S E T U P  ok   ");
Serial.println("   ver e24_NEW_E   ");
MasterVolume = 80;//mute
delay (2000);
MasterVolume = 26;
Serial.println("perexodim k osnovnoy programme ");
 } 
//=====================================================================================================================================================================================================================================================



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ЕСЛИ удерживаются кнопки регулировки громкости, то увеличиваем или уменьшаем громкость на один шаг (1dB) с периодичностью (interval - USCORENIE + 8)
void VOLFAST(unsigned long interval )
{
  static 
unsigned long prevTime = 0; // время когда последний раз увеличивали или уменьшали громкость
  
if(millis() - prevTime > interval-USCORENIE) {
                                       
prevTime = millis();  // если зажаты сразу две кнопки, приоритет будет на громкость вниз.
                                       
if (Vupupup == 1 && Vdndndn == 0) {if(interval-USCORENIE>8+20){USCORENIE = USCORENIE + 8;} if (MasterVolume==0){Serial.print ("I tak VOLUME MAX (0dB)  "); } else (MasterVolume--);  Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB");  digitalWrite(13,!digitalRead(13)); } // если зажата громкость вверх, то увеличиваем громкость на один шаг (1dB) с периодичностью interval.
                                       
if (Vdndndn == 1)                 {if(interval-USCORENIE>10+20){USCORENIE = USCORENIE + 10;} if (MasterVolume==80){Serial.print ("I tak VOLUME MIN (80dB-MUTE)   ");}  else (MasterVolume++);    Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); digitalWrite(13,!digitalRead(13)); }// если зажата громкость вниз, то уменьшаем громкость на один шаг (1dB) с периодичностью interval.
  
  
                                      
}
}
 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



/* функция void tda7442 вызов управления по I2C ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void tda7442(byte subaddress, byte data)  //Вызов данных tda7442
{ 
Wire.beginTransmission(0x40); /*СТАРТ (посылается бит старта по I2C шине) и Адрес микросхемы  tda7442  (посылается 7бит адреса по I2C шине и еще один нолик)*/
/*после beginTransmission дуина ждёт по линии ДАТА ответа от tda7442 ( присаживание линии на землю во время 8 бита синхросигнала)и потом передает*/
Wire.write(subaddress);       //Подадрес команды 
Wire.write(data);             //Команда 
Wire.endTransmission();       //СТОП 
/* То есть когда есть связь с tda7442, то функция (void tda7442) посылает сначала первый пакет tda7442(0), потом данные этого пакета 0b01000000
   Потом функция (void tda7442) посылает  второй пакет tda7442(1), потом данные этого пакета 0b00000110
   и так до конца: tda7442(9, 0b00000110); */
}
/*конец void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/




 
void loop() //~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~

 
{ 
VOLUPbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки громкости 
VOLDNbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки громкости 
MUTEbutton.read();     // читаем фильтрованное значение СТАТУСА кнопки MUTE

                          /*               Примеры
                           REDbutton.read();      // читаем фильтрованное значение СТАТУСА кнопки
                           BLACKbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки
                           if (REDbutton.click_down) {Serial.println("REDbutton = najata"); }             //нажатие кнопки  
                           if (REDbutton.click_up) {Serial.println("REDbutton = otpustily"); }            //отпускание кнопки 
                           if (REDbutton.doubleclick) {Serial.println("REDbutton = doubleclick"); }       //двойной клик 
                           if (REDbutton.timer) {Serial.println("REDbutton = neaktivnost knopki"); }      //неактивность 
                           if (REDbutton.retention) {Serial.println("REDbutton = uderjanie");}            // нажатие и удержание  
                           */


 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обработка MUTE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
if (MasterVolume<80&&MuteActiv ==1){MuteActiv = 0;}
 if (
MUTEbutton.click_down)//если кнопка MUTE однократно нажата
        
{ 
       
// Serial.println("   M U T E     ");
        
if (MuteActiv == 0){MasterVolumeDoMUTE = MasterVolume;}
        
MuteActiv = (!MuteActiv); 
        if (
MuteActiv == 1){ MasterVolumeDoMUTE = MasterVolume; MasterVolume=80; }
        if (
MuteActiv==0 ) { MasterVolume = MasterVolumeDoMUTE; MuteActiv = 0; }
        
Serial.print("MuteActiv = " );Serial.print(MuteActiv);Serial.print("   MasterVolume = "); Serial.println(MasterVolume);
       
// Serial.println("   END M U T E     ");
        
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец обработки MUTE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


/*~~~~~~~~~~~~~~~~~~~~~~обработка нажатия кнопок громкости~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
if (VOLUPbutton.click_down) /*если кнопка VOL+ однократно нажата  то ДЕЛАЕМ ШАГ(1 РАЗ): включаем светик, уменьшаем переменную громкости (для увеличения звука)выводим значение громкости в порт.*/
        
{                                                       
           if (
MasterVolume==0){Serial.println ("I tak VOLUME MAX (0dB)"); } else (MasterVolume--);  Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); // выводим значение громкости в ком порт
           
digitalWrite(13,!digitalRead(13)); 
        }
  if (
VOLDNbutton.click_down) /*если кнопка VOL- однократно нажата то ДЕЛАЕМ ШАГ(1 РАЗ): увеличиваем переменную громкости (для уменьшения звука)выводим значение громкости в порт*/
        
{  
           if (
MasterVolume==80){Serial.println ("I tak VOLUME MIN (80dB-MUTE)");}  else (MasterVolume++);    Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); // выводим значение громкости в ком порт
           
digitalWrite(13,!digitalRead(13)); 
        }
/*===================================================================================================================*/

/*~~~~~~~~~~~~~~~~~~~~~~обработка удержания кнопок громкости~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if (VOLUPbutton.retention==1){Vupupup = 1;}//если кнопка нажата  и удерживается //надо бы увеличивать громкость по шагам
if (VOLDNbutton.retention==1){Vdndndn = 1; }     //если кнопка нажата  и удержмвается //надо бы уменьшать громкость по шагам
  
if (VOLUPbutton.click_up) { Vupupup = 0; USCORENIE = 0;}  //если отпустили кнопку, надо бы перестать увеличивать громкость по шагам
  
if (VOLDNbutton.click_up) { Vdndndn = 0; USCORENIE = 0;}       
VOLFAST(VOLUME_INTERVAL); //заходим в функцию VOLFAST, которая  ЕСЛИ удерживаются кнопки регулировки громкости, то увеличивает или уменьшает громкость на один шаг (1dB) с периодичностью VOLUME_INTERVAL.   
/*===================================================================================================================*/



/*для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
static uint8_t oldValue = 0;
  
uint8_t grayValue = digitalRead(ENC_PIN1) | (digitalRead(ENC_PIN2) << 1), value = graydecode(grayValue);

  if (
value == 0) // Энкодер вращается
      
{
    if (
oldValue == 3) { /*  вращение по часовой стрелке // увеличиваем громкость, не более чем до 80*/
                                                      
if(MasterVolume + stepVOLamount <= 80) {(MasterVolume += stepVOLamount); Serial.println(MasterVolume);digitalWrite(13,!digitalRead(13));}
                       }
    else if (
oldValue == 1) { // Влево
                             
if(MasterVolume - stepVOLamount >= 0){ (MasterVolume -= stepVOLamount); Serial.println(MasterVolume);digitalWrite(13,!digitalRead(13)); }  /* уменьшаем громкость, но не ниже 0*/
                            
}
      }



  
oldValue = value;


/*конец для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

     



/*конфигурация void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

tda7442(0, 0b01000000);  //INPUT ATTENUATION    приглушение ВХОДНОГО (IN1-IN4) канала (0 ~ -31.5dB)(0db-макс громкость, без приглушения)
tda7442(1, 0b00000110);  //SURROUND & OUT & EFFECT CONTROL( -6 FIX OFF)
tda7442(2, 0b00000011);  //SURROUND PHASE RESISTOR( 37KOm)
tda7442(3, 0b00011111);  //BXXX0011 BASS SELECTION (0dB)-14dB  (0b0001100 = 14dB; 0b00011000 + 0b00000001 = 0b00011001 (+12dB) 
tda7442(4, 0b01111110);  //BXXX0100 TREBLE (0dB)
//tda7442(5, 0b00000000);  //BXXX0101 SPEAKER ATTENUATION "L" (0dB)( SPEAKER SELECTION = 0dB ~ -79dB) громкость правого канала
//tda7442(6, 0b00000000);  //BXXX0110 SPEAKER ATTENUATION "R" (0dB) громкость левого канала
// регулировку громкости можно делать  0dB ~ -79dB в DEC c шагом 1. если (80-255) - то MUTE  
tda7442(5,  MasterVolume); //0 - макс громкость, 80-255 - MUTE .  
tda7442(6,  MasterVolume);
tda7442(7, 0b00000000);  //BXXX0111 NOT ALLOWED
tda7442(8, 0b00000000);  //BXXX1000 NOT ALLOWED         
tda7442(9, 6/*0b00000110*/);  //BXXX1001 INPUT MULTIPLEXER выбор источника IN1-4 (6-in1 4-in4  2-in3 0-in2)
/*конец конфигурации void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/





  
lcd.backlight();
  
  
  
  
  
int Mdisp =map(MasterVolume, 0, 80, 80, 0);// переменная, зеркалим значение громкости, чтобы нормально выводить на дисплей(громче-больше)http://arduino.ua/ru/prog/Map
  
  
  
  
  
  
lcd.printHorizontalGraph('v', 0, Mdisp, 80); //name of the bar, first  row, current value, max. value
  
lcd.setCursor(0, 0);
  
//lcd.print((millis() )/1000); // вывод кол-ва сек работы блока ( 1 строка 1 символ)
  
  
lcd.setCursor(7, 0);
  
/*lcd.print(flagAKB); // вывод флага AKB
  
  lcd.setCursor(8, 0);
  lcd.print(flagACC); // вывод флага АСС
  
  lcd.setCursor(9, 0);
  lcd.print(flagREM); // вывод флага rem
  lcd.setCursor(11, 0);
  lcd.print(U_acc_real); // вывод напряжения АСС
  
  //lcd.setCursor(5,1);
  */
  //-------------------2 строка---------------------------------
  
lcd.setCursor(0, 1);
  
lcd.print("VOLUME -");
  
lcd.setCursor(8, 1);
  if (
MasterVolume==80){ lcd.print("MUTE");} else  {lcd.print(MasterVolume); }
  
lcd.setCursor(11, 1);
  
lcd.print("dB");


















}
//конец LOOP//~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~
//=====================================================================================================================================================================================================================================================
//__________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ 

Последний раз редактировалось oleg707; 18.10.2016 в 02:13.
oleg707 вне форума   Ответить с цитированием
Старый 18.10.2016, 22:50   #25
oleg707
Гуру
 
Аватар для oleg707
 
Регистрация: 16.04.2014
Возраст: 42
Город: Gdynia
Регион: другой - для добавления сообщить ab
Сообщений: 2,548
oleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond repute
По умолчанию

столкнулся с одним моментом. Когда подключен дисплей, то звуковой тракт ловит помеху от I2C шины. Если дисплей отключен - всё тихо.
Выражается в лёгком писке.
Как бороть?


РАЗОБРАЛСЯ.
Не было массы на кондёре С4, который идёт на ножку 23(CREF).
Из-за этого шла помеха от I2C шины на OUT.
Теперь на максимальной громкости абсолютная тишина.

Последний раз редактировалось oleg707; 20.10.2016 в 22:36.
oleg707 вне форума   Ответить с цитированием
Старый 19.10.2016, 00:04   #26
demtro
Старший Пользователь
 
Регистрация: 17.12.2014
Возраст: 35
Город: Самара
Регион: 63, 163
Машина: Lifan Solano
Сообщений: 184
demtro is on a distinguished road
По умолчанию

Если не трудно в диптрейсе укажите номиналы элементов, какую атмегу используете? Планирую повторить вашу схему с небольшими доработками и добавлением необходимых мне частей
demtro вне форума   Ответить с цитированием
Старый 19.10.2016, 00:19   #27
oleg707
Гуру
 
Аватар для oleg707
 
Регистрация: 16.04.2014
Возраст: 42
Город: Gdynia
Регион: другой - для добавления сообщить ab
Сообщений: 2,548
oleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond repute
По умолчанию

Цитата:
Сообщение от demtro Посмотреть сообщение
Если не трудно в диптрейсе укажите номиналы элементов, какую атмегу используете? Планирую повторить вашу схему с небольшими доработками и добавлением необходимых мне частей
328P. Можно 8, они по выводам одинаковые. Только скетч сразу залить.
номиналы в диптрейсе указаны, или я что пропустил?
oleg707 вне форума   Ответить с цитированием
Старый 21.10.2016, 01:24   #28
oleg707
Гуру
 
Аватар для oleg707
 
Регистрация: 16.04.2014
Возраст: 42
Город: Gdynia
Регион: другой - для добавления сообщить ab
Сообщений: 2,548
oleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond repute
По умолчанию вот скетч, который начал меня устраивать 3

PHP код:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Скетч v29 i7442
// с подавлением дребезга кнопок 
// с динамическим увеличением/уменьшением громкости при удержании кнопок ( с УСКОРЕНИЕМ при удержании)
// с энкодером (код грея - коррекция ошибок энкодера) 
// динамическое изменение скорости уменьшения\увеличения громкости при долгом воздействии на энкодер++. (требуется тонкая подстройка в реальной машине)
// с функцией MUTE
// дисплей по I2C
// с ползунком громкости
// с монитором по ком-порту
//мигание встроенного светодиода при вращении энкодером или при нажатии-удержании кнопок громкости.
//без активации внутреннего эквалайзера TDA7442D 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// класс титановый велосипед для тактовой кнопки. (версия 1.0)http://arduino.ru/forum/programmirovanie/klass-titanovyi-velosiped-dlya-taktovoi-knopki
// фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick), нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени.

#include <Arduino.h>
#include <Wire.h> /*добавление библиотеки I2C шины*/
#include <LiquidCrystal_I2C.h>  /*добавление библиотеки для работы с дисплеем по I2C*/
//LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display для 0x27 - настройка экрана для библиотеки LiquidCrystal_I2C2004V1
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE);  // для newE  описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347



  


class BUTTON {
public:
//============================================================================================
// константы настроек класса.
static const byte bounce_            =   50; // длительность отслеживания дребезга.
static const byte doubleclick_       =  250; // длительность отслеживания двойного нажатия.
static const unsigned long timer_    = 5000; // длительность отслеживания неактивности.
static const unsigned int retention_ = 500; // длительность отслеживания нажатия и удержания.
//============================================================================================
unsigned long start; // старт отсчёта времени.
boolean p;           // состояние пина кнопки.
boolean s;           // программное состояние кнопки.
boolean b;           // состояние таймера фильтра дребезга.
byte    c;           // переменная счётчика двойного нажатия.
boolean t;           // состояние таймера неактивности.
boolean r;           // состояние таймера нажатия и удержания.
//============================================================
boolean click_down;  // событие нажатия.
boolean click_up;    // событие отпускания.
boolean doubleclick; // событие двойного нажатия.
boolean timer;       // событие неактивности.
boolean retention;   // событие нажатия и удержания.
//============================================================
byte _pb;
//============================================================
BUTTON(byte pb) {
_pb = pb;
pinMode(_pb, INPUT);
digitalWrite(_pb, 1);
//===================
start = millis();
p     = digitalRead(_pb);
// p     = !digitalRead(_pb); // отключить тихий старт.
s     = p;
b     = 0;
c     = 0;
t     = 0;
r     = 0;
//==============
click_down  = 0;
click_up    = 0;
doubleclick = 0;
timer       = 0;
retention   = 0;
//==============
}

void read() {
//==============================================================================
boolean np = digitalRead(_pb); // текущее состояние пина кнопки.
unsigned long stop = millis(); // стоп отсчёта времени.
//==============================================================================
click_down  = 0;
click_up    = 0;
doubleclick = 0;
timer       = 0;
retention   = 0;
//==============================================================================
if (np != p) {p = np; click(); start = stop; b = 1; t = 1; r = 1;} // состояние цифрового пина изменилось.
//==============================================================================
if (b != 0          ) {if (stop - start > bounce_     ) {b = 0; click();      }} // фильтр дребезга.
if (c != 0          ) {if (stop - start > doubleclick_) {c = 0;               }} // обнуление счётчика двойного клика.
if (t != 0 && s == 1) {if (stop - start > timer_      ) {t = 0; timer     = 1;}} // неактивность.
if (r != 0 && s == 0) {if (stop - start > retention_  ) {r = 0; retention = 1;}} // нажатие и удержание.
//==============================================================================
}

void click() {                       // нажатие, отпускание, двойное нажатие.
if (b == 0 && s != p) {s = p;
if (
s == 0) {click_down = 1; ++c; if (c == 2) {c = 0; doubleclick = 1;}}
if (
s == 1) {click_up   = 1;}
}
}

};
// конец class BUTTON
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//конец кода для чтения состояний кнопок ~
//=====================================================================================================================================================================================================================================================










//Подтяжку для кнопок на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм

//                 ТУТ НАЗНАЧАЕМ ИМЕНА НАШИХ КНОПОК И К КАКИМ ПИНАМ ОНИ ПОДКЛЮЧЕНЫ           (также сюда пишем имена переменных, то, что обычно пишется ДО void setup().
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//BUTTON REDbutton(31);     //назначаем красной кнопке ножку 31. То есть один конец конпки подключён на пин 31 ардуины меги, а второй  конец конпки подключён на массу (GND)     Подтяжку на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм
//BUTTON BLACKbutton (33);  //назначаем красной кнопке ножку 33. То есть один конец конпки подключён на пин 33 ардуины меги, а второй  конец конпки подключён на массу (GND)    Подтяжку на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм
BUTTON VOLUPbutton(6);   //назначаем кнопке ГРОМКОСТИ++ ножку D6
BUTTON VOLDNbutton(7);   //назначаем кнопке ГРОМКОСТИ-- ножку D7
BUTTON MUTEbutton(8);   //назначаем кнопке MUTE ножку D8
byte MasterVolume = 24; //СТАВИМ НАЧАЛЬНОЕ ЗНАЧЕНИЕ ГРОМКОСТИ ПРИ ПОДАЧЕ ПИТАНИЯ НА АРДУИНУ - переменная, хранящая в себе громкость выходного звука, 0 - макс громкость, 79- минимальная, 80-255 MUTE http://arduino.ru/Reference/Byte Тип данных byte 8-ми битное беззнаковое целое число, Если DEC - в диапазоне 0..255
#define  VOLUME_INTERVAL  100UL  // интервал(время) между изменениями уровня громкости (0,05 секунд)
boolean Vupupup = 0; //переменная, показывающая надо ли увеличивать громкость раз в #define  VOLUME_INTERVAL  100UL (0,1Сек)
boolean Vdndndn = 0; //переменная, показывающая надо ли уменьшать громкость раз в #define  VOLUME_INTERVAL  100UL (0,1Сек)
byte USCORENIE = 0; //переменная, ускорение изменения громкости при удержании кнопок VOL+ и VOL-
boolean MuteActiv = 0; // Признак включённого режима MUTE (временное отключение громкости)
byte MasterVolumeDoMUTE = 80; //Значение грмкости во время того, как включаем MUTE

//====================================================================================
//для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
byte stepVOLamount = 0; // шаг изменения громкости энкодером. Логика меняется в строках 310
int stepENC = 0; // шаг изменения громкости энкодером в режиме ускорения (постоянное вращение)

unsigned long currentTimeVoumeControl;
unsigned long loopTimeVoumeControl;
 
unsigned long prevTimeE = millis(); // время когда последний раз переключали энкодер

enum {ENC_PIN1 = 9, ENC_PIN2 = 10};
// Преобразование значения Грея в двоичный код
// без изменений прямиком из wilipedia


unsigned graydecode(unsigned gray) {
  
unsigned bin;

  for (
bin = 0; gray; gray >>= 1)
    
bin ^= gray;

  return 
bin;
}

//  grayValue - Значение Грея
//  value     - Преобразованное значение Грея
//  oldValue  - Старое преобразованное значение Грея


//конец для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
//====================================================================================
//=====================================================================================================================================================================================================================================================





 
void setup()    
 { 
Serial.begin(9600); // ком порт     
pinMode(13, OUTPUT); // настройка пина встроенного светодиода на выход (чтоб моргать мог)        
Wire.begin(); // включение библиотеки I2C шины 
//lcd.init();      // initialize the lcd занимает почти секунду
lcd.begin(16, 2);//initialize the lcd newE

/*~~~~~~~~ для энкодера~~~~~~~~~~*/
pinMode(ENC_PIN1, INPUT); //настройка пинов энкодера
digitalWrite(ENC_PIN1, 1);       // включить подтягивающий резистор http://arduino.ru/Tutorial/DigitalPins
pinMode(ENC_PIN2, INPUT);
digitalWrite(ENC_PIN2, 1);

/*~~~~~~~~конец для энкодера~~~~~~~~~~*/
Serial.println("   S E T U P  ok   ");
Serial.println("   ver e31_NEW_E   ");
MasterVolume = 80;//mute
delay (2000);
MasterVolume = 24;
Serial.println("perexodim k osnovnoy programme ");
 } 
//=====================================================================================================================================================================================================================================================



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ЕСЛИ удерживаются кнопки регулировки громкости, то увеличиваем или уменьшаем громкость на один шаг (1dB) с периодичностью (interval - USCORENIE + 8)
void VOLFAST(unsigned long interval )
{
  static 
unsigned long prevTime = 0; // время когда последний раз увеличивали или уменьшали громкость
  
if(millis() - prevTime > interval-USCORENIE) {
                                       
prevTime = millis();  // если зажаты сразу две кнопки, приоритет будет на громкость вниз.
                                       
if (Vupupup == 1 && Vdndndn == 0) {if(interval-USCORENIE>8+20){USCORENIE = USCORENIE + 8;} if (MasterVolume==0){Serial.print ("I tak VOLUME MAX (0dB)  "); } else (MasterVolume--);  Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB");  digitalWrite(13,!digitalRead(13)); } // если зажата громкость вверх, то увеличиваем громкость на один шаг (1dB) с периодичностью interval.
                                       
if (Vdndndn == 1)                 {if(interval-USCORENIE>10+20){USCORENIE = USCORENIE + 10;} if (MasterVolume==80){Serial.print ("I tak VOLUME MIN (80dB-MUTE)   ");}  else (MasterVolume++);    Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); digitalWrite(13,!digitalRead(13)); }// если зажата громкость вниз, то уменьшаем громкость на один шаг (1dB) с периодичностью interval.
  
  
                                      
}
}
 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



/* функция void tda7442 вызов управления по I2C ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void tda7442(byte subaddress, byte data)  //Вызов данных tda7442
{ 
Wire.beginTransmission(0x40); /*СТАРТ (посылается бит старта по I2C шине) и Адрес микросхемы  tda7442  (посылается 7бит адреса по I2C шине и еще один нолик)*/
/*после beginTransmission дуина ждёт по линии ДАТА ответа от tda7442 ( присаживание линии на землю во время 8 бита синхросигнала)и потом передает*/
Wire.write(subaddress);       //Подадрес команды 
Wire.write(data);             //Команда 
Wire.endTransmission();       //СТОП 
/* То есть когда есть связь с tda7442, то функция (void tda7442) посылает сначала первый пакет tda7442(0), потом данные этого пакета 0b01000000
   Потом функция (void tda7442) посылает  второй пакет tda7442(1), потом данные этого пакета 0b00000110
   и так до конца: tda7442(9, 0b00000110); */
}
/*конец void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//===========================================================================================================================================================================
//===========================================================================================================================================================================
//===========================================================================================================================================================================

void printDISPLAY(unsigned long interval){
  static 
unsigned long prevTime=0;
  if(
millis()-prevTime>interval){
    
prevTime=millis();
     
     
int Mdisp =map(MasterVolume, 0, 80, 80, 0);// переменная, зеркалим значение громкости, чтобы нормально выводить на дисплей(громче-больше)http://arduino.ua/ru/prog/Map
  
  
  
  
  
  
lcd.printHorizontalGraph('v', 0, Mdisp, 80); //name of the bar, first  row, current value, max. value
  
lcd.setCursor(0, 0);
  
//lcd.print((millis() )/1000); // вывод кол-ва сек работы блока ( 1 строка 1 символ)
  
  
lcd.setCursor(7, 0);
  
  
//-------------------2 строка---------------------------------
  
lcd.setCursor(0, 1);
  if (
MasterVolume==80){ lcd.print("  MUTE  ");  } else  {lcd.print("VOLUME -");  }
 
// lcd.write(("VOLUME -")+(MasterVolume));   // так получится только с двумя аргументами
 
lcd.print(MasterVolume);
//  lcd.setCursor(12, 1);
lcd.print(" dB ");

if (
13,1){digitalWrite(13,0);}
//lcd.noBacklight();
//lcd.Backlight();
 
  
}
}



//===========================================================================================================================================================================
//===========================================================================================================================================================================
//===========================================================================================================================================================================

void ENCODER (unsigned long interval){
  static 
unsigned long prevTime=0;
  if(
millis()-prevTime>interval){
    
prevTime=millis();
    
//    ENCuscorenie(500);
      
static uint8_t oldValue = 0;
  
uint8_t grayValue = digitalRead(ENC_PIN1) | (digitalRead(ENC_PIN2) << 1), value = graydecode(grayValue);


  

  if (
stepENC >0)
  {
    if((
millis() - prevTimeE > 120 )  ) 
    {
      
      if (
stepENC>6){stepENC=6;}//НАДО ОбНУЛЯТЬРАЗ В 420
         
if((millis() - prevTimeE > 130 )  ) { prevTimeE = millis(); stepENC--; }
    }
  }

  if (
value == 0) // Энкодер вращается
      
{ 
         
     


    if (
oldValue == 3) { /*  вращение по часовой стрелке // увеличиваем громкость, не более чем до 80*/
                                                      
                                                        
if (MasterVolume == 80){stepENC = 1;} else {stepENC++;}    Serial.println(stepENC);
                                                        if( 
stepENC < 6 ) {stepVOLamount = 1;}
                                                        else  if( 
stepENC < 10 ) {stepVOLamount = 4;}
                                                        else  if( 
stepENC < 14 ) {stepVOLamount = 6;}
                                                        else  if( 
stepENC < 24 ) {stepVOLamount = 8;}
                                                        
prevTimeE = millis();
                                                        if(
MasterVolume + stepVOLamount <= 80) {(MasterVolume += stepVOLamount);}else {MasterVolume = 80;}
                                                        
                                                      
                       }
    else if (
oldValue == 1) { // Влево


                                                        
if (MasterVolume == 0){stepENC = 1;} else {stepENC++;}    Serial.println(stepENC);
                                                        if( 
stepENC < 3 ) {stepVOLamount = 1;}
                                                        else  if( 
stepENC < 6 ) {stepVOLamount = 4;}
                                                        else  if( 
stepENC < 12 ) {stepVOLamount = 6;}
                                                        else  if( 
stepENC < 18 ) {stepVOLamount = 10;}
                                                        
prevTimeE = millis();
                                                        if(
MasterVolume - stepVOLamount >= 0){ (MasterVolume -= stepVOLamount);} else{ MasterVolume = 0; /*Serial.println(MasterVolume);*/ }  /* уменьшаем громкость, но не ниже 0*/
                             
                            
}
      }
     
 

 
  
oldValue = value;

          

 
  }
}

//===========================================================================================================================================================================
//===========================================================================================================================================================================
//===========================================================================================================================================================================
/*/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  с периодичностью interval
void ENCuscorenie(unsigned long interval )
{

  static unsigned long prevTime = 0; // время когда последний раз переключали 
  if((millis() - prevTime > interval)  ) 
  {
    prevTime = millis();  // 
    digitalWrite(13,0); 
    
    
  }
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
//===========================================================================================================================================================================
//===========================================================================================================================================================================
//===========================================================================================================================================================================

 
void loop() //~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~

 
{ 
  
 
VOLUPbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки громкости 
VOLDNbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки громкости 
MUTEbutton.read();     // читаем фильтрованное значение СТАТУСА кнопки MUTE

                          /*               Примеры
                           REDbutton.read();      // читаем фильтрованное значение СТАТУСА кнопки
                           BLACKbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки
                           if (REDbutton.click_down) {Serial.println("REDbutton = najata"); }             //нажатие кнопки  
                           if (REDbutton.click_up) {Serial.println("REDbutton = otpustily"); }            //отпускание кнопки 
                           if (REDbutton.doubleclick) {Serial.println("REDbutton = doubleclick"); }       //двойной клик 
                           if (REDbutton.timer) {Serial.println("REDbutton = neaktivnost knopki"); }      //неактивность 
                           if (REDbutton.retention) {Serial.println("REDbutton = uderjanie");}            // нажатие и удержание  
                           */


 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обработка MUTE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
if (MasterVolume<80&&MuteActiv ==1){MuteActiv = 0;}
 if (
MUTEbutton.click_down)//если кнопка MUTE однократно нажата
        
{ 
       
// Serial.println("   M U T E     ");
        
if (MuteActiv == 0){MasterVolumeDoMUTE = MasterVolume;}
        
MuteActiv = (!MuteActiv); 
        if (
MuteActiv == 1){ MasterVolumeDoMUTE = MasterVolume; MasterVolume=80; }
        if (
MuteActiv==0 ) { MasterVolume = MasterVolumeDoMUTE; MuteActiv = 0; }
        
Serial.print("MuteActiv = " );Serial.print(MuteActiv);Serial.print("   MasterVolume = "); Serial.println(MasterVolume);
       
// Serial.println("   END M U T E     ");
        
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец обработки MUTE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


/*~~~~~~~~~~~~~~~~~~~~~~обработка нажатия кнопок громкости~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
if (VOLUPbutton.click_down) /*если кнопка VOL+ однократно нажата  то ДЕЛАЕМ ШАГ(1 РАЗ): включаем светик, уменьшаем переменную громкости (для увеличения звука)выводим значение громкости в порт.*/
        
{                                                       
           if (
MasterVolume==0){Serial.println ("I tak VOLUME MAX (0dB)"); } else (MasterVolume--);  Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); // выводим значение громкости в ком порт
           
digitalWrite(13,!digitalRead(13)); 
        }
  if (
VOLDNbutton.click_down) /*если кнопка VOL- однократно нажата то ДЕЛАЕМ ШАГ(1 РАЗ): увеличиваем переменную громкости (для уменьшения звука)выводим значение громкости в порт*/
        
{  
           if (
MasterVolume==80){Serial.println ("I tak VOLUME MIN (80dB-MUTE)");}  else (MasterVolume++);    Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); // выводим значение громкости в ком порт
           
digitalWrite(13,!digitalRead(13)); 
        }
/*===================================================================================================================*/

/*~~~~~~~~~~~~~~~~~~~~~~обработка удержания кнопок громкости~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if (VOLUPbutton.retention==1){Vupupup = 1;}                  //если кнопка нажата  и удерживается //надо бы увеличивать громкость по шагам
if (VOLDNbutton.retention==1){Vdndndn = 1; }                 //если кнопка нажата  и удержмвается //надо бы уменьшать громкость по шагам
  
if (VOLUPbutton.click_up) { Vupupup = 0; USCORENIE = 0;}   //если отпустили кнопку, надо бы перестать увеличивать громкость по шагам
  
if (VOLDNbutton.click_up) { Vdndndn = 0; USCORENIE = 0;}       
VOLFAST(VOLUME_INTERVAL); //заходим в функцию VOLFAST, которая  ЕСЛИ удерживаются кнопки регулировки громкости, то увеличивает или уменьшает громкость на один шаг (1dB) с периодичностью VOLUME_INTERVAL.   
/*===================================================================================================================*/



/*для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
ENCODER(0); // опрос энкодера раз в 0 миллисекунду
/*конец для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

     



/*конфигурация void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

tda7442(0, 0b01000000);  //INPUT ATTENUATION    приглушение ВХОДНОГО (IN1-IN4) канала (0 ~ -31.5dB)(0db-макс громкость, без приглушения)
tda7442(1, 0b00000110);  //SURROUND & OUT & EFFECT CONTROL( -6 FIX OFF)
tda7442(2, 0b00000011);  //SURROUND PHASE RESISTOR( 37KOm)
tda7442(3, 0b00011111);  //BXXX0011 BASS SELECTION (0dB)-14dB  (0b0001100 = 14dB; 0b00011000 + 0b00000001 = 0b00011001 (+12dB) 
tda7442(4, 0b01111110);  //BXXX0100 TREBLE (0dB)
//tda7442(5, 0b00000000);  //BXXX0101 SPEAKER ATTENUATION "L" (0dB)( SPEAKER SELECTION = 0dB ~ -79dB) громкость правого канала
//tda7442(6, 0b00000000);  //BXXX0110 SPEAKER ATTENUATION "R" (0dB) громкость левого канала
// регулировку громкости можно делать  0dB ~ -79dB в DEC c шагом 1. если (80-255) - то MUTE  
tda7442(5,  MasterVolume); //0 - макс громкость, 80-255 - MUTE .  
tda7442(6,  MasterVolume);
tda7442(7, 0b00000000);  //BXXX0111 NOT ALLOWED
tda7442(8, 0b00000000);  //BXXX1000 NOT ALLOWED         
tda7442(9, 6/*0b00000110*/);  //BXXX1001 INPUT MULTIPLEXER выбор источника IN1-4 (6-in1 4-in4  2-in3 0-in2)
/*конец конфигурации void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/





 
  
  
  
  
 








printDISPLAY(100); // выводим на дисплей раз в 100( запуская фушкцию)






}//конец LOOP//~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~
//=====================================================================================================================================================================================================================================================
//__________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ 

Последний раз редактировалось oleg707; 21.10.2016 в 22:36. Причина: доработка
oleg707 вне форума   Ответить с цитированием
Старый 24.10.2016, 22:28   #29
oleg707
Гуру
 
Аватар для oleg707
 
Регистрация: 16.04.2014
Возраст: 42
Город: Gdynia
Регион: другой - для добавления сообщить ab
Сообщений: 2,548
oleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond reputeoleg707 has a reputation beyond repute
По умолчанию

PHP код:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Скетч v32 i7442
// с подавлением дребезга кнопок 
// с динамическим увеличением/уменьшением громкости при удержании кнопок ( с УСКОРЕНИЕМ при удержании)
// с энкодером (код грея - коррекция ошибок энкодера) 
// динамическое изменение скорости уменьшения\увеличения громкости при долгом воздействии на энкодер++. (требуется тонкая подстройка в реальной машине)
// с функцией MUTE
// дисплей по I2C
// с ползунком громкости на дисплее
// с монитором по ком-порту
//мигание встроенного светодиода при вращении энкодером или при нажатии-удержании кнопок громкости.
//без активации внутреннего эквалайзера TDA7442D 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// класс титановый велосипед для тактовой кнопки. (версия 1.0)http://arduino.ru/forum/programmirovanie/klass-titanovyi-velosiped-dlya-taktovoi-knopki
// фильтр дребезга, отслеживание событий: нажатие, отпускание, двойное нажатие(doubleclick), нажато и удерживается в течении определённого времени, отпущено и неактивно в течении определённого времени.

#include <Arduino.h>
#include <Wire.h> /*добавление библиотеки I2C шины*/
#include <LiquidCrystal_I2C.h>  /*добавление библиотеки для работы с дисплеем по I2C*/
//LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display для 0x27 - настройка экрана для библиотеки LiquidCrystal_I2C2004V1
LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE);  // для newE  описание библиотеки http://elchupanibrei.livejournal.com/27443.html#t23347



  


class BUTTON {
public:
//============================================================================================
// константы настроек класса.
static const byte bounce_            =   50; // длительность отслеживания дребезга.
static const byte doubleclick_       =  250; // длительность отслеживания двойного нажатия.
static const unsigned long timer_    = 5000; // длительность отслеживания неактивности.
static const unsigned int retention_ = 500; // длительность отслеживания нажатия и удержания.
//============================================================================================
unsigned long start; // старт отсчёта времени.
boolean p;           // состояние пина кнопки.
boolean s;           // программное состояние кнопки.
boolean b;           // состояние таймера фильтра дребезга.
byte    c;           // переменная счётчика двойного нажатия.
boolean t;           // состояние таймера неактивности.
boolean r;           // состояние таймера нажатия и удержания.
//============================================================
boolean click_down;  // событие нажатия.
boolean click_up;    // событие отпускания.
boolean doubleclick; // событие двойного нажатия.
boolean timer;       // событие неактивности.
boolean retention;   // событие нажатия и удержания.
//============================================================
byte _pb;
//============================================================
BUTTON(byte pb) {
_pb = pb;
pinMode(_pb, INPUT);
digitalWrite(_pb, 1);
//===================
start = millis();
p     = digitalRead(_pb);
// p     = !digitalRead(_pb); // отключить тихий старт.
s     = p;
b     = 0;
c     = 0;
t     = 0;
r     = 0;
//==============
click_down  = 0;
click_up    = 0;
doubleclick = 0;
timer       = 0;
retention   = 0;
//==============
}

void read() {
//==============================================================================
boolean np = digitalRead(_pb); // текущее состояние пина кнопки.
unsigned long stop = millis(); // стоп отсчёта времени.
//==============================================================================
click_down  = 0;
click_up    = 0;
doubleclick = 0;
timer       = 0;
retention   = 0;
//==============================================================================
if (np != p) {p = np; click(); start = stop; b = 1; t = 1; r = 1;} // состояние цифрового пина изменилось.
//==============================================================================
if (b != 0          ) {if (stop - start > bounce_     ) {b = 0; click();      }} // фильтр дребезга.
if (c != 0          ) {if (stop - start > doubleclick_) {c = 0;               }} // обнуление счётчика двойного клика.
if (t != 0 && s == 1) {if (stop - start > timer_      ) {t = 0; timer     = 1;}} // неактивность.
if (r != 0 && s == 0) {if (stop - start > retention_  ) {r = 0; retention = 1;}} // нажатие и удержание.
//==============================================================================
}

void click() {                       // нажатие, отпускание, двойное нажатие.
if (b == 0 && s != p) {s = p;
if (
s == 0) {click_down = 1; ++c; if (c == 2) {c = 0; doubleclick = 1;}}
if (
s == 1) {click_up   = 1;}
}
}

};
// конец class BUTTON
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//конец кода для чтения состояний кнопок ~
//=====================================================================================================================================================================================================================================================










//Подтяжку для кнопок на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм

//                 ТУТ НАЗНАЧАЕМ ИМЕНА НАШИХ КНОПОК И К КАКИМ ПИНАМ ОНИ ПОДКЛЮЧЕНЫ           (также сюда пишем имена переменных, то, что обычно пишется ДО void setup().
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//BUTTON REDbutton(31);     //назначаем красной кнопке ножку 31. То есть один конец конпки подключён на пин 31 ардуины меги, а второй  конец конпки подключён на массу (GND)     Подтяжку на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм
//BUTTON BLACKbutton (33);  //назначаем красной кнопке ножку 33. То есть один конец конпки подключён на пин 33 ардуины меги, а второй  конец конпки подключён на массу (GND)    Подтяжку на +5В делать не надо,  код для чтения состояний кнопок включает внутренний подтягивающий резистор на 20кОм
BUTTON VOLUPbutton(6);   //назначаем кнопке ГРОМКОСТИ++ ножку D6
BUTTON VOLDNbutton(7);   //назначаем кнопке ГРОМКОСТИ-- ножку D7
BUTTON MUTEbutton(8);   //назначаем кнопке MUTE ножку D8
byte MasterVolume = 24; //СТАВИМ НАЧАЛЬНОЕ ЗНАЧЕНИЕ ГРОМКОСТИ ПРИ ПОДАЧЕ ПИТАНИЯ НА АРДУИНУ - переменная, хранящая в себе громкость выходного звука, 0 - макс громкость, 79- минимальная, 80-255 MUTE http://arduino.ru/Reference/Byte Тип данных byte 8-ми битное беззнаковое целое число, Если DEC - в диапазоне 0..255
#define  VOLUME_INTERVAL  100UL  // интервал(время) между изменениями уровня громкости (0,05 секунд)
boolean Vupupup = 0; //переменная, показывающая надо ли увеличивать громкость раз в #define  VOLUME_INTERVAL  100UL (0,1Сек)
boolean Vdndndn = 0; //переменная, показывающая надо ли уменьшать громкость раз в #define  VOLUME_INTERVAL  100UL (0,1Сек)
byte USCORENIE = 0; //переменная, ускорение изменения громкости при удержании кнопок VOL+ и VOL-
boolean MuteActiv = 0; // Признак включённого режима MUTE (временное отключение громкости)
byte MasterVolumeDoMUTE = 80; //Значение грмкости во время того, как включаем MUTE

//====================================================================================
//для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
byte stepVOLamount = 0; // шаг изменения громкости энкодером. Логика меняется в строках 310
int stepENC = 0; // шаг изменения громкости энкодером в режиме ускорения (постоянное вращение)

unsigned long currentTimeVoumeControl;
unsigned long loopTimeVoumeControl;
unsigned long prevTimeE = millis(); // время когда последний раз переключали энкодер

enum {ENC_PIN1 = 9, ENC_PIN2 = 10};
// Преобразование значения Грея в двоичный код
// без изменений прямиком из wilipedia


unsigned graydecode(unsigned gray) {
  
unsigned bin;

  for (
bin = 0; gray; gray >>= 1)
    
bin ^= gray;

  return 
bin;
}

//  grayValue - Значение Грея
//  value     - Преобразованное значение Грея
//  oldValue  - Старое преобразованное значение Грея


//конец для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
//====================================================================================
//=====================================================================================================================================================================================================================================================





 
void setup()    
 { 
Serial.begin(9600); // ком порт     
pinMode(13, OUTPUT); // настройка пина встроенного светодиода на выход (чтоб моргать мог)        
Wire.begin(); // включение библиотеки I2C шины 
//lcd.init();      // initialize the lcd занимает почти секунду
lcd.begin(16, 2);//initialize the lcd newE

/*~~~~~~~~ для энкодера~~~~~~~~~~*/
pinMode(ENC_PIN1, INPUT); //настройка пинов энкодера
digitalWrite(ENC_PIN1, 1);       // включить подтягивающий резистор http://arduino.ru/Tutorial/DigitalPins
pinMode(ENC_PIN2, INPUT);
digitalWrite(ENC_PIN2, 1);

/*~~~~~~~~конец для энкодера~~~~~~~~~~*/
Serial.println("   S E T U P  ok   ");
Serial.println("   ver e32_NEW_Eopt   ");
MasterVolume = 80;//mute
lcd.noBacklight();
delay (2000);
MasterVolume = 24;
Serial.println("perexodim k osnovnoy programme ");
lcd.backlight();
 } 
//=====================================================================================================================================================================================================================================================



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ЕСЛИ удерживаются кнопки регулировки громкости, то увеличиваем или уменьшаем громкость на один шаг (1dB) с периодичностью (interval - USCORENIE + 8)
void VOLFAST(unsigned long interval )
{
  static 
unsigned long prevTime = 0; // время когда последний раз увеличивали или уменьшали громкость
  
if(millis() - prevTime > interval-USCORENIE) {
                                       
prevTime = millis();  // если зажаты сразу две кнопки, приоритет будет на громкость вниз.
                                       
if (Vupupup == 1 && Vdndndn == 0) {if(interval-USCORENIE>8+20){USCORENIE = USCORENIE + 8;} if (MasterVolume==0){Serial.print ("I tak VOLUME MAX (0dB)  "); } else (MasterVolume--);  Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB");  digitalWrite(13,!digitalRead(13)); } // если зажата громкость вверх, то увеличиваем громкость на один шаг (1dB) с периодичностью interval.
                                       
if (Vdndndn == 1)                 {if(interval-USCORENIE>10+20){USCORENIE = USCORENIE + 10;} if (MasterVolume==80){Serial.print ("I tak VOLUME MIN (80dB-MUTE)   ");}  else (MasterVolume++);    Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); digitalWrite(13,!digitalRead(13)); }// если зажата громкость вниз, то уменьшаем громкость на один шаг (1dB) с периодичностью interval.
  
  
                                      
}
}
 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



/* функция void tda7442 вызов управления по I2C ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void tda7442(byte subaddress, byte data)  //Вызов данных tda7442
{ 
Wire.beginTransmission(0x40); /*СТАРТ (посылается бит старта по I2C шине) и Адрес микросхемы  tda7442  (посылается 7бит адреса по I2C шине и еще один нолик)*/
/*после beginTransmission дуина ждёт по линии ДАТА ответа от tda7442 ( присаживание линии на землю во время 8 бита синхросигнала)и потом передает*/
Wire.write(subaddress);       //Подадрес команды 
Wire.write(data);             //Команда 
Wire.endTransmission();       //СТОП 
/* То есть когда есть связь с tda7442, то функция (void tda7442) посылает сначала первый пакет tda7442(0), потом данные этого пакета 0b01000000
   Потом функция (void tda7442) посылает  второй пакет tda7442(1), потом данные этого пакета 0b00000110
   и так до конца: tda7442(9, 0b00000110); */
}
/*конец void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//===========================================================================================================================================================================
//===========================================================================================================================================================================
//===========================================================================================================================================================================

void printDISPLAY(unsigned long interval){
  static 
unsigned long prevTime=0;
  if(
millis()-prevTime>interval){
    
prevTime=millis();
     
int Mdisp =map(MasterVolume, 0, 80, 80, 0);// переменная, зеркалим значение громкости, чтобы нормально выводить на дисплей(громче-больше)http://arduino.ua/ru/prog/Map
  
  
// lcd.setCursor(0, 0); не надо явно указывать, т.к. отсчет все равно с 0,0
lcd.printHorizontalGraph('v', 0, Mdisp, 80); //name of the bar, first  row, current value, max. value вывод полоски громкости в первой строке
 
  //-------------------2 строка---------------------------------
lcd.setCursor(0, 1); //2строка 0символ 
if (MasterVolume==80){ lcd.print("  MUTE  ");  } else  {lcd.print("VOLUME -");  }
lcd.print(MasterVolume);
lcd.print("dB ");

if (
13,1){digitalWrite(13,0);}

 
  }
}



//===========================================================================================================================================================================
//===========================================================================================================================================================================
//===========================================================================================================================================================================

void ENCODER (unsigned long interval){
  static 
unsigned long prevTime=0;
  if(
millis()-prevTime>interval){
    
prevTime=millis();
    
      static 
uint8_t oldValue = 0;
  
uint8_t grayValue = digitalRead(ENC_PIN1) | (digitalRead(ENC_PIN2) << 1), value = graydecode(grayValue);


  

  if (
stepENC >0)
  {
    if((
millis() - prevTimeE > 120 )  ) 
    {
      
      if (
stepENC>6){stepENC=6;}//НАДО ОбНУЛЯТЬРАЗ В 420
         
if((millis() - prevTimeE > 130 )  ) { prevTimeE = millis(); stepENC--; }
    }
  }

  if (
value == 0) // Энкодер вращается
      
{ 
         
     


    if (
oldValue == 3) { /*  вращение по часовой стрелке // увеличиваем громкость, не более чем до 80*/
                                                      
                                                        
if (MasterVolume == 80){stepENC = 1;} else {stepENC++;}    Serial.println(stepENC);
                                                        if( 
stepENC < 6 ) {stepVOLamount = 1;}
                                                        else  if( 
stepENC < 10 ) {stepVOLamount = 4;}
                                                        else  if( 
stepENC < 14 ) {stepVOLamount = 6;}
                                                        else  if( 
stepENC < 24 ) {stepVOLamount = 8;}
                                                        
prevTimeE = millis();
                                                        if(
MasterVolume + stepVOLamount <= 80) {(MasterVolume += stepVOLamount);}else {MasterVolume = 80;}
                                                        
                                                      
                       }
    else if (
oldValue == 1) { // Влево


                                                        
if (MasterVolume == 0){stepENC = 1;} else {stepENC++;}    Serial.println(stepENC);
                                                        if( 
stepENC < 3 ) {stepVOLamount = 1;}
                                                        else  if( 
stepENC < 6 ) {stepVOLamount = 4;}
                                                        else  if( 
stepENC < 12 ) {stepVOLamount = 6;}
                                                        else  if( 
stepENC < 18 ) {stepVOLamount = 10;}
                                                        
prevTimeE = millis();
                                                        if(
MasterVolume - stepVOLamount >= 0){ (MasterVolume -= stepVOLamount);} else{ MasterVolume = 0; /*Serial.println(MasterVolume);*/ }  /* уменьшаем громкость, но не ниже 0*/
                             
                            
}
      }
     
 

 
  
oldValue = value;

          

 
  }
}

//===========================================================================================================================================================================
//===========================================================================================================================================================================
//===========================================================================================================================================================================


 
void loop() //~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~

 
{ 
  
 
VOLUPbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки громкости 
VOLDNbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки громкости 
MUTEbutton.read();     // читаем фильтрованное значение СТАТУСА кнопки MUTE

                          /*               Примеры
                           REDbutton.read();      // читаем фильтрованное значение СТАТУСА кнопки
                           BLACKbutton.read();    // читаем фильтрованное значение СТАТУСА кнопки
                           if (REDbutton.click_down) {Serial.println("REDbutton = najata"); }             //нажатие кнопки  
                           if (REDbutton.click_up) {Serial.println("REDbutton = otpustily"); }            //отпускание кнопки 
                           if (REDbutton.doubleclick) {Serial.println("REDbutton = doubleclick"); }       //двойной клик 
                           if (REDbutton.timer) {Serial.println("REDbutton = neaktivnost knopki"); }      //неактивность 
                           if (REDbutton.retention) {Serial.println("REDbutton = uderjanie");}            // нажатие и удержание  
                           */


 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~обработка MUTE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
if (MasterVolume<80&&MuteActiv ==1){MuteActiv = 0;}
 if (
MUTEbutton.click_down)//если кнопка MUTE однократно нажата
        
{ 
        if (
MuteActiv == 0){MasterVolumeDoMUTE = MasterVolume;}
        
MuteActiv = (!MuteActiv); 
        if (
MuteActiv == 1){ MasterVolumeDoMUTE = MasterVolume; MasterVolume=80; }
        if (
MuteActiv==0 ) { MasterVolume = MasterVolumeDoMUTE; MuteActiv = 0; }
        
Serial.print("MuteActiv = " );Serial.print(MuteActiv);Serial.print("   MasterVolume = "); Serial.println(MasterVolume);
        }
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~конец обработки MUTE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


/*~~~~~~~~~~~~~~~~~~~~~~обработка нажатия кнопок громкости~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
if (VOLUPbutton.click_down) /*если кнопка VOL+ однократно нажата  то ДЕЛАЕМ ШАГ(1 РАЗ): включаем светик, уменьшаем переменную громкости (для увеличения звука)выводим значение громкости в порт.*/
        
{                                                       
           if (
MasterVolume==0){Serial.println ("I tak VOLUME MAX (0dB)"); } else (MasterVolume--);  Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); // выводим значение громкости в ком порт
           
digitalWrite(13,!digitalRead(13)); 
        }
  if (
VOLDNbutton.click_down) /*если кнопка VOL- однократно нажата то ДЕЛАЕМ ШАГ(1 РАЗ): увеличиваем переменную громкости (для уменьшения звука)выводим значение громкости в порт*/
        
{  
           if (
MasterVolume==80){Serial.println ("I tak VOLUME MIN (80dB-MUTE)");}  else (MasterVolume++);    Serial.print("MasterVolume = "); Serial.print(MasterVolume); Serial.println("dB"); // выводим значение громкости в ком порт
           
digitalWrite(13,!digitalRead(13)); 
        }
/*===================================================================================================================*/

/*~~~~~~~~~~~~~~~~~~~~~~обработка удержания кнопок громкости~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if (VOLUPbutton.retention==1){Vupupup = 1;}                  //если кнопка нажата  и удерживается //надо бы увеличивать громкость по шагам
if (VOLDNbutton.retention==1){Vdndndn = 1; }                 //если кнопка нажата  и удержмвается //надо бы уменьшать громкость по шагам
  
if (VOLUPbutton.click_up) { Vupupup = 0; USCORENIE = 0;}   //если отпустили кнопку, надо бы перестать увеличивать громкость по шагам
  
if (VOLDNbutton.click_up) { Vdndndn = 0; USCORENIE = 0;}       
VOLFAST(VOLUME_INTERVAL); //заходим в функцию VOLFAST, которая  ЕСЛИ удерживаются кнопки регулировки громкости, то увеличивает или уменьшает громкость на один шаг (1dB) с периодичностью VOLUME_INTERVAL.   
/*===================================================================================================================*/



/*для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
ENCODER(0); // опрос энкодера раз в 0 миллисекунду
/*конец для энкодера~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

     



/*конфигурация void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

tda7442(0, 0b01000000);  //INPUT ATTENUATION    приглушение ВХОДНОГО (IN1-IN4) канала (0 ~ -31.5dB)(0db-макс громкость, без приглушения)
tda7442(1, 0b00000110);  //SURROUND & OUT & EFFECT CONTROL( -6 FIX OFF)
tda7442(2, 0b00000011);  //SURROUND PHASE RESISTOR( 37KOm)
tda7442(3, 0b00011111);  //BXXX0011 BASS SELECTION (0dB)-14dB  (0b0001100 = 14dB; 0b00011000 + 0b00000001 = 0b00011001 (+12dB) 
tda7442(4, 0b01111110);  //BXXX0100 TREBLE (0dB)
//tda7442(5, 0b00000000);  //BXXX0101 SPEAKER ATTENUATION "L" (0dB)( SPEAKER SELECTION = 0dB ~ -79dB) громкость правого канала
//tda7442(6, 0b00000000);  //BXXX0110 SPEAKER ATTENUATION "R" (0dB) громкость левого канала
// регулировку громкости можно делать  0dB ~ -79dB в DEC c шагом 1. если (80-255) - то MUTE  
tda7442(5,  MasterVolume); //0 - макс громкость, 80-255 - MUTE .  
tda7442(6,  MasterVolume);
tda7442(7, 0b00000000);  //BXXX0111 NOT ALLOWED
tda7442(8, 0b00000000);  //BXXX1000 NOT ALLOWED         
tda7442(9, 6/*0b00000110*/);  //BXXX1001 INPUT MULTIPLEXER выбор источника IN1-4 (6-in1 4-in4  2-in3 0-in2)
/*конец конфигурации void tda7442~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/





 
  
  
  
  
 








printDISPLAY(100); // выводим на дисплей раз в 100( запуская фушкцию)






}//конец LOOP//~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~`~
//=====================================================================================================================================================================================================================================================
//__________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ 
oleg707 вне форума   Ответить с цитированием
Старый 25.10.2016, 07:33   #30
demtro
Старший Пользователь
 
Регистрация: 17.12.2014
Возраст: 35
Город: Самара
Регион: 63, 163
Машина: Lifan Solano
Сообщений: 184
demtro is on a distinguished road
По умолчанию

Как на счет микширования источников? Имеет ли смысл через tda7442 это делать? Или лучше их физически объединить через сумматор? Думаю просто на счет pcm2704+бт модуль+ радио
demtro вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.



Часовой пояс GMT +4, время: 18:32.


Работает на vBulletin® версия 3.8.4.
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Перевод: zCarot