Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Русский
    3. аппаратные средства
    4. Железо
    5. ESP8266 remote control to Squeezebox server

    NEWS

    • ioBroker goes Matter ... Matter Adapter in Stable

    • 15. 05. Wartungsarbeiten am ioBroker Forum

    • Monatsrückblick - April 2025

    ESP8266 remote control to Squeezebox server

    This topic has been deleted. Only users with topic management privileges can see it.
    • M
      MSapogov last edited by

      Решил переставить Вашему вниманию, еще один из способов управлять Вашим плеером, кроме хардварных кнопок (у кого они есть) и WEB интерфейсов и смартфонов.

      Если у Вас имеется установленные Logitech Media Server, а также один или несколько плееров подключенных к нему, то вопрос локального управления этими плеерами у Вас когда нибудь да возникнет, как возник у меня.

      Дети услышат музыку играющюю в столовой, попросят что-бы у них она тоже заиграла, берешь свой телефон и добавляешь их плеер в синхногруппу (для синхроного воспроизведения) со столовой. Все наслаждаются музыкой. Но их нежелание на телефоне самим управлять громкостью и воспроизведением меня начало бесить… Как говорится сам сделал, сам и включай и выключай музыку. Чес самым озадачил себя сделать локальное управление проигрывателями описаными здесь - http://forum.iobroker.net/viewtopic.php?f=33&t=4983

      Т.к с неделя понять как заставить работать с кнопками (по прерываниям) в Orange Pi прошла безуспешно, то решил взять, то с чем у меня когда-то получалось это делать. Тем более в наличии еще и целая горсть ESP8266-12E.

      Пока все параметры задаются в скетче, но постепенно буду дописывать и переделывать, что-бы можно было указать параметры wifi, сервер и плеер через WEB сервер ESP-шки. А в дальнейшем можно будет сделать и через меню на OLED дисплее с сохранем этих данных во Flash памяти.

      Беглое изучение управления CLI (http://адрес_вашего_сервера:9000/html/docs/cli-api.html) привело к появлению на свет первого варианта вполне рабочего кода:

      ! ```
      `#include <esp8266wifi.h>
      #include <rotary.h> // Rotary-master https://github.com/brianlow/Rotary
      #include <onebutton.h> // OneButton https://github.com/mathertel/OneButton
      #include <wire.h> // Only needed for Arduino 1.6.5 and earlier
      #include "SSD1306.h" // SSD1306 https://github.com/squix78/esp8266-oled-ssd1306
      ! Rotary encoder = Rotary(D1, D2); // Выход энкодера GPIO5 и GPIO4
      OneButton button(D5, true); // Кнопка энкодера GPIO 14
      SSD1306 display(0x3c, D3, D4); // D3 (GPIO0) и D4 (GPIO2)
      ! const char* ssid = "";
      const char
      password = "
      ***";
      ! const char
      server = "192.168.11.1";
      const int port = 9090;
      ! int power = 0;
      int vol = 0;
      ! //String player = "00%3A00%3A00%3A00%3A00%3A1f";
      String player = "aa%3Aaa%3A5e%3A01%3Ad1%3A02";
      ! WiFiClient client;
      ! void connectWifi() {
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
      }

      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());

      display.clear();
      display.setFont(ArialMT_Plain_10);
      display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
      display.drawString(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, "Ready to work:\n" + WiFi.localIP().toString());
      display.display();
      }

      ! // Подпрограмма передачи команды на сервер
      void clitx(String cmd) {
      Serial.print("Send to LMS: ");
      Serial.print(player + " " + cmd + "\r\n");
      // This will send the request to the server
      client.print(player + " " + cmd + "\r\n");
      }
      ! // Подпрограмма обработки одиночного нажатия
      void ClickFunction() {
      Serial.println("Click.");
      clitx("mode play");
      digitalWrite(D6, 1);
      delay(5);
      digitalWrite(D6, 0);
      }
      ! // Подпрограмма обработки двойного нажатия
      void DoubleclickFunction() {
      Serial.println("Doubleclick..");
      if (power) {
      clitx("mode pause");
      digitalWrite(D6, 1);
      delay(5);
      digitalWrite(D6, 0);
      }
      }
      ! // Подпрограмма обработки долгого удержания
      void LongPressStartFunction() {
      Serial.println("LongPress start");
      ! digitalWrite(D6, 1);
      delay(5);
      digitalWrite(D6, 0);

      if (!power){
      clitx("power 1");
      power=1;
      return;
      }

      if (power) {
      clitx("power 0");
      power=0;
      return;
      }

      }

      ! // Подпрограмма обработки удержания (не используется пока)
      void LongPressFunction() {
      Serial.println("LongPress...");

      }

      ! // Подпрограмма обработки отпускания после долгого удержания (не используется пока)
      void LongPressStopFunction() {
      Serial.println("LongPress stop");
      }
      ! // Подпрограмма обработки вращения против направления движения часовой стрелки
      void LeftRotation() {
      Serial.println("LeftRotation.");
      if (power) {
      clitx("mixer volume -1");
      digitalWrite(D6, 1);
      delay(5);
      digitalWrite(D6, 0);
      }
      }
      ! // Подпрограмма обработки вращения по направлению движения часовой стрелки
      void RightRotation() {
      Serial.println("RightRotation.");
      if (power) {
      clitx("mixer volume +1");
      digitalWrite(D6, 1);
      delay(5);
      digitalWrite(D6, 0);
      }
      }
      ! // Подпрограмма подписывания и получния текущих значений
      void clisubscribe(){
      delay(100);
      client.connect(server, port);
      delay(100);
      //clitx("subscribe mode"); // подписываемся на оповещение об изменении статуса
      //delay(10);
      clitx("subscribe mixer,power,pause,play,stop"); // подписываемся на оповещение об изменении статуса
      delay(10);
      clitx("mixer volume ?"); // получаем текущие параметры
      delay(10);
      clitx("power ?");
      delay(10);
      clitx("mode ?");
      delay(10);
      clitx("playlist index ?");
      delay(10);
      }
      ! void drawProgressBarVolume(int vol) {
      display.clear();
      //int vol = (vol / 5) % 100;
      // draw the progress bar
      display.drawProgressBar(0, 51, 127, 12, vol);
      ! // draw the percentage as String
      display.setTextAlignment(TEXT_ALIGN_CENTER);
      display.drawString(10, 30, "Громкость " + String(vol) + "%");
      display.display();
      }
      ! void setup() {
      ! power = 0; // присdаиваем питанию временное значение 0

      pinMode(D8, OUTPUT); //POWER - Red led (статус питания плеера)
      pinMode(D6, OUTPUT); //TX to LMS - Green led (вспыхивает когда передается команда на сервер)

      Serial.begin(115200);
      Serial.println("Power ON...");
      Serial.println ("Connect to Router requested");

      ! display.init();
      display.flipScreenVertically();
      display.setContrast(255);
      display.setFont(ArialMT_Plain_10);
      ! connectWifi(); // signal WiFi connected
      ! Serial.print("Free Heap[b]: ");
      Serial.println(ESP.getFreeHeap());
      ! // give the WiFi a second to initialize:
      delay(500);
      ! Serial.print("connecting to ");
      Serial.print(server);
      Serial.print(":");
      Serial.println("9090");
      ! if (!client.connect(server, port)) {
      Serial.println("connection failed");
      return;
      }
      Serial.println("connection OK");
      delay(10);
      ! clisubscribe();
      delay(100);
      client.println();
      delay(200);
      if (client.available()) Serial.println("CLI available...");

      digitalWrite(D6, LOW);
      digitalWrite(D8, LOW);

      ! button.attachClick(ClickFunction);
      button.attachDoubleClick(DoubleclickFunction);
      button.attachLongPressStart(LongPressStartFunction);
      //button.attachLongPressStop(LongPressStopFunction);
      //button.attachDuringLongPress(LongPressFunction);
      ! //vol = 0;
      //drawProgressBarVolume(vol);

      }

      ! void loop() {
      ! button.tick();

      unsigned char rotary = encoder.process();
      if (rotary == DIR_NONE) {
      // do nothing
      }
      else if (rotary == DIR_CW) {
      LeftRotation();
      }
      else if (rotary == DIR_CCW) {
      RightRotation();
      }

      ! while(client.available()){
      String clirx = client.readStringUntil('\r\n');
      Serial.println("Recieving: " + clirx);

      if ( clirx == (player + " power 1 \r") || 
           clirx == (player + " power 1\r") || 
           clirx == (player + " power 1 1\r")) {
        digitalWrite(D8, HIGH);
        power = 1;
      }
      if ( clirx == (player + " power 0 \r") || 
           clirx == (player + " power 0\r")) {
        digitalWrite(D8, LOW);
        power = 0;
      }
      if (clirx.startsWith(player + " mixer volume")) {
        Serial.println("Change mixer volume " + clirx.substring(41));
        if (clirx.substring(41).startsWith("-")) {
        Serial.println("Volume -" + clirx.substring(42)); 
        if (vol >= 0) vol = vol-clirx.substring(42).toInt();
        if (vol < 0) vol =0;
        drawProgressBarVolume(vol); 
        }
        if (clirx.substring(41).startsWith("%2B")) {
        Serial.println("Volume +" + clirx.substring(44)); 
        if (vol <= 100) vol = vol+clirx.substring(44).toInt();
        if (vol > 100) vol = 100; 
        drawProgressBarVolume(vol);
        }
        if (!clirx.substring(41).startsWith("-") && !clirx.substring(41).startsWith("%2B")) {
        Serial.println("Volume set to " + clirx.substring(41));
        vol = clirx.substring(41).toInt();
        drawProgressBarVolume(vol);  
        }
      }
      // еще можно анализировать ответы...
      

      }
      String clirx="";

      !

      // проверка что есть соединение, если нет, то перезапуск
      if (client.connected() != 1 || WiFi.status() != WL_CONNECTED)
      {
      Serial.print("Reconnect to CLI ");
      client.connect(server, port);
      while (!client.connect(server, port)) {
      delay(500);
      Serial.print(".");
      }
      Serial.println();
      Serial.println("Reconnect OK.");
      //ESP.reset();
      clisubscribe();
      }
      // идем дальше...

      ! }</wire.h></onebutton.h></rotary.h></esp8266wifi.h>`
      Для отладки использовал платку "ESP8266 Witty Cloud".
      ! По тексту есть коментарии так, что можно понять как работает.
      ! Пока работает так:
      ! Включение/выключение - долгое удержание кнопки
      ! Играть - короткое нажатие на кнопку
      ! Пауза - двойное нажатие
      ! Громкость +1 или -1 - крутилка энкодера (можно изменить на +-2,3,5 %)
      ! Причем громкость передается только если состояние питания у проигрывателя - включено.
      ! Будет добавлено еще 2 кнопки вперед и назад (это команды "playlist index +1" и "playlist index -1")
      ! Ну и постараюсь добавить управление по MQTT.
      ! Понимаю, что много необходимо оптимизировать, а может и условия проверять по другому, но пока сделал так, как умею.[/b]

      1 Reply Last reply Reply Quote 0
      • M
        MSapogov last edited by

        В чем у меня есть трудности с добавлением дисплея для отображения информации, то это вот в чем:

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

        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume 34
        

        текущюю громкость с сервера, нам необходимо запомнить значение 34 в пременой vol.

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

        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume %2B1
        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume %2B2
        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume %2B2
        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume %2B2
        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume -2
        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume -2
        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume -2
        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume -2
        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume 60
        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume 30
        Recieving: 00%3A00%3A00%3A00%3A00%3A1f mixer volume 70
        
        

        В дальнейшем при приеме команд мы должны или прибавлять (если mixer volume %2B2) или убавлять (если mixer volume -2) текущее значение vol. А если получен (mixer volume 30), то задаеть ей это значение.

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

        Ох… Разобрался... Может и коряво, но работает...

        if (clirx.startsWith(player + " mixer volume")) {
              Serial.println("Change mixer volume " + clirx.substring(41));
              if (clirx.substring(41).startsWith("-")) {
              Serial.println("Volume -" + clirx.substring(42)); 
              if (vol >= 0) vol = vol-clirx.substring(42).toInt();
              if (vol < 0) vol =0;
              drawProgressBarVolume(vol); 
              }
              if (clirx.substring(41).startsWith("%2B")) {
              Serial.println("Volume +" + clirx.substring(44)); 
              if (vol <= 100) vol = vol+clirx.substring(44).toInt();
              if (vol > 100) vol = 100; 
              drawProgressBarVolume(vol);
              }
              if (!clirx.substring(41).startsWith("-") && !clirx.substring(41).startsWith("%2B")) {
              Serial.println("Volume set to " + clirx.substring(41));
              vol = clirx.substring(41).toInt();
              drawProgressBarVolume(vol);  
              }
            }
        

        Обновил код с поддержкой OLED SSD1306.

        PS: Очень хочется русского шрифта для библиотеки SSD1306 https://github.com/squix78/esp8266-oled-ssd1306

        1 Reply Last reply Reply Quote 0
        • M
          maks-d last edited by

          Привет. Уже неделю вынашиваю точно такую же идею. Только в моих планах было использовать еще ардуину как прослойку между экраном и ESP, а также поручить ей будить ESP из слип режима, для экономии питания. Идея была оформить в виде пульта с экраном от нокии.

          Но моя проблема, в программировании я не очень, а с ESP8266 только начал общаться, писать сам прошивку еще не пробовал. 😉

          1 Reply Last reply Reply Quote 0
          • M
            MSapogov last edited by

            @MSapogov:

            PS: Очень хочется русского шрифта для библиотеки SSD1306 https://github.com/squix78/esp8266-oled-ssd1306 `
            Сам отвечу…

            Вот конвертер шрифтов для этой библиотеки... https://github.com/arcao/esp8266-oled-s ... nt-creator

            Сконвертировать можно любой шрифт установленный у Вас в компьютере и под любой размер!!!
            643_whatsapp_image_2017-10-04_at_16.23.18.jpeg

            Евгений Рудаков 2 Replies Last reply Reply Quote 0
            • Евгений Рудаков
              Евгений Рудаков @MSapogov last edited by

              @msapogov Добрый вечер.Скажите пожалуйста доделать пульт дистанционного управления ESP8266 для сервера Squeezebox какой хотели?

              1 Reply Last reply Reply Quote 0
              • Евгений Рудаков
                Евгений Рудаков @MSapogov last edited by

                @msapogov Добрый вечер.Скажите пожалуйста сделали пульт дистанционного управления ESP8266 для сервера Squeezebox какой хотели?

                M 1 Reply Last reply Reply Quote 0
                • M
                  MSapogov @Евгений Рудаков last edited by

                  @евгений-рудаков said in ESP8266 remote control to Squeezebox server:

                  @msapogov Добрый вечер.Скажите пожалуйста сделали пульт дистанционного управления ESP8266 для сервера Squeezebox какой хотели?

                  Взять код из первого сообщения , подставить свои значения , и скомпилировать в Arduino IDE.

                  Евгений Рудаков 1 Reply Last reply Reply Quote 0
                  • Евгений Рудаков
                    Евгений Рудаков @MSapogov last edited by

                    @msapogov Ок. Спасибо.

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post

                    Support us

                    ioBroker
                    Community Adapters
                    Donate

                    466
                    Online

                    31.6k
                    Users

                    79.5k
                    Topics

                    1.3m
                    Posts

                    3
                    8
                    5511
                    Loading More Posts
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes
                    Reply
                    • Reply as topic
                    Log in to reply
                    Community
                    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                    The ioBroker Community 2014-2023
                    logo