Управление громкостью на Arduino

doc_bravn
Offline
Зарегистрирован: 26.08.2017

Доброго всем дня. 

В данный момент реализовано включение и выключение нагрузки по ИК сигналу с пульта. Вот код скетча:

/*********************************************************************
 *         Замена принятого кода ИК пульта Dune HD TV-102            *
 *              на коды управления телевизором SAMSUNG               *
*                             IR_change                              *
 *                        ИК приемник - PIN 2                        *
 *                           ИК диод - PIN 3                         *
 *                          Реле - PIN 5                             *
 *                              08.09.217г.                          *
 *********************************************************************/

#include <IRremote.h>

int RECV_PIN = 2;
int RELAY_PIN = 5;
unsigned long ON_OFF = 0xFDC23D; // Кнопка пульта Dune HD TV-102  включение
//Аналогично можно прописывать остальные кнопки пульта
IRrecv irrecv(RECV_PIN);
decode_results results;
IRsend irsend;

void setup()
{
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN,LOW);
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    if ( results.value != ON_OFF) {
      // Исключили из принятого ненужное, оставили только прописанные команды пульта
      delay(200);/*без этой строки неустойчивое управление,
       значение подбираем: чем больше значение - тем больше задержка,
       чем меньше значение - тем хуже управление, у меня от 100 до 200*/
      Serial.print("Not declared command - ");
      //irrecv.resume();
      //irrecv.enableIRIn();
    }

    if ( results.value==ON_OFF ) {
      delay(200);
      Serial.print("ON_OFF - ");
      irrecv.resume();
      irsend.sendSAMSUNG(0xE0E040BF, 32); // Передаем команду вкл/выкл
      digitalWrite(RELAY_PIN, !digitalRead(RELAY_PIN));
	  delay(100);
      //irrecv.resume();
      irrecv.enableIRIn();
    };

    Serial.println(results.value, HEX);
      irrecv.resume();
  }
  delay(40);
}

 

Потребовалось еще в этот скетч добавить регулировку громкости с помощью цифрового потенциометра X9C503P.

Коды кнопок пульта я считаю. Нужно настроить передачу команд на потенциометр. Не поможете встроить в код команды для управления громкостью?

sadman41
Онлайн
Зарегистрирован: 19.10.2016
doc_bravn
Offline
Зарегистрирован: 26.08.2017

Я нашел в интернетах такой вариант кода управления этим потенциометром. Главное его теперь в код моего скетча внедрить.

#include "IRLremote.h"
#include <DigiPotX9Cxxx.h>
#include <EEPROM.h>

int Direccion = 0;               //We declare a variable where we store the address of the memory that we will use. In this case 0.
int Countervol = 0;              // counter for the VOL

DigiPot pot(3, 4, 5);                     // potenciometer vol

const int interruptIR = 0;

uint8_t IRProtocol = 0;                   // Variables for recibe the IR
uint16_t IRAddress = 0;
uint32_t IRCommand = 0;

int  Ledrojo = 13;                        // Relay
int Ledamarillo = 12;                     // Relay
int Led = A5;                              //To see when push a buttom

void setup() {
  Serial.begin(115200);                   //Serial monitor
  IRLbegin<IR_ALL>(interruptIR);
  pinMode(Ledrojo, OUTPUT);              // Relay
  pinMode(Ledamarillo, OUTPUT);          // Relay
  Countervol = EEPROM.read(Direccion);   //Save vol in this direction
  Countersub = EEPROM.read(Direccion1);  //Save sub  in this direction
  Counterrear = EEPROM.read(Direccion2); //Save rear  in this direction
  pot.increase  (Countervol);            //To put the potenciometers with the values saved before turn off
  Serial.print("vol = ");
  Serial.println(Countervol);            //Saved vol befor turn off
}

void loop() {

  if (IRProtocol) {

    if (IRCommand == 0x40BF)                       //+ vol
    { pot.increase(5);                             //Increases 5 of 100 (you can put the value you want) the scale is from 0 to
      digitalWrite(Led, HIGH);
      delay(100);                                  //Time led on
      digitalWrite(Led, LOW);
      if (Countervol < 100) {                      //The potenciometer has 100 pushs to change the value
        Countervol += (5);                         //Increases 5 the counter if it is <100
        Serial.println("vol + ");
        Serial.println(Countervol);
        EEPROM.write(Direccion, Countervol);       //Save the value in the EEPROM  directión choosed
      }
    }


    if (IRCommand == 0xC03F)                         // - vol
    { pot.decrease(5);                              //decreases 5 of 100 (you can put the value you want) the scale is from 0 to
      digitalWrite(Led, HIGH);
      delay(100);                                   //Time led on
      digitalWrite(Led, LOW);
      if (Countervol > 0) {
        Countervol -= (5);                          //decreases 5 the counter if it is >0
        Serial.println("vol - ");
        Serial.println(Countervol);
        EEPROM.write(Direccion, Countervol);        //Save the value in the EEPROM  directión choosed

      }
    }

    
    IRProtocol = 0;
  }

}
void IREvent(uint8_t protocol, uint16_t address, uint32_t command)
{
  IRProtocol = protocol;                               // We collect values and we become
  IRAddress = address;
  IRCommand = command;
}

 

b707
Offline
Зарегистрирован: 26.05.2017

doc_bravn пишет:

Я нашел в интернетах такой вариант кода управления этим потенциометром. Главное его теперь в код моего скетча внедрить.

Это вы рано на форум пришли. Вы сначала попробуйте сами их соединить, и если будут вопросы - приходите со своим скетчем и спрашивайте.

andryn
Offline
Зарегистрирован: 08.06.2018

Так в чем проблема? Подключайте:

#include <DigiPotX9Cxxx.h>
 
Описываете:
DigiPot pot(3, 4, 5); 
 
Дальше в лупе при сигнале "+":
pot.increase(5)
При "-":
pot.decrease(5)
 
Если нужно сохранять и восстанавливать значения, используйте #include <EEPROM.h> и EEPROM.write, EEPROM.read.
 
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

doc_bravn пишет:
Потребовалось еще в этот скетч добавить регулировку громкости с помощью цифрового потенциометра X9C503P.
Плохая идея. Очень плохая. Он линейный и Вам придётся компенсировать это программно. Судя по Вашим вопросам - это для Вас трудно. Намучаетесь и хорошо всё равно не получится.

Возмите лучше более адекватную для этого микросхему. Например, M62429 - она специально для регулирования громкости.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

andryn пишет:

Если нужно сохранять и восстанавливать значения, используйте #include <EEPROM.h> и EEPROM.write, EEPROM.read.
 
Зачем? X9C503P и сама отлично умеет сохранять и восстанавливать при включении питания.
doc_bravn
Offline
Зарегистрирован: 26.08.2017

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

Можете подсказать какой код для управления M62429 нужно добавить в мой скетч и как он вообще управляется?

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

По двум проводам - часы и данные, см. даташит - http://nice.kaze.com/M62429.pdf

andryn
Offline
Зарегистрирован: 08.06.2018

ЕвгенийП пишет:

Возмите лучше более адекватную для этого микросхему. Например, M62429 - она специально для регулирования громкости.

Судя по описанию, M62429 не совсем адекватная замена X9C503P. M62429 - это двухканальный регулятор громкости, а автор хочет в уже имеющемся устройстве заменить обычный потенциометр на электронный.

Ну а для реализации логарифмической характеристики можно массив на 20 значений (если регулировать +-5 пунктов) сделать.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Не выйдет с резистором.
Объясню почему.
Телевизор, ну или колонка не знает таких команд как, поставить звук на определенный порог.
Он либо добавляет громкость на одну позицию, либо убавляет. В зависимости от того какая кнопка нажата.
Т.е. за место резистора использовать придется две кнопки.
И вроде бы можно программно реализовать, но вот только обратной связи у нас не будет , поэтому такую херь будет вытворять...

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Упс.
Потенциометром оказывается цифровой.
Тогда все получится :)

doc_bravn
Offline
Зарегистрирован: 26.08.2017

Kakmyc пишет:
Не выйдет с резистором. Объясню почему. Телевизор, ну или колонка не знает таких команд как, поставить звук на определенный порог. Он либо добавляет громкость на одну позицию, либо убавляет. В зависимости от того какая кнопка нажата. Т.е. за место резистора использовать придется две кнопки. И вроде бы можно программно реализовать, но вот только обратной связи у нас не будет , поэтому такую херь будет вытворять...

Телевизор или колонка не знают. Зато цифровой потенциометр знает. Он запоминает то показание громкости которое было на нем установлено. И если отключить, а затем включить его и колонки, то потенциометр устаноивт то показание которое у него было до выключения. 

Так в чем могут быть тогда проблемы и какую он будет вытворять херь? Расскажите поподробнее.

doc_bravn
Offline
Зарегистрирован: 26.08.2017

Посидел, покумекал. Вроде как модернизировал свой скетч в применении для регулировки громкости.

Посмотрите пожалуйста, знатоки, правильно ли получилось.

/*********************************************************************
 *         Замена принятого кода ИК пульта Dune HD TV-102            *
 *              на коды управления телевизором SAMSUNG               *
 *                             IR_change                             *
 *			+ управление громкостью колонок с помощью X9Cxxx         *
 *                        ИК приемник - PIN 2                        *
 *                           ИК диод - PIN 13                        *
 *                          Реле - PIN 8 							 *
 *						X9Cxxx INC - PIN 3							 *
 *						X9Cxxx U/D - PIN 4							 *
 *						X9Cxxx CS - PIN 5							 *
 *                              20.06.2018г.                         *
 *********************************************************************/

#include <IRremote.h>
#include <DigiPotX9Cxxx.h>
#include <EEPROM.h>

int Direccion = 0;               //We declare a variable where we store the address of the memory that we will use. In this case 0.
int Countervol = 0;              // counter for the VOL

DigiPot pot(3, 4, 5);                     // potenciometer vol

int RECV_PIN = 2;
int RELAY_PIN = 8;
unsigned long ON_OFF = 0xFDC23D; // Кнопка пульта Dune HD TV-102  включение
unsigned long VOL_UP = 0x...; // Кнопка пульта Dune HD TV-102  VOL+
unsigned long VOL_DN = 0x...; // Кнопка пульта Dune HD TV-102  VOL-
//Аналогично можно прописывать остальные кнопки пульта
IRrecv irrecv(RECV_PIN);
decode_results results;
IRsend irsend;

void setup()
{
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN,LOW);
  Serial.begin(115200);
  irrecv.enableIRIn(); // Start the receiver
  Countervol = EEPROM.read(Direccion);   //Save vol in this direction
  pot.increase  (Countervol);            //To put the potenciometers with the values saved before turn off
  Serial.print("VOL = ");
  Serial.println(Countervol);            //Saved vol befor turn off
}

void loop() {
  if (irrecv.decode(&results)) {
    if ( results.value != ON_OFF && results.value != VOL_UP && results.value != VOL_DN) {
      // Исключили из принятого ненужное, оставили только прописанные команды пульта
      delay(200);/*без этой строки неустойчивое управление,
       значение подбираем: чем больше значение - тем больше задержка,
       чем меньше значение - тем хуже управление, у меня от 100 до 200*/
      Serial.print("Not declared command - ");
      
    }

    if ( results.value == ON_OFF ) {
      delay(200);
      Serial.print("ON_OFF - ");
      irrecv.resume();
      irsend.sendSAMSUNG(0xE0E040BF, 32); // Передаем команду вкл/выкл
      digitalWrite(RELAY_PIN, !digitalRead(RELAY_PIN));
	  delay(100);
      irrecv.enableIRIn();
    };
	
    if ( results.value == VOL_UP ) {
      delay(200);
      pot.increase(5);                             //Increases 5 of 100 (you can put the value you want) the scale is from 0 to
      if (Countervol < 100) {                      //The potenciometer has 100 pushs to change the value
      Countervol += (5);                         //Increases 5 the counter if it is <100
      Serial.println("VOL + ");
      Serial.println(Countervol);
      EEPROM.write(Direccion, Countervol);       //Save the value in the EEPROM  directión choosed
      delay(100);
      irrecv.enableIRIn();
    };
     
    if ( results.value == VOL_DN ) {
      delay(200);
      pot.decrease(5);                              //decreases 5 of 100 (you can put the value you want) the scale is from 0 to
      if (Countervol > 0) {
      Countervol -= (5);                          //decreases 5 the counter if it is >0
      Serial.println("VOL - ");
      Serial.println(Countervol);
      EEPROM.write(Direccion, Countervol);        //Save the value in the EEPROM  directión choosed
      delay(100);
      irrecv.enableIRIn();
    };
	
    Serial.println(results.value, HEX);
      irrecv.resume();
  }
  delay(40);
}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Мне вот интересно - кто-то серьёзно эти поты гонял? На сколько записей им хватает епрома внутреннего?

Кстати, рекомендую сэйв значения делать через какое-то время после окончания регулировки, так как процесс записи в еепром идет дольше, чем процесс выставления значения на ногах.

andryn
Offline
Зарегистрирован: 08.06.2018

doc_bravn пишет:

Посмотрите пожалуйста, знатоки, правильно ли получилось.

В общих чертах правильно, однако выше ЕвгенийП замечал, что X9Cxxx вроде бы сохраняет последнее значение при отключении питания. Уточните в документации, тогда всякие EEPROM.write не нужны. Даже если нужны, то писать туда каждый раз при нажатии кнопки не лучшая идея.

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

 

doc_bravn
Offline
Зарегистрирован: 26.08.2017

andryn пишет:

doc_bravn пишет:

Посмотрите пожалуйста, знатоки, правильно ли получилось.

В общих чертах правильно, однако выше ЕвгенийП замечал, что X9Cxxx вроде бы сохраняет последнее значение при отключении питания. Уточните в документации, тогда всякие EEPROM.write не нужны. Даже если нужны, то писать туда каждый раз при нажатии кнопки не лучшая идея.

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

 

Да, сохранять значение этот потенциометр может, но при подаче команды на один из своих выводов. Разберусь по даташиту и заменю запись в EEPROM на эту команду. 

Если подскажете как внести изменение для логарифмической регулировки буду премного благодарен.

P.S. У меня идет изменение громкости в скетче не на 1 единицу, а сразу на 5. Это тоже линейное изменение получается? 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

andryn пишет:
ЕвгенийП замечал, что X9Cxxx вроде бы сохраняет последнее значение при отключении питания.
Не сам, ему надо команду давать. Там точно не помню, в даташите написано. Типа один пин держать HIGH, а другой при этом скинуть на LOW, по нисходящему фронту значение и сохранится (или наоборот). В общем, несложно, но делать это надо явно - само не сделается.

Кстати, про его линейность. Там собственно какое сопртивление нужно? А то если параллельно ему поставить обычный резистор, линейности как рукой снимет :))))

doc_bravn
Offline
Зарегистрирован: 26.08.2017

ЕвгенийП пишет:

andryn пишет:
ЕвгенийП замечал, что X9Cxxx вроде бы сохраняет последнее значение при отключении питания.
Не сам, ему надо команду давать. Там точно не помню, в даташите написано. Типа один пин держать HIGH, а другой при этом скинуть на LOW, по нисходящему фронту значение и сохранится (или наоборот). В общем, несложно, но делать это надо явно - само не сделается.

Кстати, про его линейность. Там собственно какое сопртивление нужно? А то если параллельно ему поставить обычный резистор, линейности как рукой снимет :))))

Описание как запоминать состояние громкости вроде нашел. Модернизирую скетч с его учетом. 

Сопротивление аналогового потенциометра у меня в колонках 50 Ком.

andryn
Offline
Зарегистрирован: 08.06.2018

doc_bravn пишет:

Если подскажете как внести изменение для логарифмической регулировки буду премного благодарен.

Сначала нужно посмотреть какой тип потенциометра установлен. Тут про типы неплохо написано: http://guitar-gear.ru/2016/pots/

Теоретически может быть любой, но скорее всего тип A(обратная логарифмическая зависимость). 

Алгоритмически можно завести массив констант из 20ти значений(от 0 до 100 с нужной зависимостью), соответствующих двадцати уровням громкости и переменную, в которой хранится текущий индекс установленной громкости. При изменении громкости меняем текущий индекс(+1 или -1), выбираем из массива соответствующий этому индексу уровень и делаем pot.set(значение из массива).

 

vitos08
Offline
Зарегистрирован: 25.12.2018

доброго времени суток 

интересно получилось ли реализовать проект