ESP, IoT Самое дешёвое интернет-радио на базе esp8266 и esp32.

Leon111_09

★✩✩✩✩✩✩
6 Июн 2021
92
15
Захотелось сделать миниинтернет-радио. Прошерстил интернет в поисках информации,но везде предлагают либо закрытый код,либо с использованием дополнительных наворотов типа экрана, внешнего ЦАП, и т.п. А по сути-то нужно всего две вещи: модуль ЕСП,наушники и какой нибудь источник питания. Но тут мне на глаза попалось интересное видео, и я решил взять за основу проекта скетч автора.
Андрей Ушаков: internet radio esp8266 esp32 (микро проект)
Сразу скажу важное: версия ядра esp8266 должна быть 2.5.2: на последних версиях не работает-ругается на саму есп-шку. esp32 не проверял-нет в наличии.
сам скетч еще не модифицировал-приводил,так сказать, железо к заданным параметрам. и вот что получилось:
Плата ESP8266 D1 UNO;
усилитель простейший,с алика-рублей за 20/40 покупал (уже точно не помню);
два слабеньких динамика (завалялось в хозяйстве);
небольшой мини-лабораторник;
ну и провода естественно;
и собственно, вот что получилось:
6.jpg5.jpg

4.jpg

вот схема подключения:

схема подключения есп8266 интернет-радио.png

Вот видео работы интернет-радио:


вот ссылка на материалы (в архиве скетч, библиотеки и схема подключения):

webradio_micro.rar

R.S. Забыл сказать: в скетче зашиты пять федеральных радиоканалов,так что авторские права соблюдены :) .
R.S.S Забыл еще один ресурс указать: я беру URL станций для прошивки здесь: Список потоков вещающих радиостанций .
Тут больше 1000 станций, и есть возможность сразу проверить работоспособность ссылок (чтоб потом при прошивке не гадать:почему не работает( а окажется-нерабочий URL)).
 
Изменено:

Leon111_09

★✩✩✩✩✩✩
6 Июн 2021
92
15
Ребят, подскажите старику где я ошибся: заменил в скетче таймер на кнопку (для ручного переключения станций, а не по таймеру). Станции переключает, а звук не выводит. Заливаю оригинал ( с таймером переключения станций)-все прекрасно работает. Не пинайте если где-то ошибся: вчера только сделал второй укол ревакцинации,голова как валенок,ничего не соображает :( .
 

Вложения

bort707

★★★★★✩✩
21 Сен 2020
1,461
407
Я в глубь библиотек МП3 не лазал, полностью кода не понимаю.
Но если оригинал работает - попробуйте (временно) убрать библиотеку кнопки и опрашивать кнопку просто чтением пина, без библиотеки. Если станет лучше - значит библиотеки конфликтуют. будет пища для размышлений
 

Leon111_09

★✩✩✩✩✩✩
6 Июн 2021
92
15
библиотеки конфликтуют.
навряд ли конфликтуют: я пробовал с библиотекой и подвязанной кнопкой (просто задачу по переключению выбора станции оставлял за миллисом). все работает,но естественно,кнопка не переключает, а идет смена станций по таймеру. убираю таймер,а вместо него назначаю кнопку: станции листает,но звука нет почему-то :(
вот кусок кода,отвечающий за переключение станций по таймеру (радио играет):
millis:
{

static uint32_t t = 0;

if ( millis()-t>60000){

  Serial.print("Ch: ");
  delay(200);
  ch++;
  set_ch();
  Serial.println(ch);
  StopPlaying();
  play();
t=millis();
}

  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  } else {
    delay(1000);
    play();
  }

}

а вот кусок кода,переключающий станции кнопкой (переключает,но звука нет):

Кнопка:
{
//------кнопка----
  touch.tick();
  if (touch.hasClicks()) {
    byte clicks = touch.getClicks();
    switch (clicks) {
      case 1:
  Serial.print("Ch: ");
  delay(200);
  ch++;
  set_ch();
  Serial.println(ch);
  StopPlaying();
  play();
}

  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  } else {
    delay(1000);
    play();

   }[/SPOILER]
  }
}
 
Изменено:

bort707

★★★★★✩✩
21 Сен 2020
1,461
407
@Leon111_09, я эти коды видел и сравнивал.
Еще раз - вы проюовали написать этот же код без использования библиотеки ГайверБаттон? - если нет то попробуйте.
Никаких других отличий между двумя кодами я не вижу.
 

bort707

★★★★★✩✩
21 Сен 2020
1,461
407
пробовал: картина почти та же: там вообще почему-то не переключает
показывайте

Вообще, коды так похожи, что ошибка должна быть где-то рядом. Скажите, вывод в сериал в обоих случаях АБСОЛЮТНО одинаковый? Или есть какая-то разница? Кнопка при нажатии печатает в Сериал номер канала?
 

Leon111_09

★✩✩✩✩✩✩
6 Июн 2021
92
15
показать сейчас не смогу: я там на ее месте уже гайверовскую кнопку поселил.
ошибка должна быть где-то рядом.
согласен.
Скажите, вывод в сериал в обоих случаях АБСОЛЮТНО одинаковый? Или есть какая-то разница? Кнопка при нажатии печатает в Сериал номер канала?
кнопка либо вообще ничего не давала в сериал,либо шло безостановочное переключение станций. на гайверовской в порт шлет один в один как на миллисе: все одинаковое пишет,даже что подключено к станции. но звука почему-то нет.
 

bort707

★★★★★✩✩
21 Сен 2020
1,461
407
А когда кнопка, как вы пишете, "безостановочно переключала" - звук был?
 

Leon111_09

★✩✩✩✩✩✩
6 Июн 2021
92
15
"безостановочно переключала" - звук был?
нет. его там в принципе не должно было быть: частота переключений шла где-то раз в секунду. радио просто не смогло бы с такой частотой соединяться со станциями.
 

namelessnkz

✩✩✩✩✩✩✩
13 Окт 2021
1
1
навряд ли конфликтуют: я пробовал с библиотекой и подвязанной кнопкой (просто задачу по переключению выбора станции оставлял за миллисом). все работает,но естественно,кнопка не переключает, а идет смена станций по таймеру. убираю таймер,а вместо него назначаю кнопку: станции листает,но звука нет почему-то :(
вот кусок кода,отвечающий за переключение станций по таймеру (радио играет):
millis:
{

static uint32_t t = 0;

if ( millis()-t>60000){

  Serial.print("Ch: ");
  delay(200);
  ch++;
  set_ch();
  Serial.println(ch);
  StopPlaying();
  play();
t=millis();
}

  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  } else {
    delay(1000);
    play();
  }

}

а вот кусок кода,переключающий станции кнопкой (переключает,но звука нет):

Кнопка:
{
//------кнопка----
  touch.tick();
  if (touch.hasClicks()) {
    byte clicks = touch.getClicks();
    switch (clicks) {
      case 1:
  Serial.print("Ch: ");
  delay(200);
  ch++;
  set_ch();
  Serial.println(ch);
  StopPlaying();
  play();
}

  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  } else {
    delay(1000);
    play();

   }[/SPOILER]
  }
}
У вас отсутствует оператор break в теле switch, может, проблема в этом? И еще ветка default отсутствует. На мой взгляд, использование switch в этом месте лишнее, определили что было нажатие на кнопку - выполнили действие. Попробуйте так:

Кнопка:
{
      //------кнопка----
      touch.tick();
      if (touch.hasClicks()) {
          Serial.print("Ch: ");
          delay(200);
          ch++;
          set_ch();
          Serial.println(ch);
          StopPlaying();
          play();
      }

      if (mp3->isRunning()) {
          if (!mp3->loop()) mp3->stop();
          }
      else {
          delay(1000);
          play();
       }
}
 
  • Лойс +1
Реакции: Leon111_09

Leon111_09

★✩✩✩✩✩✩
6 Июн 2021
92
15
У вас отсутствует оператор break в теле switch, может, проблема в этом? И еще ветка default отсутствует. На мой взгляд, использование switch в этом месте лишнее, определили что было нажатие на кнопку - выполнили действие. Попробуйте так:
Спасибо,помогло: теперь и переключает и звук идет на усилитель. Что значит "век живи-век учись" :) . Вот в конечном варианте как выглядит теперь код
код:
webradio_micro:
//esp8266 out D9 GPIO 3  v2 ipv6 h
//esp32 out D25 ,D26

// ------------ Кнопка -------------
#define BTN_PIN 4           // пин кнопки GPIO4 (D2 на wemos/node), 0 для схемы с ESP-01
#include "GyverButton.h"
GButton touch(BTN_PIN, HIGH_PULL, NORM_OPEN);

#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
#endif

#ifdef ESP32
#include "AudioOutputI2S.h"
#else
#include "AudioOutputI2SNoDAC.h"
#endif

#include "AudioFileSourceHTTPStream.h" //https://github.com/earlephilhower/ESP8266Audio
#include "AudioFileSourceBuffer.h" //https://github.com/earlephilhower/ESP8266Audio
#include "AudioGeneratorMP3.h" //https://github.com/earlephilhower/ESP8266Audio

// Enter your WiFi setup here:
const char *SSID = "Login";        // имя точки
const char *PASSWORD = "Password"; // пароль

String url0="http://icecast.vgtrk.cdnvideo.ru:80/vestifm_mp3_128kbps"; // URL потока станции. 1 канал Вести ФМ Федеральный
String url1="http://icecast.vgtrk.cdnvideo.ru:80/mayakfm_mp3_128kbps"; // URL потока станции. 2 канал Радио Маяк Федеральный
String url2="http://icecast.vgtrk.cdnvideo.ru:80/rrzonam_mp3_128kbps"; // URL потока станции. 3 канал Радио России Федеральный
String url3="http://icecast.vgtrk.cdnvideo.ru:80/kulturafm_mp3_128kbps"; // URL потока станции. 4 канал Радио Культура ФМ
String url4="http://icecast.vgtrk.cdnvideo.ru:80/unost_mp3_128kbps"; // URL потока станции. 5 канал Радио ЮФМ Юность ФМ
String url5="http://shoutcast.aplus.by:9000/aplus_relax_128"; // Radio @plus - Relax

String url_tmp;
int ch;

AudioGeneratorMP3 *mp3;
AudioFileSourceHTTPStream *file;
AudioFileSourceBuffer *buff;

#ifdef ESP32
AudioOutputI2S *out;
#else
AudioOutputI2SNoDAC *out;
#endif


void setup() {

#ifdef ESP8266
system_update_cpu_freq(SYS_CPU_160MHZ);//esp12
#endif

  Serial.begin(115200);
  delay(1000);
  Serial.println("Connecting to WiFi");

  WiFi.disconnect();
  WiFi.softAPdisconnect(true);
  WiFi.mode(WIFI_STA);

  WiFi.begin(SSID, PASSWORD);

      Serial.println("...Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.println(".");
    delay(1000);
  }

  Serial.println("Connected");
  Serial.printf("Start Heap: %d b\n",  ESP.getFreeHeap());

  //out = new AudioOutputI2SNoDAC(0, INTERNAL_DAC);
#ifdef ESP32
out = new AudioOutputI2S(0, 1);
#else
out = new AudioOutputI2SNoDAC();
#endif
  Serial.printf("Init audio out Heap: %d b\n",  ESP.getFreeHeap());
  url_tmp=url0;
  play();
  Serial.printf("Play audio Heap: %d b\n",  ESP.getFreeHeap());
}


void loop()
{
//------кнопка----
  touch.tick();
if (touch.hasClicks()){
  Serial.print("Ch: ");
  delay(200);
  ch++;
  set_ch();
  Serial.println(ch);
  StopPlaying();
  play();
}

  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  } else {
    delay(1000);
    play();
}
}
void play()
{
file = new AudioFileSourceHTTPStream(url_tmp.c_str());
buff = new AudioFileSourceBuffer(file, 2048);
mp3 = new AudioGeneratorMP3();
mp3->begin(buff, out);

Serial.println("play");
Serial.printf("Play audio Heap: %d b\n",  ESP.getFreeHeap());
}

void StopPlaying()
{
  if (mp3) {
    mp3->stop();
    delete mp3;
    mp3 = NULL;
  }
  if (buff) {
    buff->close();
    delete buff;
    buff = NULL;
  }
  if (file) {
    file->close();
    delete file;
    file = NULL;
  }
  Serial.println("stop");
Serial.printf(" Heap: %d b\n",  ESP.getFreeHeap());

}

void set_ch()
{
  if (ch==0) url_tmp=url0;
  if (ch==1) url_tmp=url1;
  if (ch==2) url_tmp=url2;
  if (ch==3) url_tmp=url3;
  if (ch==4) url_tmp=url4;
  if (ch==5) url_tmp=url5;
  if (ch>5) ch=0,  url_tmp=url0;  // (ch>5) цифра в кавычках должна соответствовать номеру в списке последней станции
Serial.println(url_tmp);
}
 
Изменено:

Leon111_09

★✩✩✩✩✩✩
6 Июн 2021
92
15
Представляете, я оказывается, изобретал велосипед. Специально искал проект в интернете-не нашел. А тут чисто случайно попался на глаза: и оказался практически идеальный вариант: есть и две кнопки (регулируют звук при длительном нажатии, и перелистывают станции при кратковременном), и есть простое,но функциональное управление через браузер (есть даже переназначение пинов под свою платку). Так же можно добавлять свои станции (только ограничение в 20 штук). Вот этот проект:

WiFi радио на базе ESP8266