|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
интернет-радио на базе ESP8266 (NodeMCU) с расширенными возможностями
Время создания: 24.05.2025 13:48
Автор: alensav
Текстовые метки: интернет-радио на базе ESP8266 (NodeMCU)
Раздел: FRAM
Запись: alensav/MyTetra2/main/base/1748083702kz4a8ex6or/text.html на raw.githubusercontent.com
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Хочу реализовать : Добавить вывод названия трека и станции на экран. Реализовать логирование событий в FRAM . Настроить работу с несколькими станциями и сохранение выбора пользователя. Оптимизировать использование памяти и пинов. Применить: Модуль поворотного энкодера KY-040. 1.2 RIXITE XH-A232 Цифровой аудиоусилитель 30Вт+30Вт; 1.3 Estardyn PCM5102 DAC декодер для Raspberry Pi; 1.4 Цветной TFT дисплей 1.8′ SPI 128×160 px на базе ST7735; 1.5Контроллер NodeMCU ESP8266 (учесть номерацию пинов в формате D и GPI0. Qwen3-235B-A22B1:44 PM Отлично! Мы будем создавать интернет-радио на базе ESP8266 (NodeMCU) с расширенными возможностями: 🎯 Цель проекта: Создание интернет-радио с:
📦 Компоненты
📝 Основные функции
🔧 Пины ESP8266 (NodeMCU)
⚠️ Убедитесь, что пины не конфликтуют между SPI/I²C модулями. 📄 Структура проекта cpp 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <ESP8266WiFi.h> #include <Wire.h> #include <SPI.h> // === Audio === #include <AudioGeneratorMP3.h> #include <AudioFileSourceICYStream.h> #include <AudioFileSourceBuffer.h> #include <AudioOutputI2SNoDAC.h> // === Display === #include <Adafruit_ST7735.h> // === SD Card === #include <SdFat.h> // === Encoder === #include <Encoder.h> 💡 Пример кода (частично реализованный функционал) 📋 1. Инициализация Wi-Fi и подключение к станции cpp 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ⌄ ⌄ const char* ssid = "your_wifi"; const char* password = "wifi_password"; const char* stations[] = { "http://stream.station1.com/stream", "http://stream.station2.com/stream", "http://stream.station3.com/stream" }; int currentStation = 0; bool stationChanged = true; void connectToRadio() { if (mp3 && mp3->isRunning()) mp3->stop(); file = new AudioFileSourceICYStream(stations[currentStation]); buff = new AudioFileSourceBuffer(file, 2048); mp3 = new AudioGeneratorMP3(); outp = new AudioOutputI2SNoDAC(); mp3->begin(buff, outp); } 📋 2. Энкодер KY-040 — переключение станций cpp 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ⌄ ⌄ ⌄ ⌄ ⌄ #define ENCODER_CLK D5 // GPIO14 #define ENCODER_DT D6 // GPIO12 #define ENCODER_SW D7 // GPIO13 Encoder myEncoder(ENCODER_CLK, ENCODER_DT); long lastPosition = -999; void IRAM_ATTR isr_encoder() { long newPosition = myEncoder.read(); if (newPosition != lastPosition) { if (newPosition > lastPosition) { currentStation = (currentStation + 1) % (sizeof(stations)/sizeof(char*)); } else { currentStation = (currentStation - 1 + sizeof(stations)/sizeof(char*)) % (sizeof(stations)/sizeof(char*)); } stationChanged = true; lastPosition = newPosition; } } void setup() { pinMode(ENCODER_SW, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), isr_encoder, CHANGE); } 📋 3. FRAM — сохранение текущей станции и логирование cpp 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ⌄ ⌄ ⌄ ⌄ #define FRAM_ADDR_1 0x50 // для станции #define FRAM_ADDR_2 0x51 // для логов void saveCurrentStation(int stationIndex) { Wire.beginTransmission(FRAM_ADDR_1); Wire.write(0x00); // адрес Wire.write(stationIndex); Wire.endTransmission(); } int loadCurrentStation() { Wire.beginTransmission(FRAM_ADDR_1); Wire.write(0x00); Wire.endTransmission(); Wire.requestFrom(FRAM_ADDR_1, 1); return Wire.read(); } void logEvent(const char* event) { static uint16_t logPos = 0; for (int i = 0; event[i]; i++) { writeByte(FRAM_ADDR_2, logPos++, event[i]); } writeByte(FRAM_ADDR_2, logPos++, '\n'); } 📋 4. TFT ST7735 — отображение информации cpp 2 3 4 5 6 7 8 9 10 11 12 ⌄ Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); void updateDisplay(const char* stationName, const char* trackTitle) { tft.fillScreen(ST77XX_BLACK); tft.setTextSize(1); tft.setTextColor(ST77XX_YELLOW); tft.setCursor(0, 0); tft.println("Станция:"); tft.println(stationName); tft.println("\nТрек:"); tft.println(trackTitle); } ✅ Дополнительно: работа с ID3-тегами cpp 2 3 4 5 6 7 ⌄ if (file->getMetadataLength()) { char metadata[512]; int len = file->readMetadata(metadata, sizeof(metadata)); metadata[len] = 0; Serial.println("Метаданные:"); Serial.println(metadata); } 🧰 Что еще можно оптимизировать?
📌 Далее можем добавить:
🛠 Тебе понадобится:
✅ Готов к следующему шагу? Напиши: 👉 «Хочу реализовать вывод обложки» , И я подготовлю соответствующую часть проекта. 🚀 Когда закончим, у тебя будет полноценное интернет-радио с цветным интерфейсом, управлением и надёжным хранением данных. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Так же в этом разделе:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|