Позвонить 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-підсилювач із вбудованим ЦАП
  • Динамік 3 Вт (рекомендується 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Ω 3 Вт для нормальної гучності

Забезпечте стабільне живлення 5V

Не підключайте динамік безпосередньо до ESP32

Що важливо знати про MAX98357A

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

Якщо немає звуку

1. Перевірте піни I2S

Найчастіше помилка в підключенні BCLK / LRC / DIN

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

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

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Вт
    105 грн
    ДЕТАЛЬНІШЕ
  • ESP32-C3 Super Mini — компактная плата разработки с USB-C для Arduino

    ESP32-C3 SuperMini — компактная плата разработки с USB-C для Arduino
    160 грн
    ДЕТАЛЬНІШЕ
  • Кабель DuPont мама-мама 20 см (2.54 мм) для Arduino та макетних плат

    Кабель DuPont мама-мама 20 см (2.54 мм) для Arduino та макетних плат
    2 грн
    ДЕТАЛЬНІШЕ

Коментарі до статті

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

Додати коментар