Arduino Yún: Слушаем Интернет-радио. И через Малину и через Cubietruck.

Тема в разделе "Глядите, что я сделал", создана пользователем ИгорьК, 4 янв 2015.

  1. ИгорьК

    ИгорьК Гуру

    Ура! Нашего (а не критиков) полку прибыло ;)
    Мне нравится русский интерфейс, но нежно отношусь к чужому авторству. Ничего серьезно там менять не надо, ИМХО, решил пусть так и будет.
    Да и вообще - язык интерфейса последнее дело.
    Не последнее - кририллица. Сейчас ее конвертирует в транслит для LCD Ардуино файл index_web_api.php
    Пытался конвертировать "на лету" посредством sed - получаются кракозяблы :(

    Если уж до конца переводить... Вы кое-что забыли (табличка удаления не русифицирована).
    Кроме того, файл index_web_api.php выдает "n/a". Его тоже можно заменить.
    И раз пошла такая пьянка... Еще чуть поменял расположение вывода в index. Сделал логичнее - теперь название станции вверху, а не перемещается вверх, когда нет информации о том что звучит.
    Приложил все три файла.
    00111.jpg
    00110.jpg
     

    Вложения:

    • 3Files.zip
      Размер файла:
      7,6 КБ
      Просмотров:
      350
    Последнее редактирование: 5 фев 2015
  2. ИгорьК

    ИгорьК Гуру

    Где-то читал такую вещь, что скорость в сетке wifi зависит от скорости самого медленного клиента. С опаской отношусь к вывешиванию в сетку стандарта n устройств старых стандартов, хотя они и совместимы.
    Вы не разбирались с этим вопросом?
     
  3. ИгорьК

    ИгорьК Гуру

    Скетч для Ардуино - отражение информации на LCD. Скетч полностью рабочий, но временный. Для работы с энкодером перепишу с целью обеспечения его проверки и избавления от волшебной функции delay() :) Но пока это была тренировка вывода и сдвига.
    Для работоспособности скетча необходимо:
    1. Заменить файл index_web_api.php на тот, что я дал в предыдущем посте.
    2. В opt/radio/ заменить файл rollstationinfo.sh на прилагаемый.

    Код (C):

    /*
    Этот скетч ПОЛНОСТЬЮ РАБОЧИЙ! Выравнивает, отображает отсутствуие информации.

    http://robocraft.ru/blog/808.html  -идею взял от сюда

    */


    #include <LiquidCrystal.h>
    #include <Bridge.h>
    #include <Console.h>
    #include <string.h>

    // initialize the library with the numbers of the interface pins
    LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
    String info = " Jiraffe Radio";
    const String clearingRow = "                ";
    char to_lcd[] = "                ";

    void setup() {
        Bridge.begin();
    //    Console.begin();
    //    while(!Console);
        lcd.begin(16, 2);
        lcd.print(info);
        delay(3000);
    }

    void loop() {
        FPrintInfo();
        delay(1000);
    }

    void FPrintInfo(void) {
        unsigned int len_str  = 0;          // Счетчик длины строки информаци
        const char *poInfo;                // Указатель на строку
        info = FGetInfo(1);                // Информация о станции
        lcd.setCursor(0,0);
        lcd.print(clearingRow);
        int aa = (16 - info.length()) / 2;  // Подсчеты для центровки вывода
        lcd.setCursor(aa,0);
        lcd.print(info) ;
        info = FGetInfo(0);                // Информация о музыке
        info.trim();                        // Очистка лишнего на всякий случай

        if (info.length() > 16) {
            poInfo = info.c_str();          // Установка указателя на строку
            info += "                ";    // Добавляем справа 16 пробелов, чтобы строка уезжала с экрана полностью.
            for(byte a=0; a<16; a++) {      // Забиваем символы в стринг для вывода
                to_lcd[a] = *(poInfo+a);
            }
            lcd.setCursor(0,1);
            lcd.print(to_lcd);              // Выводим сринг
            delay(2000);                    // Ждем две секунды перед скроллингом
            len_str = 16;                  // Чтобы не двигать сначала
            while (*(poInfo+len_str))  {    // Пока не конец строки ... Поехал скроллинг
                for (byte i=0 ; i < 15 ; i++) to_lcd[i] = to_lcd[i+1] ;
                to_lcd[15] = *(poInfo+len_str);
                len_str++ ;
                for (byte i=0 ; i < 16 ; i++) { // Отображаем на LCD посимвольно.
                    lcd.setCursor(i,1);
                    lcd.print(to_lcd[i]);
                }
                delay(350) ;                // Задержка перед перепечаткой
            }
        }
        else {                              // Если информация меньше 16 символов
            lcd.setCursor(0,1);
            lcd.print(clearingRow);
            if(info.length() <4) info = "No Info"; // Или ее вообще нет
            int bb = (16 - info.length()) / 2;  // Центрируем
            lcd.setCursor(bb,1);
            lcd.print(info);                    // Печатаем
        }
    }

    String FGetInfo (byte no) {            // Функция запроса информации
    //  Console.println("In Function Now.");
        String info = "";
        Process PrGetInfo;
        PrGetInfo.begin("cat");
        if (no == 0) {
            PrGetInfo.addParameter("/opt/radio/nowSong.txt");
        }
        //else if(no == 1) {
        else  {
            PrGetInfo.addParameter("/opt/radio/nowRadio.txt");
        }

        PrGetInfo.run();
        while (PrGetInfo.available()>0) {
            char c = PrGetInfo.read();
    //        Console.println(c);
            info += (String) c;
        }
    //    Console.println(info);
        info.trim();
        return info;
    }
     
     

    Вложения:

    Последнее редактирование: 5 фев 2015
  4. shaman1010

    shaman1010 Нерд

    Там немного сложней, в целом - можно тормознуть свою сеть, особенно если железка b-стандарта на границе покрытия. Общий смысл таков, если сейчас в сети кто-то из старого стандарта просит связь - точка доступа спрыгивает туда (если ей разрешено это делать). Устройство отпало - точка вернулась. (некоторые точки доступа потом обратно не могут вернуться, отсюда в некоторых комбинациях выплывают подобные проблемы). Но у меня уже очень давно нет железок b-стандарта. По-этому уже и не помню, когда с таким сталкивался (по-моему никогда, всегда мои железки возвращались обратно без проблем).
    Еще поменял местами кнопки Play и Пауза - так мне кажется логичней (нажатие на кнопку предполагает действие, а не индикацию текущего режима).
     

    Вложения:

    • index_play.zip
      Размер файла:
      2,3 КБ
      Просмотров:
      320
  5. ИгорьК

    ИгорьК Гуру

    У меня этого старого железа в закромах - как у дурачка фантиков :) Только и втыкай USB звуковухи.
    Думаю, можно сделать отдельную wifi сетку для радио на старых железках.
     
  6. shaman1010

    shaman1010 Нерд

    Это, по-сути, самое логичное решение.
     
  7. shaman1010

    shaman1010 Нерд

    Названия станций берутся из потока, а для экрана (без кириллицы, как я понял) - из плейлиста.
    А каким образом в плейлист руками добавить два названия? (одно кириллицей, для отображения в web-интерфейсе, второе латиницей, для передачи на экран). А то в качестве названия читать n/a или непонятную аббревиатуру - не комильфо. Можно же для себя их вполне логично обозвать.
     
  8. ИгорьК

    ИгорьК Гуру

    Названия станций для LCD от ардуино берутся из плейлиста и они там должны быть все на латинице. Плейлист - единственный файл, с которым надо работать руками, это я для себя как ограничение имею.

    То что в веб-морде есть возможность добавлять и удалять станции - дело хорошее, но не доработанное. Нужно бы еще сохранение. Кнопку как-нибудь добавлю, но проблема в том, что MPD сохраняет листы в .m3u без сохранения названий станций. А это не интересно. С другой стороны, правка плейлиста радио - не частая операция.

    1. Для Веб-морды названия берутся из потока и достаются файлом index_web_api.php. Он сейчас (в отличие от авторского) отдает кириллицу и в названии станции и в названии музыки. Для LCD он осуществляет транслитерацию музыки и вывод в файл nowSong.txt.
    index_web_api.php вызвается веб-мордой, когда она открыта, методами AJAX.
    Также index_web_api.php вызывается демоном rollstationinfo.sh каждые пять секунд.
    2. Этот же демон формирует файл nowRadio.txt - как раз берет латиницу из плейлиста на основе номера воспроизведения от запроса к mpc.
     
    Последнее редактирование: 5 фев 2015
  9. ИгорьК

    ИгорьК Гуру

    Я же это исправил в файлах index_web_api.php и index.html - см. мой пост с картинкой.
     
  10. shaman1010

    shaman1010 Нерд

    У меня, если заменить php-ник, вообще вся информация пропадает, и названия текущих станций/композиций, и общий список станций...
     
  11. ИгорьК

    ИгорьК Гуру

    Вот рабочий комплект еще раз - прямо из железки только что выкачал
     

    Вложения:

    • Desktop.zip
      Размер файла:
      268,4 КБ
      Просмотров:
      718
  12. shaman1010

    shaman1010 Нерд

    Между ответами уже разобрался :)
    Добавил новый файл и подправил пути у себя.
    Остался нюанс, через 5 сек файл обновляется, и видим опять то, что передает станция в качестве названия :)
    Плюс в списке станций изменяется ее название.
    // $test = fwrite($fp, $information); не помогает, нужно на досуге разобраться с этим файлом
     
    Последнее редактирование: 5 фев 2015
  13. ИгорьК

    ИгорьК Гуру

    Чет не так у Вас. Вот так правильно:

     
    Последнее редактирование: 11 фев 2015
  14. shaman1010

    shaman1010 Нерд

    У меня там все не так:) После нескольких итераций с железом - решил пока остановиться на кубитраке.
    Но по ходу движения разбираюсь с mpd/mpc. Очень хорошая связка, уже поставил клиентов под андроид и винду. Все достаточно быстро/красиво. А вот с правами доступа - полная неразбериха пока что (apache+php не наш путь; только nginx, только хардкор :) ). На текущий момент, пока не запущен демон mpd, сайт отзывается, демона запускаю, похоже блокирую доступ к каким-то ресурсам, и веб-интерфейс не может достучаться до нужных ему файлов.
    Но по ходу движения понимаю, что достаточно просто можно получить полный доступ к проигрываемому контенту, соответственно создавать/добавлять/изменять плейлисты, регулировать громкость, перемещаться по треку/трекам, стартовать с того файла, на котором у сервака питание пропало и т.д. В радио многое из этого не нужно, но потихоньку приходит понимание возможностей, и способа их реализации. В общем пока остановился на кубитраке (он у меня наименее загруженный, но с достаточными возможностями для любых воплощений), но по большому счету конечный продукт может быть легко адаптируемым под различные linux-платформы. Если здесь мои движения в этом направлении кому-нибудь интересны, могу делиться своими наработками.

    p.s. на кубике выявилась одна интересная особенность, возможно на другом железе она тоже актуальна:
    Вот так в mpd.conf звук радиостанций со временем начинает джиттерить (заикаться/вибрировать/...)
    format "44100:16:2"
    а вот так - работает исключительно:
    format "48000:24:2"

    решил попробовать только по тому, что виндовый клиент показал 24 бита во всех передаваемых потоках. Причем "48000:16:2" тоже квакает со временем.
    Т.е. почему-то кубитраковской карте больше нравится 24 бита.
    Вобщем вот такой, незаметный на первый взгляд момент присутствует...
     
    Последнее редактирование: 10 фев 2015
    ИгорьК нравится это.
  15. shaman1010

    shaman1010 Нерд

    Cubietruck:
    Итак, очередное мелкое, но интересное дополнение, а именно - UPnP Media Renderer
    Что это такое? Да все очень просто, есть винда (у меня 8.1), есть сеть, есть стандартный медиаплейер.
    Сидим мы за компьютером, и решили музыку послушать на большой акустике (к которой подключен наш cubietruck). Нет ничего проще - запускаем стандартный "проигрыватель Windows Media", переключаемся в библиотеку (прямоугольничек в правом верхнем углу), открывается библиотека, справа вверху значек медиаплейера (с треугольничком в зеленом кружочке), жмем Play To, и выбираем UpMpd.
    Открывается маленькое окошко со списком файлов и начинает играть на удаленном кубике. Файлы добавляются обычным перетаскиванием.
    Но это для нубов :)
    Для любителей музыки - запускаем настроенный и прокачанный foobar200, идем в настройки, Playback-Output и выбираем в качестве выхода: UPnP: UpMpd. Все! :) Запускаем то, что хотим послушать и слушаем себе.

    А что бы это все заработало (считаем, что mpd/mpc у нас установлен, настроен и радио воспроизводит, у меня стоят настройки format "48000:24:2", на других не проверял) нужно всего нечего:
    1) для правильных и последовательных - идем туда, читаем, разбираемся, устанавливаем.
    2) для ленивых и доверчивых -
    Создаем и редактируем файл /etc/apt/sources.list.d/upmpdcli.list
    добавляем в него две строчки:
    deb http://www.lesbonscomptes.com/upmpdcli/downloads/debian/ unstable main
    deb-src http://www.lesbonscomptes.com/upmpdcli/downloads/debian/ unstable main
    затем:
    sudo apt-get update
    sudo apt-get install upmpdcli

    Все :)

    UPnP появится в сети. Пользуемся, как написал выше.

    p.s. foobar весь lossless стримит без проблем.
     
    Последнее редактирование: 11 фев 2015
    ИгорьК нравится это.
  16. ИгорьК

    ИгорьК Гуру

    "Делай добро и кидай его в воду". Это обязательно кому-то потребуется.

    Это оно? Интересный выбор. А почему? Видимо, Кубик Вы будете использовать еще как-то, ИМХО для медиаплейера суперизбыточно. А все функции и радиопримочки уже действительно реализованы в Малине-Volumio.
    Мне, кстати, к Малинке железки пришли на почту. Отпишусь скоро.
     
    Последнее редактирование: 11 фев 2015
  17. shaman1010

    shaman1010 Нерд

    Оно.
    Причины:
    1) Уже есть :)
    2) Брал в качестве сервера домашней автоматизации. Сразу в комплекте с отличным корпусом, такой.
    Становится нормальный Debian.
    3) На плате уже разведен SATA интерфейс и есть место для установки 2,5" винта, причем с доп. платой можно и 3,5" установить (12В питание подается отдельно)
    4) Не нужно изобретать велосипед в качестве ИБП. На плате разъем, в который вставляется LiON батарея.
    5) 2ГБ RAM, для сервера - актуально.
    6) Куча выведенных GPIO, и вполне развитое сообщество, чтоб их использовать.
    7) Потребление... почти отсутствует, для круглосуточной домашней железки весьма весомый аргумент.
    8) Есть SPDIF, причем при наличии прямых рук - получаем выход уровня HiEnd.
    9) WiFi/Bluetooth/IR в комплекте (хотя синезуб достаточно гемморный, но при большом желании можно использовать)
    10) Гигабитная сетевушка (по факту, конечно полугигабитная, но все-равно в 5 раз быстрее соток, у меня вся локалка на гигабите)
    11) Достаточно мощный проц. Видео слабовато, но 720p можно смотреть, если есть в этом необходимость (у меня нет такой необходимости)

    Мне этого хватило :)

    А малинку A+ отложил для чего-нить другого....
     
  18. ИгорьК

    ИгорьК Гуру

    Ок. Бум наблюдать. А пока к OpenWRT.
    На вопрос, как я организую возобновление проигрывания последней станции после включения питания.
    Демон rollstationinfo.sh имеет следующий код, который вызывается каждые пять секунд:
    Код (Text):
    playing=$(mpc | grep "playing" | sed "s/^.*#//" | sed "s/\/.*//")
    echo "$playing" > /opt/radio/nowNumber.txt
    Файл /etc/rc.local имеет такой код:
    Код (Text):
    startplaying=$(cat /opt/radio/nowNumber.txt)
    mpc play $startplaying
    Эта парочка и обеспечивает при включении воспроизведение последней станции.
     
  19. shaman1010

    shaman1010 Нерд

    В mpd.config есть два таких параметра:
    state_file "/var/lib/mpd/state"
    sticker_file "/var/lib/mpd/sticker.sql"
    Они как раз и занимаются штатно этими вещами. Проверьте на OpenWRT.
    Весьма возможно нужно будет еще раскомментировать эту строчку:
    db_file "/var/lib/mpd/tag_cache"
     
    ИгорьК нравится это.
  20. ИгорьК

    ИгорьК Гуру

    В OpenWRT надо раскоментировать соответствующую строку в файле /etc/mpd.conf чтобы получить файл state. Этот файл появится в директории /root/.mpd
    Теперь действительно воспроизведение начинается с той станции, где было ранее. Надо заметить, что в файле state находится и текущий плейлист. Как он будет взаимодействовать с подргужаемым - надо будет разбираться.
    Но...:
    (+) Зато решается вопрос сохранения станций, добавленных через веб-морду.
    (-) Если в названии станции есть кириллица, возникает проблема ее отражения на LCD
    ==============
    Таким образом. Если оставлять загрузку плейлиста через скрипт при старте, то листы складываются, а не дополняются. Это плохо...
     
    Последнее редактирование: 11 фев 2015