Позвонить Telegram Viber
График работы: пн–пт 9:00–18:00

Интернет-радио на ESP32 и MAX98357A (I2S усилитель), схема, код, 3D корпус.

RizneVdim

Время сборки: 30 мин

Сложность: низкая

Компоненты

  • ESP32-C3
  • MAX98357A
  • speaker 3W 4Ω
  • tact switch x2
  • CASE

 Слушать интернет-радио через телефон или компьютер не всегда удобно: устройство должно быть рядом, Bluetooth — подключён, а батарея — не разряжена. Если хочется просто включить музыку на кухне, в мастерской или детской — логичнее сделать отдельное устройство, которое работает само по себе.

 В этом проекте вы соберёте компактное интернет-радио на базе ESP32-C3. Оно автоматически подключается к Wi-Fi, запускает поток и управляется всего двумя кнопками. Без приложений, без сопряжения и без лишних действий — включил питание и слушаешь.

В конце статьи вы найдёте готовый код и 3D-модель корпуса.

Что получится в итоге

  • Рабочее интернет-радио с Wi-Fi подключением
  • Воспроизведение MP3-потока через I2S-усилитель
  • Управление громкостью кнопками
  • Автоматическое переподключение при обрыве потока
  • Готовый корпус для 3D-печати

Используемые компоненты

  • ESP32-C3 Mini — микроконтроллер
  • MAX98357A — I2S-усилитель со встроенным DAC
  • Динамик 3W (рекомендуется 4Ω)
  • Кнопки tact switch ×2
  • Провода DuPont
  • 3D-печатный корпус

Как это работает

  • ESP32 подключается к Wi-Fi сети (в коде укажите настройки вашего WI-FI)
  • Получает поток интернет-радио в формате MP3 (замените url радиостанции на свой).
  • Далее аудио декодируется и передаётся по интерфейсу I2S на усилитель.
  • MAX98357A усиливает сигнал и выводит звук на динамик.
  • Вся логика работает автономно — без внешних устройств.

Схема подключения MAX98357A

Подключение по I2S:

  • BCLK → GPIO 5
  • LRC → GPIO 3
  • DIN → GPIO 7
  • VIN → 5V
  • GND → GND

Советы по сборке

Проверьте правильность подключения BCLK, LRC и DIN

Используйте динамик 4Ω 3W для нормальной громкости

Обеспечьте стабильное питание 5V

Не подключайте динамик напрямую к ESP32

Что важно знать про MAX98357A

MAX98357A — это цифровой усилитель класса D с интерфейсом I2S и встроенным ЦАП. Он позволяет напрямую выводить звук с ESP32 без сложных аналоговых схем, благодаря чему идеально подходит для DIY аудио-проектов.

Если нет звука

1. Проверьте пины I2S

Чаще всего ошибка в подключении BCLK / LRC / DIN

2. Проверьте динамик

Оптимально — 4Ω 3W

3. Питание

Нестабильные 5V = искажения или пропадание звука

Используемые библиотеки

  • WiFi.h
  • AudioGeneratorMP3
  • AudioFileSourceHTTPStream
  • AudioOutputI2S

Итог

 Собрав это устройство, вы получите полностью автономное интернет-радио, которое включается одной кнопкой и не требует смартфона или компьютера. Это отличная база для дальнейших проектов на ESP32: можно добавить дисплей, переключение станций или интеграцию с умным домом.

 По всем вопросам по проекту вы можете написать в комментариях ниже.

Internet Radio on ESP32 – Arduino Sketch
#include <WiFi.h>
#include "AudioFileSourceHTTPStream.h"
#include "AudioFileSourceBuffer.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"

// ===== SETTINGS =====
const char* ssid = "YOUR-WIFI";
const char* password = "YOUR-PASS";
const char* streamUrl = "http://zt01.cdn.eurozet.pl/zet-net.mp3";

// usable pins (NOT 0 and 1)
#define VOL_UP_PIN     2
#define VOL_DOWN_PIN   4

float currentVolume = 0.21;
const float volumeStep = 0.03;

// buttons
unsigned long volUpPressTime = 0;
unsigned long volDownPressTime = 0;

// audio
AudioGeneratorMP3* mp3 = nullptr;
AudioFileSourceHTTPStream* file = nullptr;
AudioFileSourceBuffer* buff = nullptr;
AudioOutputI2S* out = nullptr;

// ===== START STREAM =====
void startStream() {
    Serial.println("Starting stream");

    if (mp3)  { mp3->stop(); delete mp3;  mp3  = nullptr; }
    if (buff) { delete buff; buff = nullptr; }
    if (file) { delete file; file = nullptr; }

    file = new AudioFileSourceHTTPStream(streamUrl);
    buff = new AudioFileSourceBuffer(file, 32768);      // was 16384 → 32 KB more stable

    mp3 = new AudioGeneratorMP3();
    if (!mp3->begin(buff, out)) {
        Serial.println("Error: mp3->begin() failed");
    } else {
        Serial.println("MP3 decoder started");
    }
}

// ===== BUTTONS =====
void handleButtons() {
    unsigned long now = millis();

    // VOL UP
    if (digitalRead(VOL_UP_PIN) == LOW) {
        if (volUpPressTime == 0) {
            volUpPressTime = now;
        }
    } else if (volUpPressTime > 0) {
        unsigned long pressDuration = now - volUpPressTime;
        if (pressDuration < 800 && pressDuration > 50) {  // debounce ~50 ms
            currentVolume += volumeStep;
            if (currentVolume > 1.0) currentVolume = 1.0;
            out->SetGain(currentVolume);
            Serial.print("Volume ↑: ");
            Serial.println(currentVolume, 2);
        }
        volUpPressTime = 0;
    }

    // VOL DOWN
    if (digitalRead(VOL_DOWN_PIN) == LOW) {
        if (volDownPressTime == 0) {
            volDownPressTime = now;
        }
    } else if (volDownPressTime > 0) {
        unsigned long pressDuration = now - volDownPressTime;
        if (pressDuration < 800 && pressDuration > 50) {
            currentVolume -= volumeStep;
            if (currentVolume < 0.0) currentVolume = 0.0;
            out->SetGain(currentVolume);
            Serial.print("Volume ↓: ");
            Serial.println(currentVolume, 2);
        }
        volDownPressTime = 0;
    }
}

// ===== SETUP =====
void setup() {
    Serial.begin(115200);
    delay(500);

    pinMode(VOL_UP_PIN, INPUT_PULLUP);
    pinMode(VOL_DOWN_PIN, INPUT_PULLUP);

    Serial.print("WiFi...");
    WiFi.begin(ssid, password);

    unsigned long startTime = millis();
    while (WiFi.status() != WL_CONNECTED && millis() - startTime < 15000) {
        delay(300);
        Serial.print(".");
    }

    if (WiFi.status() == WL_CONNECTED) {
        Serial.println("\nWiFi OK");
        // WiFi.setTxPower(WIFI_POWER_8_5dBm);   // commented out — often interferes with stability
    } else {
        Serial.println("\nWiFi FAIL");
    }

    out = new AudioOutputI2S();
    out->SetPinout(5, 3, 7);           // your pins — left as is
    out->begin();                      // important: begin AFTER SetPinout
    out->SetGain(currentVolume);

    startStream();
}

// ===== LOOP =====
void loop() {
    if (mp3 && mp3->isRunning()) {
        if (!mp3->loop()) {
            Serial.println("Stream interrupted → restarting...");
            delay(300);
            startStream();
        }
    }

    handleButtons();
    delay(5);   // small pause to avoid 100% CPU usage
}

С этим покупают:

  • Корпус для ESP32 под интернет радио (3D печать)

    Корпус для ESP32 под интернет радио (3D печать)
    100 грн
    ПОДРОБНЕЙ
  • I2S аудио модуль MAX98357A усилитель 3Вт для ESP32, Raspberry Pi, Arduino

    Аудио модуль MAX98357 I2S 3.2Вт
    110 грн
    ПОДРОБНЕЙ
  • ESP32-C3 Super Mini — компактная плата разработки с USB-C для Arduino и IoT проектов

    ESP32-C3 SuperMini — компактная плата разработки с USB-C для Arduino и IoT проектов
    160 грн
    ПОДРОБНЕЙ
  • Кабель DuPont мама-мама 20 см (2.54 мм) для Arduino и макетных плат

    Кабель DuPont мама-мама 20 см (2.54 мм) для Arduino и макетных плат
    2 грн
    ПОДРОБНЕЙ

Комментарии к статье

Артем30.03.2026
Підкажіть який діаметр у динаміка має бути під цей корпус?
Дякую.
Модератор- 30.03.2026
40мм стандартні начє, бюджетний динамiк до ардуіно.

Добавить комментарий