Умная книжная полка

Тема в разделе "Глядите, что я сделал", создана пользователем barya, 6 май 2013.

  1. barya

    barya Нуб

    Здравстуйте!
    Делаем умную книжную полку. Смысл её состоит в том, что с фоторезистора идёт сигнал на аналоговый вход Ардуино УНО. Если этот сигнал превышает какое-то пороговое значение (т.е. фоторезистор достаточно освещён), то с помощью Music Shield начинает воспроизводиться определённый трек.
    Проблема в том, что собирал схему и писал код для двух фоторезисторов на аналоговых входах А4 и А5. Теперь подключил плату Тройка, чтоб с её помощью упростить схему и задействовать больше аналоговых входов.
    При включении двух пар резистор-фоторезистор на входы A4 и A5 всё работает нормально. Но как только переключаю одну из пар на любой другой вход, при этом меняя только две строки кода, завязанные на соответствующий аналоговый вход, программа сразу же перестаёт быть работоспособной.
    Код во вложении. При перемене аналогового входа в А4 на А1 меняю только две строчки
    myplayer.attachAnalogOperation(A4,adjustVolume);
    unsigned int vol_1 = analogRead(A4);
    Ставлю А1 вместо А4
    Прошу прощения за кривой код. У меня довольно-таки небольшой опыт в программировании :)
    Начинаю думать, что косячит сигнал на другом входе. С одной стороны, маловероятно, а с другой, на А4 и А5 всё работает - и не представляю, где что ещё нужно менять при изменении аналогового входа.
     

    Вложения:

  2. Megakoteyka

    Megakoteyka Оракул Модератор

    Выкладывайте код с тэгом CODE, пожалуйста. Подумайте о тех, кто с планшетов сидит.
    Вот я, например, сижу - нифига не удобно, приходится качать файл, открывать его, потом не забыть удалить... К тому же гораздо удобней видеть Ваше сообщение и код одновременно.
     
  3. Megakoteyka

    Megakoteyka Оракул Модератор

    Снимите все шилды и проверьте все аналоговые входы. Если работают - сажайте Тройку и снова проверяйте, и так до тех пор, пока не перестанут работать аналоговые входы или пока не закончатся шилды )))
     
  4. barya

    barya Нуб

    Вставил код на всякий случай
    Кнешн, неприятно по шилдам гонять, но делать нечего - с утра попробую :)

    Код (Text):

    //подключаем используемые в нашей программе библиотеки
    //сами они находятся в папке \arduino-1.0.4\libraries
    #include <Fat16.h>
    #include <Fat16Util.h>
    #include <NewSPI.h>
    #include <arduino.h>
    #include "pins_config.h"
    #include "vs10xx.h"
    #include "newSDLib.h"
    #include "MusicPlayer.h"
     
    MusicPlayer myplayer;  //вводим переменную нашего myplayer плеера, которая имеет тип MusicPlayer. все функции для этого типа описаны в библиотеке MusicPlayer.h
     
    int track_1=0;      //флаги воспроизведения треков №1 и №2. если соответствующий флаг равен 0, то данный трек в этоть момент не воспроизводится
    int track_2=0;      //если равен 1, то пора включить соответствующий трек. если больше 1, то данный трек уже находится в режиме воспоизведения
     
    int no_volume=0;      //флаг тишины в эфире. если равен 0, то в данный момент ничего не играет. если равен 1, то что-то в данный момент воспроизводится
     
    int koef=3;         //коэффициент освещённости. вводится в следствие различой освещённости в местах испытания
                          //если оч светло, то сделать около 1.5, если темнее (тусклый комнатный свет), то сделать 4-5
               
    void setup()                                            //функция setup является обязательной и выполняется только один раз при запуске устройства (а значит и самой программы)
    {
     
      Serial.begin(9600);                                   //начинаем вести журнал контроллера, чтоб если что посмотреть события на нём (Меню Сервис - Монитор порта)
     
      myplayer.keyDisable();                                //отключаем управление кнопками на Music Shield
     
      myplayer.analogControlEnable();                       //разрешаем Music Shield отслеживать сигнал на аналоговых портах A4 и A5
     
      myplayer.begin();                                   //инициализируем начало работы на Music Sield
     
      myplayer.attachAnalogOperation(A5,adjustVolume);      //разрешаем нашей функции adjustVilume, которую мы опишем дальше,
      myplayer.attachAnalogOperation(A4,adjustVolume);      //использовать значения сигналов с аналоговых входов A4 и A5
     
      myplayer.setVolume(200);                              //устанавливаем начальную громкость Music Shield равную 200.
                                                              //для справки, диапазон громкости Music Shield меняется от 0 до 255. чем меньше значение громкости, тем звучание громче.
                                                              //диапазон громкости, слышимый человеком примерно равен 0-155 (0 - самая большая громкость)
    }
     
    void loop()                                           //функция loop - обязательная функция, которая выполняется постоянно раз за разом постоянно
    {
      myplayer.setPlayMode(MODE_REPEAT_ONE);                  //ставим плеер в режим повторения одного трека
     
      myplayer.playSong("02.mp3");                          //запускаем плеер (пока с помощью трека 02.mp3)
     
      if (track_1 == 1)                                   //если флаг трэка №1 стал равен 1, то:
      {
        myplayer.playSong("01.mp3");                          //запускаем его на воспроизведение
        no_volume=1;                                          //флаг тишины делаем равным 1
        track_1++;                                          //увеличиваем флаг трека №1, т.к. он уже запущен
      }
     
      if (track_2 == 1)                                   //если флаг трэка №2 стал равен 1, то поступаем аналогично, как и с треком №1
      {
        myplayer.playSong("02.mp3");         
        no_volume=1;
        track_2++;
      }
     
    }
     
    void adjustVolume()                                   //описываем нашу функцию, которая запускается каждый момент, как только меняется значение на входах A4 или A5,
    {                                                       //а значит и освещённость какого-либо из фоторезистров
     
    unsigned int vol_1 = analogRead(A4);                    //вводим вспомогательныепеременные vol_1 и vol_2, из которых будет рассчитываться громкость звука (сами они не равны громкости)
                                                              //в vol_1 считываем значение со входа A4
     
    vol_1=vol_1*koef;                                       //масштабируем это значение в соответствии с нашей общей освещённостью, используя коэффициент, заданный выше (обычно koef=2-3)
     
    if (vol_1 >= 80)                                        //экспериментально установлено, что освещённость фоторезисторов меняется примерно от 2 до 80
      vol_1=79;                                           //ограничим на всякий случай параметр vol_1 значением 79. итого 0 < vol_1 < 80.
                                                              //79 - значение максимально освещённого первого фоторезистора. при нём громкость равна 1 (самое громкое значение)
                                                             
     
    unsigned int vol_2 = analogRead(A5);                    //для вспомогательной переменной vol_2 поступаем аналогично, как и для vol_1
    vol_2=vol_2*koef;
    if (vol_2 >= 80)
      vol_2=79;
     
     
    if ((track_1==0) && (vol_1 > 10) )                    //если в данный момент трек №1 не воспроизводится, но значение освещённсти первого фоторезистора
    {                                                       //превысило 10 (заданный на основе экспериментовнами порог), то пора запускать трек 01.mp3. для этого:
     
      myplayer.opStop();                                    //останавливаем всё, что воспроизводится на данный момент
     
      track_1=1;                                            //ставим значение флага трека №1 в значение, равное 1. т.е. как только цикл loop увидит, что мы поменяли здесь
                                                              //значение track_1 на 1 вместо 0, то он запускает трек 01.mp3 (см. выше по тексту кода)
    }
     
    if ((track_2==0) && (vol_2 > 10) )                    //если в данный момент трек №2 не воспроизводится, но значение освещённсти второго фоторезистора
    {                                                       //превысило 10, то пора запускать трек 02.mp3. для этого поступаем аналогично, как и с первым треком
      myplayer.opStop();
      track_2=1;
    }
     
    if ((vol_1 <= 10) && (vol_2 <= 10) && (no_volume != 0))  //как только значения освещённостей обоих фоторезисторов стали ниже порогового, но флаг тишины no_volume
    {                                                       //всё ещё равен 1, то пора глушить музыку. для этого:
     
      myplayer.opStop();                                    //останавливаем воспроизведение на Music Shield
     
      track_1=0;                                            //ставим флаги обоих треков в значение, равное 0
      track_2=0;
     
      no_volume=0;                                        //ставим флаг тишины в эфире в значение, равное 0
     
    }
     
    unsigned char volume=230;                               //вводим переменную, которая равна громкости звука на Music Shield. Пока она равна 230 (т.е. тишина)
     
    if (vol_1 > 10)                                       //если освещённость первого фоторезистора выше порогового значения, т.е. играет первый трек,
      volume = (80-vol_1);                                //то и общую громкость рассчитываем из значения vol_1 для первого фоторезистора
     
    if (vol_2 > 10)                                       //если освещённость второго фоторезистора выше порогового значения, т.е. играет второй трек,
      volume = (80-vol_2);                                //то и общую громкость рассчитываем из значения vol_2 для второго фоторезистора
     
    myplayer.setVolume(volume);                           //устанавливаем громкость для нашего плеера
    }
     
  5. barya

    barya Нуб

    Добрый день!
    Снял Тройку, использую аналоговые входы с Music Shield
    Переписал код, чтоб просто проверять сигнал с помощью Music Shield только с одного фоторезистора (код см. ниже). Программа изначально работает.
    Первая проблема - как только раскомменчиваю строки myplayer.attachAnalogOperation(A2,adjustVolume); или myplayer.attachAnalogOperation(A3,adjustVolume); работоспособность программы сразу же теряется
    Вторая проблема - когда в коде делаю в строке vol_1 = analogRead(A4); считывание с A0 или A1 (соответственно, перетыкаю контакт на них) программа, кажется, работает, но судя про громкости звучания сигнал из них идёт намного ниже.
    В инете нашёл про порты А4 и А5 только такую отличительную особенность: I2C: 4 (SDA) и 5 (SCL)
    Пока в тупике, а время жмёт :) Есть совет?


    Код (Text):
    #include <Fat16.h>
    #include <Fat16Util.h>
    #include <NewSPI.h>
    #include <arduino.h>
    #include "pins_config.h"
    #include "vs10xx.h"
    #include "newSDLib.h"
    #include "MusicPlayer.h"
     
    MusicPlayer myplayer;  //вводим переменную нашего myplayer плеера, которая имеет тип MusicPlayer. все функции для этого типа описаны в библиотеке MusicPlayer.h
     
    int track_1=0;      //флаги воспроизведения треков №1 и №2. если соответствующий флаг равен 0, то данный трек в этоть момент не воспроизводится
     
    int no_volume=0;      //флаг тишины в эфире. если равен 0, то в данный момент ничего не играет. если равен 1, то что-то в данный момент воспроизводится
     
    int koef=3;         //коэффициент освещённости. вводится в следствие различой освещённости в местах испытания
                          //если оч светло, то сделать около 1.5, если темнее (тусклый комнатный свет), то сделать 4-5
     
    void setup()                                            //функция setup является обязательной и выполняется только один раз при запуске устройства (а значит и самой программы)
    {
     
      Serial.begin(9600);                                   //начинаем вести журнал контроллера, чтоб если что посмотреть события на нём (Меню Сервис - Монитор порта)
     
      myplayer.keyDisable();                                //отключаем управление кнопками на Music Shield
     
      myplayer.analogControlEnable();                       //разрешаем Music Shield отслеживать сигнал на аналоговых портах A4 и A5
     
      myplayer.begin();                                   //инициализируем начало работы на Music Sield
     
      myplayer.attachAnalogOperation(A0,adjustVolume);
      myplayer.attachAnalogOperation(A1,adjustVolume); 
      //myplayer.attachAnalogOperation(A2,adjustVolume);
      //myplayer.attachAnalogOperation(A3,adjustVolume);   
      myplayer.attachAnalogOperation(A5,adjustVolume);      //разрешаем нашей функции adjustVilume, которую мы опишем дальше,
      myplayer.attachAnalogOperation(A4,adjustVolume);      //использовать значения сигналов с аналоговых входов A4 и A5
     
      myplayer.setVolume(200);                              //устанавливаем начальную громкость Music Shield равную 200.
                                                              //для справки, диапазон громкости Music Shield меняется от 0 до 255. чем меньше значение громкости, тем звучание громче.
                                                              //диапазон громкости, слышимый человеком примерно равен 0-155 (0 - самая большая громкость)
    }
     
    void loop()                                           //функция loop - обязательная функция, которая выполняется постоянно раз за разом постоянно
    {
      myplayer.setPlayMode(MODE_REPEAT_ONE);                  //ставим плеер в режим повторения одного трека
     
      myplayer.playSong("02.mp3");                          //запускаем плеер (пока с помощью трека 02.mp3)
     
      if (track_1 == 1)                                   //если флаг трэка №1 стал равен 1, то:
      {
        myplayer.playSong("01.mp3");                          //запускаем его на воспроизведение
        no_volume=1;                                          //флаг тишины делаем равным 1
        track_1++;                                          //увеличиваем флаг трека №1, т.к. он уже запущен
      }
     
    }
     
    void adjustVolume()                                   //описываем нашу функцию, которая запускается каждый момент, как только меняется значение на входах A4 или A5,
    {                                                       //а значит и освещённость какого-либо из фоторезистров
     
    unsigned int vol_1 = analogRead(A4);                    //вводим вспомогательныепеременные vol_1 и vol_2, из которых будет рассчитываться громкость звука (сами они не равны громкости)
                                                              //в vol_1 считываем значение со входа A4
     
    vol_1=vol_1*koef;                                       //масштабируем это значение в соответствии с нашей общей освещённостью, используя коэффициент, заданный выше (обычно koef=2-3)
     
    if (vol_1 >= 80)                                        //экспериментально установлено, что освещённость фоторезисторов меняется примерно от 2 до 80
      vol_1=79;                                           //ограничим на всякий случай параметр vol_1 значением 79. итого 0 < vol_1 < 80.
                                                              //79 - значение максимально освещённого первого фоторезистора. при нём громкость равна 1 (самое громкое значение)
     
     
    if ((track_1==0) && (vol_1 > 10) )                    //если в данный момент трек №1 не воспроизводится, но значение освещённсти первого фоторезистора
    {                                                       //превысило 10 (заданный на основе экспериментовнами порог), то пора запускать трек 01.mp3. для этого:
     
      myplayer.opStop();                                    //останавливаем всё, что воспроизводится на данный момент
     
      track_1=1;                                            //ставим значение флага трека №1 в значение, равное 1. т.е. как только цикл loop увидит, что мы поменяли здесь
                                                              //значение track_1 на 1 вместо 0, то он запускает трек 01.mp3 (см. выше по тексту кода)
    }
     
    if ((vol_1 <= 10) && (no_volume != 0))  //как только значения освещённостей обоих фоторезисторов стали ниже порогового, но флаг тишины no_volume
    {                                                       //всё ещё равен 1, то пора глушить музыку. для этого:
     
      myplayer.opStop();                                    //останавливаем воспроизведение на Music Shield
     
      track_1=0;                                            //ставим флаги обоих треков в значение, равное 0
     
      no_volume=0;                                        //ставим флаг тишины в эфире в значение, равное 0
     
    }
     
    unsigned char volume=230;                               //вводим переменную, которая равна громкости звука на Music Shield. Пока она равна 230 (т.е. тишина)
     
    if (vol_1 > 10)                                       //если освещённость первого фоторезистора выше порогового значения, т.е. играет первый трек,
      volume = (80-vol_1);                                //то и общую громкость рассчитываем из значения vol_1 для первого фоторезистора
     
    myplayer.setVolume(volume);                           //устанавливаем громкость для нашего плеера
    }
     
  6. barya

    barya Нуб

    Так, я понял. Сам дурак)
    Music Shield использует аналоговые входы А0-А3. Поэтому А4 и А5 как раз остаются свободными
    Вопрос - можно ли как-либо освободить А0-А3 для собственного использования?
     
  7. Mitrandir

    Mitrandir Гуру

    снимаешь шилд с ардруины, и проводами мама-папа перекидываешь ноги 0-3 шилда на другие дырки ардуины + правишь код на использования новых ног
    как вариант, купить прото-шилд и на нем собрать перестановщик ног.
     
  8. barya

    barya Нуб

    Так, если я приеду за Леонардо, то попадаю в следующую ситуацию
    Мьюзик Шилд использует аналоговые входы А0-А3. Нам остаётся А4-А5. Итого пока два
    Мьюзик Шилд использует цифровые входы 2-13. Используя myplayer.keyDisable(); освобождаем выходы 3-7, из которых 4 и 6 можно использовать, как я понимаю, в качестве аналоговых
    Нужно как-то взять ещё один порт (8,9,10 или 12). Это реально? :)))
     
  9. nailxx

    nailxx Официальный Нерд Администратор

    Да, верно. A0-A3 заняты для взаимодействия с VS1053 мимо штатного интерфейса SPI. Руками этого проделывать не пробовал, но есть несколько предположений:
    • Это взаимодействие нафиг не нужно в общем случае и Music Shield будет играть треки без него. Чтобы проверить не установить шилд поверх, а соединить все пины проводками мама-папа навесу. Все, кроме A0-A3 и поглядеть. Если они таки не нужны, их можно загнуть/откусить и по боку проводками прокинуть до тройки
    • A3 является chip select’ом. Поэтому, даже если по железу ничего не менять и просто не трогать A3, по идее, всё может продолжить работать
    • Если A0-A3 таки используются, можно либо (а) прибегнуть к совету barya, либо (б) использовать внешний АЦП. Например, http://www.chipdip.ru/product/tlc1541in/. С ним заимеете 12 дополнительных аналоговых входов.
    • Или «семь бед — один ответ»: Arduino Mega 2560
     
  10. barya

    barya Нуб

    http://seeedstudio.com/wiki/Music_Shield_V2.0
    Здесь написано, D8 - Green Led instructions;
    Думаю - если её отломать на Мьюзик Шилде - ничего не испортится?)))
     
  11. nailxx

    nailxx Официальный Нерд Администратор

    А ну да, точно. И отламывать не придётся. Просто не будет у вас светодиод зелёный гореть, если вы пин на вход включите.
     
  12. Megakoteyka

    Megakoteyka Оракул Модератор

    Все стесняюсь спросить - а книги и полка каким образом участвуют? :)
     
  13. nailxx

    nailxx Официальный Нерд Администратор

    Оэтоязнаю :)

    На полке стоят книги, под книгами дырки, в дырках фоторезисторы. Берём книгу, светим на фоторезистор, проигрываем саундтрек к книге.
     
    Megakoteyka нравится это.
  14. Mitrandir

    Mitrandir Гуру

    ага типа положи книгу на место!