

Podłączenia:
Pin ESP32 | Funkcja I2S | Opis |
---|---|---|
GPIO26 | BCLK (Bit Clock) | Zegar bitowy dla przesyłania danych |
GPIO25 | LCK (Word Select / LRCLK) | Zegar słowa do synchronizacji kanałów lewego i prawego |
GPIO22 | DIN (Data In) | Dane wejściowe audio |
GND | Masa | Połączenie z masą układu |
VIN | Zasilanie | Wejście zasilania modułu (tu 3.3V) |
SCK | Zegar główny | Podłączony do GND w tej konfiguracji |
Kod programu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#include <WiFi.h> #include <AudioFileSourceHTTPStream.h> #include <AudioGeneratorMP3.h> #include <AudioOutputI2S.h> // Dane WiFi const char* ssid = "nazwa sieci wifi"; const char* password = "haslo do wifi"; // URL strumienia radia internetowego const char* radio_url = "http://31.192.216.7:8000/rmf_fm"; // Obiekty audio AudioGeneratorMP3 *mp3; AudioFileSourceHTTPStream *file; AudioOutputI2S *out; void setup() { Serial.begin(115200); // Połącz z Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.println("Łączenie z WiFi..."); } Serial.println("Połączono z WiFi!"); // Konfiguracja I2S z PCM5102 out = new AudioOutputI2S(); out->SetPinout(26, 25, 22); // GPIO26: BCLK, GPIO25: LCK, GPIO22: DIN out->begin(); // Inicjalizacja strumienia audio file = new AudioFileSourceHTTPStream(radio_url); mp3 = new AudioGeneratorMP3(); mp3->begin(file, out); } void loop() { // Odtwarzanie audio if (mp3->isRunning()) { mp3->loop(); } else { mp3->stop(); Serial.println("Strumień zatrzymany."); delay(1000); // Opcjonalnie } } |
Wyjaśnienie Przykładu: Strumieniowanie Audio z Wi-Fi na ESP32
Ten przykład demonstruje, jak używać ESP32 do strumieniowego odtwarzania radia internetowego w formacie MP3 za pomocą interfejsu I2S oraz dekodowania dźwięku w czasie rzeczywistym.
Główne sekcje kodu:
1. Inkluzje bibliotek:
1 2 3 4 |
#include WiFi; #include AudioFileSourceHTTPStream; #include AudioGeneratorMP3 #include AudioOutputI2S; |
- WiFi.h: Łączy ESP32 z siecią Wi-Fi.
- AudioFileSourceHTTPStream: Pobiera strumień MP3 z internetu.
- AudioGeneratorMP3: Dekoduje dane MP3 na format PCM.
- AudioOutputI2S: Wysyła dane audio przez interfejs I2S do modułu DAC.
2. Konfiguracja Wi-Fi:
1 2 3 |
const char* ssid = "nazwa sieci wifi"; const char* password = "haslo do wifi"; const char* radio_url = "http://31.192.216.7:8000/rmf_fm"; |
- ssid i password: Dane logowania do sieci Wi-Fi.
- radio_url: Adres URL strumienia radia internetowego.
3. Połączenie z Wi-Fi:
1 2 3 4 5 6 |
WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.println("Łączenie z WiFi..."); } Serial.println("Połączono z WiFi!"); |
ESP32 próbuje połączyć się z siecią Wi-Fi, wyświetlając status w monitorze szeregowym.
4. Konfiguracja I2S:
1 2 3 |
out = new AudioOutputI2S(); out->SetPinout(26, 25, 22); // GPIO26: BCLK, GPIO25: LCK, GPIO22: DIN out->begin(); |
- GPIO26 (BCLK): Bit Clock.
- GPIO25 (LCK): Word Select (Left-Right Clock).
- GPIO22 (DIN): Dane audio.
5. Inicjalizacja dekodera MP3:
1 2 3 |
file = new AudioFileSourceHTTPStream(radio_url); mp3 = new AudioGeneratorMP3(); mp3->begin(file, out); |
- AudioFileSourceHTTPStream: Pobiera dane audio z internetu.
- AudioGeneratorMP3: Dekoduje dane MP3 na PCM.
6. Pętla główna:
1 2 3 4 5 6 7 |
if (mp3->isRunning()) { mp3->loop(); } else { mp3->stop(); Serial.println("Strumień zatrzymany."); delay(1000); } |
Sprawdza, czy strumień działa. Jeśli strumień się zatrzyma, zostanie automatycznie uruchomiony ponownie.
Biblioteka ESP8266Audio
Ten przykład korzysta z biblioteki ESP8266Audio, która umożliwia dekodowanie i odtwarzanie audio (MP3, WAV, FLAC) na mikrokontrolerach takich jak ESP8266 i ESP32.
Instalacja biblioteki:
- Otwórz Arduino IDE.
- Przejdź do Menedżera bibliotek:
- Wybierz Narzędzia > Zarządzaj bibliotekami… lub użyj skrótu Ctrl+Shift+I.
- Wyszukaj bibliotekę:
- W polu wyszukiwania wpisz:
ESP8266Audio
.
- W polu wyszukiwania wpisz:
- Zainstaluj:
- Znajdź bibliotekę autorstwa Earle Philhower i kliknij Zainstaluj.
- Sprawdź instalację:
- Po instalacji upewnij się, że biblioteka jest widoczna w menu Szkic > Dołącz bibliotekę > Zarządzaj bibliotekami.
Alternatywa: Instalacja ręczna
- Pobierz bibliotekę:
- Przejdź do repozytorium GitHub ESP8266Audio.
- Rozpakuj pliki:
- Po pobraniu pliku ZIP rozpakuj go.
- Skopiuj do katalogu bibliotek Arduino:
- Przenieś folder do katalogu
Documents/Arduino/libraries
.
- Przenieś folder do katalogu
- Zrestartuj Arduino IDE:
- Uruchom ponownie Arduino IDE, aby biblioteka została wykryta.

Użyte w projekcie elementy:
Lista stacji polskiego radia: https://github.com/RoEdAl/polish-radio-urls
Bardziej zaawansowane podejście z buforem i pracy na 2 rdzeniach (jeden rdzeń obsługuje wifi i ładuje bufor, drugi rdzeń ma za zadanie tylko dekodowanie mp3) – wydaje się, że nie polepsza to wyników (dla radia trójki http://mp3.polskieradio.pl:8904 dalej czasem zacina się).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
#include <WiFi.h> #include <AudioFileSourceHTTPStream.h> #include <AudioGeneratorMP3.h> #include <AudioOutputI2S.h> // Dane WiFi const char* ssid = "nazwa sieci wifi"; const char* password = "haslo do wifi"; // URL strumienia radia internetowego const char* radio_url = "http://31.192.216.7:8000/rmf_fm"; // Zmienne globalne AudioGeneratorMP3 *mp3; AudioFileSourceHTTPStream *file; AudioOutputI2S *out; // Bufor const size_t bufferSize = 8192; // Bufor uint8_t buffer[bufferSize]; size_t bufferFill = 0; // Funkcja napełniająca bufor void fillBuffer() { while (bufferFill < bufferSize) { size_t bytesRead = file->read(buffer + bufferFill, bufferSize - bufferFill); if (bytesRead > 0) { bufferFill += bytesRead; } else { break; // Nie udało się odczytać więcej danych } } } // Funkcja napełniająca bufor w tle void bufferTask(void* parameter) { while (true) { if (bufferFill < bufferSize) { size_t bytesRead = file->read(buffer + bufferFill, bufferSize - bufferFill); if (bytesRead > 0) { bufferFill += bytesRead; } } vTaskDelay(10 / portTICK_PERIOD_MS); // Krótkie opóźnienie } } // Funkcja obsługująca odtwarzanie MP3 void mp3Task(void* parameter) { while (true) { if (mp3->isRunning()) { mp3->loop(); // Dekodowanie i odtwarzanie } else { mp3->stop(); Serial.println("Strumień zatrzymany."); delay(1000); mp3->begin(file, out); // Ponowne uruchomienie strumienia } vTaskDelay(10 / portTICK_PERIOD_MS); // Krótkie opóźnienie } } void setup() { Serial.begin(115200); // Połączenie z Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.println("Łączenie z WiFi..."); } Serial.println("Połączono z WiFi!"); // Konfiguracja I2S out = new AudioOutputI2S(); out->SetPinout(26, 25, 22); // GPIO26: BCLK, GPIO25: LCK, GPIO22: DIN out->begin(); // Inicjalizacja strumienia audio file = new AudioFileSourceHTTPStream(radio_url); fillBuffer(); // Początkowe napełnienie bufora mp3 = new AudioGeneratorMP3(); mp3->begin(file, out); // Tworzenie zadania dla ładowania bufora xTaskCreatePinnedToCore( bufferTask, // Funkcja napełniająca bufor "Buffer Task", // Nazwa zadania 8192, // Rozmiar stosu w bajtach NULL, // Parametry przekazane do zadania 1, // Priorytet zadania NULL, // Uchwyt zadania (opcjonalnie) 0 // Rdzeń procesora (0) ); // Tworzenie zadania dla dekodowania MP3 xTaskCreatePinnedToCore( mp3Task, // Funkcja dekodująca "MP3 Decoder", // Nazwa zadania 16384, // Rozmiar stosu w bajtach NULL, // Parametry przekazane do zadania 2, // Priorytet zadania NULL, // Uchwyt zadania (opcjonalnie) 1 // Rdzeń procesora (1) ); } void loop() { // Główna pętla pozostaje pusta lub obsługuje inne zadania } |