Управление аналоговым ТБ с помощью Arduino

Тема в разделе "Arduino & Shields", создана пользователем Salk, 3 окт 2014.

?

Реализуема ли моя идея, с цифровым управлением 3-х канальной аудио-системы

Голосование закрыто 16 окт 2014.
  1. Да, ничего сложного в этом нет

    100,0%
  2. Нет, проще собрать на готовых аудио процессорах с функциями ТБ (TDA8425, TDA7318, TDA7439 и т.д)

    0 голосов
    0,0%
  1. Salk

    Salk Гик

    Всем доброго времени суток. Суть - собрал трехканальную (2.1) акустику. Усилители и к ним аналоговый темброблок, хороший (даже очень, на ОУ TL072 и TL074), все как положено, играет круто :)
    А теперь решил это дело осовременить, оцифровать так сказать. Цель - добиться цифровой регулировки темброблоком, т.е. с дистанционного пульта (ИК) управлять всеми "крутилками" ТБ: громкость стерео, ВЧ, НЧ, громкость сабвуферного канала (ну и может дисплей двухстрочный для красоты :) ). Для достижения этой цели, я так понял, на помощь мне придет "цифровые потенциометры", ну к примеру "AD8403". Но встал вопрос, как подружить Arduino и цифровой потенциометр, прошу помочь мне со скетчем, если есть подобные проекты, направьте. Заранее огромное спасибо.
    Имеется в наличии Arduino Uno и желание, разумеется :)
     
  2. acos

    acos Официальный гик Администратор

    Ну вроде можно сделать на этом "цифровом потенциометре". Правда не понятно, как совместить одновременное управление и ручками и им. Хотя не - можно, если положение ручек сама Arduino будет оцифровывать) С помощью этого http://arduino.cc/en/tutorial/ShiftOut можно передать сигнала на микросхему. Ну или лучше с помощью этого http://arduino.cc/en/Reference/SPI
    Посмотреть можно вот что http://wiki.amperka.ru/видеоуроки:8-интерфейсы-spi
    это про сам интерфейс SPI, которым управляется потенциометр
     
  3. Salk

    Salk Гик

    Большое спасибо, да это то что мне нужно. На видео уроках Джереми довольно неплохо все рассказано и даже показано. Если правильно понимаю, библиотека #include <SPI.h> уже есть изначально в базовой программе Arduino, т.е. дополнительно ничего скачивать не нужно. В дальнейшем я могу обращаться сюда же, если что-то у меня не будет получаться?
     
  4. vvr

    vvr Инженерище

    Форум для того и есть, чтобы общаться и помогать. Только не забудь код показать и грамотно объяснить проблему.
     
  5. Salk

    Salk Гик

    Так, только найти у себя в городе хотя бы четырехканальный потенциометр не удалось. Есть только одноканальные - "AD8400" . Такие подойдут? У Джерими AD5204 серия. А мне нужно управлять, хотя бы тремя регулировками. Получается каждый потенциометр нужно подключать отдельно к Arduino. Т.е. применив 3 отдельных одноканальных потенциометра нужно уже использовать 9 пинов Arduino, вместо 3? Для подключения CS, SDI, CLK. Или их можно объединить?
    [​IMG]

    [​IMG]
    [​IMG]
    http://lib.chipdip.ru/143/DOC000143845.pdf
     
    Последнее редактирование: 4 окт 2014
  6. acos

    acos Официальный гик Администратор

    У AD8400 выхода SDO похоже нет, т.е. их нельзя каскадировать. Похоже, придётся использовать 9 пинов и передавать данные не через библиотеку SPI, а через ShiftOut(). Если пинов хватает, то можно смело и 12 пинов использовать, и 4 микросхемы. Пины 2 - 13 на потенциометры, на аналоговые пины повесить 4 потенциометра и ими регулировать значения на цифровые потенциометры. На оставшиеся ноги повешать ик-приёмник и ещё чего-нибудь. Но а вдруг захочется чего-то ещё? Например, на два оставшихся аналоговых входа захочется повесить непосредственно стерео-выход с усилителя, и на сдвиговых регистрах зашабашить ещё UV-метр какой? В таком случае ног уже не хватит. Можно просто заказать где-то в интернет-магазине радиодеталей нужную микросхему на 4 выхода, или хотя бы каскадируемые микросхемы.
     
    Salk нравится это.
  7. acos

    acos Официальный гик Администратор

    Можно, конечно, существенно сэкономить выводы - например, подключить все CLK на одну ножку, и все CS на другую ножку, учесть это в скетче и обновлять все потенциометры одновременно (даже если значения не изменились). В таком случае четыре потенциометра можно подключить на 6 пинов.
     
  8. Salk

    Salk Гик

    Да, но тогда же получится параллельное подключение и Arduino будет управлять всеми тремя потенциометрами, что не есть ГУД. Как я понял в счетверенном потенциометре есть, как раз этот вывод - SDO, как вы сказали, он служит для переключения между этими потенциометрами внутри корпуса, т.е. все настройки (громкость/НЧ/ВЧ) настраиваются отдельно и имеют разные значения сопротивления и т.д. Мне это и нужно.
    Я на днях, только, смогу купить эти AD8400 и буду с ними "играться" :) о результатах писать тут. ;)
     
  9. acos

    acos Официальный гик Администратор

    Суть: вы выставляете необходимое значение в буфер куда-то. Когда вам нужно изменить громкость одного канала, вы изменяете громкость всех четырех. Но в те потенциометры, которые изменять не нужно, вы просто записываете старое значение. Поэтому в итоге меняется громкость только одного.
     
  10. Salk

    Salk Гик

    Хм... :) На AD8400 сделал заказ, приедет через пару дней пообещали. Тут наткнулся на ещё один "способ регулировать ТБ": "Электронный регулятор громкости на полевом транзисторе":
    [​IMG]
    Качество, конечно, НАМНОГО хуже "специализированных" микросхем, но может сойти?? :))


    Ключи на "понижение и повышение" заменить транзисторами PNP, а на базы их подавать, как раз сигналы с Arduino (HIGH, LOW), вроде просто :) Такую же схему применить и на регулировку НЧ и ВЧ.
    Даете добро? :D Я пока слабо разбираюсь в программировании, точнее на 0.00001% :), но у меня есть скетч на управление реле ИК-приемником:
    http://student-proger.ru/2013/03/arduino-upravlenie-svetom-s-pulta-distancionnogo-upravleniya/
    Там заменить коды кнопок пульта (разумеется) и используемые пины и вместо реле подставить транзисторы (вместо кнопок), и те же сигналы (HIGH; LOW) будут управлять полевиком, т.е. громкостью/ВЧ/НЧ. Вроде бы ничего не упустил. :)
     
    Последнее редактирование: 8 окт 2014
  11. acos

    acos Официальный гик Администратор

    Если честно - мне не нравится) Но для саморазвития - обязательно попробуйте!
     
  12. Salk

    Salk Гик

    Доброе время суток :) Простите, за задержку. Наконец-то удалось приобрести мне цифровой потенциометр, но не просто потенциометр, а двуканальный (AD8402), чем я конечно безумно рад! ;)Схемку с полевиком проверить пока не получилось, но транзистор КП501 приобрел, хотя в интернете эту схемку не особо жалуют, мол большие искажения вносит в звук. Ну что ж, эту забаву я оставлю на потом, хотя по той схеме, мне тоже нужна будет консультация по прошивке (скетчу), т.к. на базу транзистора нужно подавать управляющий сигнал импульсами, а не просто держать его ВСЕГДА закрытым или открытым (LOW; HIGH), иначе громкость будет всегда либо уменьшаться, либо увеличиваться, и о никакой фиксации на определенном уровне речи не пойдет. Ну ладно, оставим это на потом, вернемся к AD8402, не зря же я его покупал. Как смог я разобрался с распиновкой этой микросхемы, она немного отличается от "AD5204", которой использовал Джереми в своих уроках. Вот набросал схемку:
    [​IMG]
    http://www.promelec.ru/pdf/ad8400_2_3_c.pdf
    Т.к. у меня стерео система, а потенциометр удалось купить только двуканальный, поэтому давайте пока попробуем управлять только громкостью.
    Отсутствует "SDO" (PIN12 у Джереми), но он его все равно не использует. Так же не много не понял насчет разделения земель (AGnd и DGnd). Т.е. AGnd (Analog) подключаем к источнику звука? (земля темброблока и т.д.), а DGnd (Digital Ground - цифровая земля) к Arduino? В квадрате, как подключается обычный потенциометр. А теперь самое важное - скетч! В принципе скетч Джереми можно использовать, который он написал для изменения яркости свечения светодиодов, но тогда у меня будет громкость так же "светить" :rolleyes: Вот его код:
    Код (Text):
    //Program by Jeremy Blum
    //www.jeremyblum.com
    //Changes LED brightness using voltag input instead of PWM

    //Include SPI library
    #include <SPI.h>

    //When Using the SPI library, you only have to worry
    //about picking your slave select
    //By Default, 11 = MOSI, 12 = MISO, 13 = CLK
    int SS_PIN = 10;  //SPI Slave Select

    void setup()
    {

      //Set Pin Direction
      //Again, the other SPI pins are configured automatically
      pinMode(SS, OUTPUT);

      //Initialize SPI
      SPI.begin();

    }

    //This will set 1 LED to the specififed level
    void setLed(int reg, int level)
    {
      digitalWrite(SS, LOW);
      SPI.transfer(reg);
      SPI.transfer(level);
      digitalWrite(SS, HIGH);
    }

    void loop()
    {
      for(int i=0; i<=2; i++)
      {
        for (int j=50; j<=255; j++)
        {
          setLed(i,j);
          delay(20);
        }
        delay(500);
        for (int j=255; j>=50; j--)
        {
          setLed(i,j);
          delay(20);
        }
      }
    }
    Т.к. я хочу управлять этим всем с пульта ДУ, то мне понадобится соответствующий скетч, вот что я нашел:
    Код (Text):
    #include <IRremote.h>
    int RECV_PIN = 3; //пин подключения IR приёмника
    int RELAY_PIN = 7; //пин подключения реле
    int RELAY_PIN2 = 10; //пин подключения реле 2
    IRrecv irrecv(RECV_PIN);
    decode_results results;
    bool LampState = false;
    bool LampState2 = false;
    void setup()
    {
      pinMode(RELAY_PIN,OUTPUT);
      pinMode(RELAY_PIN2,OUTPUT);
      digitalWrite(RELAY_PIN,HIGH);
      digitalWrite(RELAY_PIN2,HIGH);
      irrecv.enableIRIn(); // Включаем ресивер
    }
    void loop()
    {
      if (irrecv.decode(&results))
      {
          if (results.value == 573503) //Код кнопки
          {
              LampState = !LampState;
              if (LampState)
              {
                  digitalWrite(RELAY_PIN,LOW);
              }
              else
              {
                  digitalWrite(RELAY_PIN,HIGH);
              }
          }

    if (results.value == 532703) //Код 2 кнопки

          {
              LampState2 = !LampState2;
              if (LampState2)
              {
                  digitalWrite(RELAY_PIN2,LOW);
              }
              else
              {
                  digitalWrite(RELAY_PIN2,HIGH);
              }
          }

        irrecv.resume(); // Получаем следующее значение
      }
    }
    Отлично, этот скетч рабочий, я с помощью него управляю реле, т.е. худо бедно обращаться с ИК-приемником научился. Теперь нужно эти два скетча объединить. Я попытался и начал :D Вот:


    Код (Text):
    //Program by Jeremy Blum
    //www.jeremyblum.com
    //Changes LED brightness using voltag input instead of PWM

    //Include SPI library
    #include <SPI.h>
    #include <IRremote.h>

    //When Using the SPI library, you only have to worry
    //about picking your slave select
    //By Default, 11 = MOSI, 12 = MISO, 13 = CLK
    int SS_PIN = 10;  //SPI Slave Select
    int RECV_PIN = 3; //пин подключения IR приёмника

    IRrecv irrecv(RECV_PIN);
    decode_results results;
    bool LampState = false;

    void setup()

    {
      irrecv.enableIRIn(); // Включаем ресивер
    }

    {
      //Set Pin Direction
      //Again, the other SPI pins are configured automatically
      pinMode(SS, OUTPUT);

      //Initialize SPI
      SPI.begin();
    }

    //This will set 1 LED to the specififed level
    void setLed(int reg, int level)
    {
      digitalWrite(SS, LOW);
      SPI.transfer(reg);
      SPI.transfer(level);
      digitalWrite(SS, HIGH);
    }

    void loop()

      if (irrecv.decode(&results))
      {
          if (results.value == 573503) //Код кнопки
       
           
    }
     
    Скетч не дописан, т.к. я не знаю, что писать в LOOP. Что я сделал: я подключил библиотеку "#include <IRremote.h>", добавил пин подключения ИК-приемника, по сути все. Дальше тупик. Очень прошу помочь со скетчем и проверить подключение этого AD8402, подключал по аналогии, как Джереми AD5204, только SDO нет, RS пин (на AD8402), это тоже самое, что PR (на AD5204) - Active low preset to midscale; sets RDAC registers to 80H, его на + питания. Ох, надеюсь ничего не упустил и надеюсь на помощь. СПАСИБО.
     
  13. acos

    acos Официальный гик Администратор

    с AGND и DGND своя магия. По сути да, AGND на усилители, DGND на Arduino. Но тут такой момент: AGND и DGND будут где-то связаны между собой. Обычно рекомендуют их связывать только в одной точке - как можно ближе к источнику питания. Arduino же у вас будет точно так же питаться от блока питания усилителя.

    Это наверное должно быть в блоке setup()
    Код (C):
    {
      //Set Pin Direction
      //Again, the other SPI pins are configured automatically
      pinMode(SS, OUTPUT);

      //Initialize SPI
      SPI.begin();
    }
    Вам нужна переменная, в которой будет хранится текущая громкость. По ir вам нужно её инкрементировать и декрементировать. И проверять её - если она изменилась - записываем её значение в АЦП
     
  14. Salk

    Salk Гик

    Да Вы правы насчет Void Setup (). Но не понял насчет переменной. Так как MISO (SDO) у меня нет, хотя странно, как я понял он служит для отправки данных от ведомого к ведущему, т.е. от потенциометра к Arduino. Получится ли собрать на этом AD8402 регулятор громкости, ещё вопрос, т.к. как я буду считывать текущие значения с потенциометра? Управлять им, да буду, но вот синхронизировать не получится или я не правильно понимаю?
    Давайте хотя бы научимся им управлять, т.е. посылать команды на потенциометр с пульта ДУ. Как правильно составить скетч?

    Код (Text):
    //Program by Jeremy Blum
    //www.jeremyblum.com
    //Changes LED brightness using voltag input instead of PWM

    //Include SPI library
    #include <SPI.h>
    #include <IRremote.h>

    //When Using the SPI library, you only have to worry
    //about picking your slave select
    //By Default, 11 = MOSI, 12 = MISO, 13 = CLK
    int SS_PIN = 10;  //SPI Slave Select
    int RECV_PIN = 3; //пин подключения IR приёмника

    IRrecv irrecv(RECV_PIN);
    decode_results results;
    bool LampState = false;
    bool LampState2 = false;

    void setup()

    {
      //Set Pin Direction
      //Again, the other SPI pins are configured automatically
      pinMode(SS, OUTPUT);

      //Initialize SPI
      SPI.begin();
      irrecv.enableIRIn(); // Включаем ресивер
     
      int value = digitalRead(10);
    }

    //This will set 1 LED to the specififed level
    void setLed(int reg, int level)

    {
      digitalWrite(SS, LOW);
      SPI.transfer(reg);
      SPI.transfer(level);
      digitalWrite(SS, HIGH);
    }

    void loop()
    {
        if (irrecv.decode(&results))
      {
          if (results.value == 573503) //Код кнопки + громкость
              {
              LampState = !LampState;
              if (LampState)
              {
                  ???
                  }
              }
        if (results.value == 532703) //Код 2 кнопки - громкость
              {
              LampState2 = !LampState2;
              if (LampState2)
              {
                  ???
              }
          }

    irrecv.resume(); // Получаем следующее значение
      }
    }
    Необходимо при нажатии кнопки пульта отдать сигнал на потенциометр, чтобы он сработал и изменил своё сопротивление.
     
  15. Salk

    Salk Гик

    Ладно, это сложновато наверное. Можете скинуть литературы, что "курить", чтобы самому хоть что-то более менее разбираться?
    А сейчас поможете со скетчем для той схемы на полевике, поэкспериментирую.
    Суть - нажимаю на кнопку пульта, на затвор полевика (PIN) подается сигнал HIGH, но он должен быстро перейти в LOW, после того, как я отпущу эту кнопку, тем самым я буду регулировать громкостью, как на телевизоре и т.д. Как базовый скетч можно использовать:

    Код (Text):
    #include <IRremote.h>
    int RECV_PIN = 3; //пин подключения IR приёмника
    int RELAY_PIN = 7; //пин подключения реле
    int RELAY_PIN2 = 10; //пин подключения реле 2
    IRrecv irrecv(RECV_PIN);
    decode_results results;
    bool LampState = false;
    bool LampState2 = false;

    void setup()
    {
      pinMode(RELAY_PIN,OUTPUT);
      pinMode(RELAY_PIN2,OUTPUT);
      digitalWrite(RELAY_PIN,HIGH);
      digitalWrite(RELAY_PIN2,HIGH);
      irrecv.enableIRIn(); // Включаем ресивер
    }
    void loop()
    {
      if (irrecv.decode(&results))
      {
          if (results.value == 573503) //Код кнопки
          {
              LampState = !LampState;
              if (LampState)
              {
                  digitalWrite(RELAY_PIN,LOW);
              }
              else
              {
                  digitalWrite(RELAY_PIN,HIGH);
              }
          }

    if (results.value == 532703) //Код 2 кнопки

          {
              LampState2 = !LampState2;
              if (LampState2)
              {
                  digitalWrite(RELAY_PIN2,LOW);
              }
              else
              {
                  digitalWrite(RELAY_PIN2,HIGH);
              }
          }

        irrecv.resume(); // Получаем следующее значение
      }
    }
    Пины реле будут управляющими транзисторами (кнопками). Но в данном скетче будет всегда либо HIGH, либо LOW, а нужно чтобы был HIGH уровень только на время нажатой кнопки.
     
    Последнее редактирование: 10 окт 2014
  16. acos

    acos Официальный гик Администратор

    да не, даже с полевиком идеология другая должна бы быть) На самом деле, я бы на вашем месте просто попробовал бы кучу разных вариантов и набил бы шишек. чтобы потом разобраться почему все не работает и понять, как же должно быть. Это очень приятно, решать загадки:)
    Ну это лирика. На самом деле ничего сложного нет. Открываем ваш же даташит (спасибо что предоставили, не пришлось самому гуглить - ценю) на странице 5. Там видим форму посылки. Значит у нас в микросхему передается 10 бит : А1, А0, D7, D6, D5, D4, D3, D2, D0. Судя по всему, A0 и А1 это выбор канала, D7-D0 это собственно сопротивление, от 0 до 255 (8 бит). Мы хотим иметь одинкаовую громкость на двух каналах - мы же не баланс делаем, а тупо громкость. На странице 15 написано (да и интуитивно понятно, если прикинуть в двоичном виде) как выбирать канал. если А0 = 0 и А 1 = 0, то мы передаем значение в канал 1, если А0 = 1, а А1 = 0, то канал 2. Остальные варианты - для более толстых микросхем)
    Значит так. Допустим у нас регулятор громкости сидит на канале А0 ардуино.
    Тогда скетч какой-то такой:
    Код (C):
    #define CS 10
    #define SCK 11
    #define MOSI 12
    int volume; // тут хранится громкость
    void setup()
    {
    //лень писать библиотеки SPI и тд. Пусть будет полностью ручное управление
    //Я ситаю, что CS подключен к 10 ноге,
    //sck к 11-й
    //MOSI к 12-й. Ну просто потому что мне лень
    for (int i=10; i<13; ++i)
      pinMode(i, OUTPUT);

    digitalWrite(CS, HIGH); // в таком виде данные не передаются
    }

    void loop()
    {
      int pot = analogRead(A0); // считаем значение с потенциометра
      volume = map(pot, 0, 1023, 0, 255); // смасштабируем из 10-битного значения AnalogRead в 8-битное
     
      send(volume); // пошлем первый канал

      setBit(volume, 9); // переключим на второй канал
      send(volume); // пошлём второй канал
     
    }

    void send(int data)
    {
      digitalWrite(CS, LOW);
      for (int i=0; i < 10; ++i)
      {
        digitalWrite(SCK, HIGH);
        digitalWrite(MOSI, bitRead(data, i));
        digitalWrite(SCK, LOW);
      }
    digitalWrite(CS, HIGH);
    delay(10); // на всякий пожарный - было там что-то в даташите про задержку, не стал глубоко копать
    }
    Придумывать корректный и правильно работающий код за вас мне лень, особенно в пятницу) Тот что выше - не проверял, но надеюсь он донесет до вас смысл о связи даташиты и того, что происходит с пинами на самом деле. Он вполне работоспособен как идея. Библиотека SPI по сути делает то же самое, только не программно, а отдельным устройством - SPI - периферией. Короче говоря - должно работать. Прикрутить к этому IR труда составить не должно. Если заработает,, конечно)
     
    Salk нравится это.
  17. Salk

    Salk Гик

    Добрый день. Спасибо за ответ и что возитесь со мной, но пока доходит туго :) Поигрался я с AD8402 :) со скетчем Джереми, немного понял его механику, он использовал регистры (reg, мы их тоже можем использовать для управления громкостью? Как я понял каждый регистр соответствует кол-ву используемых потенциометров (reg 0,1,2,3, если это четырех канальный потенциометр, если двух - reg 0,1, reg присваивается =" i", i=0; i<=1, а значение i++ просто гоняет эти два потенциометра по кругу, тем самым то гаснут или загораются светодиоды, хотя level - уровень, который мы хотим присвоить каждому потенциометру (светодиоду от 0-255) можно присвоить отдельно для каждого reg. Тут ещё более менее что-то отложилось :) После каждого бита информации он устанавливает HIGH на SS, т.е. данные перестают передаваться:
    Код (Text):
    {
      digitalWrite(SS, LOW);
      SPI.transfer(reg);
      SPI.transfer(level);
      digitalWrite(SS, HIGH);
    }
    Вот, что получилось на практике, пару фоток:
    [​IMG]
    [​IMG]
    [​IMG]
    Жалко, что у Вас нет , фотографии большими получаются :)
    Пришлось делать не большую платку, т.к. корпус SOIC, DIP не было. Все работает. CS, MOSI, CLK подключил по умолчанию, как указано в SPI.h библиотеке (MOSI=11, CLK=13, SS = 10). AGND соединил с DGND и на общую землю :) Но меня тут смутило, что не удалось напряжение понизить до 0, поэтому светодиоды горят всегда, но видно когда они загораются ярче (когда напряжение максимум). На фото видно, что регулировка напряжения только от 2.18 В до 4.24 В, хотя может виной то, что у меня потенциометр на 1 кОм, а не на 10 или 50 кОм. Фуф. После взялся за ваш код, подставил все необходимое: подключил библиотеку, Вы изменили пины на 10, 11, 12, это выполняет функция:
    Код (Text):
    #define MOSI 12
    ?
    Так же я никак не могу понять, что Вы имели ввиду:
    ?
    Как я понял по шине MISO (SDO), должна передаваться информация от ведомого к ведущему (т.е. от потенциометра к Arduino), но у меня нет этого пина или это не проблема? Схему подключения моего потенциометра я приводил, ну ещё покажу :)
    [​IMG]
    Когда я вроде бы все подставил, вот получившийся код:

    Код (Text):
    //Program by Jeremy Blum
    //www.jeremyblum.com
    //Changes LED brightness using voltag input instead of PWM

    //Include SPI library
    #include <SPI.h>
    #define CS 10
    #define SCK 11
    #define MOSI 12

    int volume; // тут хранится громкость

    void setup()
    {
    for (int i=10; i<13; ++i)
    pinMode(i, OUTPUT);
    //When Using the SPI library, you only have to worry
    //about picking your slave select
    //11 = CLK, 12 = MOSI, 13 = SS
    digitalWrite(CS, HIGH); // в таком виде данные не передаются
    }

    void loop()

    {
      int pot = analogRead(A0); // считаем значение с потенциометра
      volume = map(pot, 0, 1023, 0, 255); // смасштабируем из 10-битного значения AnalogRead в 8-битное
      send(volume); // пошлем первый канал

      setBit(volume, 9); // переключим на второй канал
      send(volume); // пошлём второй канал
    }

    void send(int data)
    {
      digitalWrite(CS, LOW);
      for (int i=0; i < 10; ++i)
      {
        digitalWrite(SCK, HIGH);
        digitalWrite(MOSI, bitRead(data, i));
        digitalWrite(SCK, LOW);
      }
     
    digitalWrite(CS, HIGH);
    delay(10); // на всякий пожарный - было там что-то в даташите про задержку, не стал глубоко копать
    }
    Я получил ошибку при компилировании:
    Test_SPI.ino: In function 'void loop()':
    Test_SPI:31: error: 'setBit' was not declared in this scope

    Ругается на "setBit(volume, 9); // переключим на второй канал".

    Как я понял по вашей задумке, синхронно оба канала должны повышать напряжение на 1 за один такт,
    т.к. i = volume, при том всегда по циклу.

    Код (Text):
    void send(int data)
    {
      digitalWrite(CS, LOW);
      for (int i=0; i < 10; ++i)
      {
        digitalWrite(SCK, HIGH);
        digitalWrite(MOSI, bitRead(data, i));
        digitalWrite(SCK, LOW);
      }
    Вы уж простите меня за мою глупость.
     
  18. acos

    acos Официальный гик Администратор

    На счёт потенциометра, я имел ввиду обычный потенциометр. Ладно, давайте про него забудем и будем делать всё по-порядку.
    Функция setBit не работает потому, что на самом деле она называется bitSet. Извините, не проверил скетч http://arduino.cc/en/Reference/bitSet

    #define это не функция, а макроопределение http://wiki.amperka.ru/программирование:константы-переменные-арифметика

    заодно
    http://wiki.amperka.ru/программирование:языки-программирования
    http://wiki.amperka.ru/программирование:структура-программы-для-arduino
    http://wiki.amperka.ru/программирование:логические-переменные-ветвление
    http://wiki.amperka.ru/программирование:конечный-автомат



    Ну а по сути код должен быть таким тогда
    Код (C):
    //Program by Jeremy Blum
    //www.jeremyblum.com
    //Changes LED brightness using voltag input instead of PWM

    //Include SPI library
    #include <SPI.h>
    #include <IRremote.h>

    #define START_VOLUME 20; //стартовое значение громкости
    #define VOLUME_STEP 5; //шаг приращения громкости


    //When Using the SPI library, you only have to worry
    //about picking your slave select
    //By Default, 11 = MOSI, 12 = MISO, 13 = CLK
    int SS_pin = 10;  //SPI Slave Select

    int RECV_PIN = 3; //пин подключения IR приёмника
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    byte volume = START_VOLUME;
    byte volumeOld = 0;

    void setup()
    {

      //Set Pin Direction
      //Again, the other SPI pins are configured automatically
      pinMode(SS_pin, OUTPUT);

      //Initialize SPI
      SPI.begin();

    }

    //This will set 1 LED to the specififed level
    void setVolume(int reg, int level)
    {
      digitalWrite(SS_pin, LOW);
      SPI.transfer(reg);
      SPI.transfer(level);
      digitalWrite(SS_pin, HIGH);
    }


    void loop()
    {

      if (irrecv.decode(&results))
      {
        if (results.value == 573503) //Код кнопки (пусть это громкость плюс)
        {
          volume = volume + VOLUME_STEP;
        }

        if (results.value == 532703) //Код 2 кнопки (пусть это громкость минус)
        {
          volume = volume - VOLUME_STEP;
        }

        irrecv.resume(); // Получаем следующее значение
      }

      if (volume != volumeOld)
      {
        for (int i = 0; i <= 1; i++)
        {
          setVolume(i, volume);
        }
        volumeOld = volume;
      }
    }
     
     
    Salk нравится это.
  19. Salk

    Salk Гик

    Огромное спасибо!!! Я даже не знаю, как Вас отблагодарить. Полевые испытания начнутся завтра, обязательно отпишусь о результатах.
     
    Последнее редактирование: 13 окт 2014
  20. Salk

    Salk Гик

    Что-то не получилось. Сначала AGND соединил к DGND, думал ничего страшного, в итоге сама микросхема, стала сильно греться, но звук был, но на нажатия кнопок не реагировал. Потом разделил GND (AGND к ТБ, DGND к Arduino), микросхема больше не греется, звук так же проходил, но регулировки с пульта не происходило. Коды кнопок перепроверял несколько раз. ИК-приемник их принимал. Единственное что удалось изменить - это "START_VOLUME" менял от 1 до 256, и да действительно стартовая громкость была то тише, то громче. (Правда в компьютере максимальную громкость выше 70% не выставить, т.к. свыше уже начинались искажения, возможно максимальное входное напряжение у AD8402 ограничено, так же "START_VOLUME 0" выставить нельзя было минимум 1, при этом музыка тихо, но играла). Изменения VOLUME_STEP ничего не давали, хоть START_VOLUME 250 и STEP_VOLUME 250 выстави, чтобы хотя бы при одной нажатии кнопки видеть, что громкость меняется... ничего. :( Либо успел "убить" AD8402, либо дело в чем-то ещё. Сейчас попробую повторить урок от Джереми, чтобы проверить работоспособность микросхемы.