Die Entwicklung eines einfachen Internetradios ist mit Hilfe eines ESP32 Audiokit Boards sehr einfach. Das Board enthält bereits sämtliche Komponenten, die für das Verbinden ins Internet (ESP32 WiFi Modul) und das Ausgeben der Audio-Signale benötigt werden (DAC, Audiobuchsen bzw. Verstärker für direkte Lautsprecherausgabe). Somit ist nur noch die Software notwendig. Hier werden bereits sämtliche SW-Komponenten durch Libraries abgedeckt. Somit beschränkt sich die Programmierung nur auf die generelle Ablaufsteuerung (LED ansteuern, Taster auswerten, WiFi Verbindung starten, Audiostream abspielen ...). Die Liste unterhalb enthält eine Schritt-für-Schritt Anleitung für das Projekt. Weiter unterhalb befindet sich der Source Code.
/* USED LIBRARIES ESP32-audioI2S library - https://github.com/schreibfaul1/ESP32-audioI2S ES8388 library - https://github.com/maditnerd/es8388 */ /* IDE BOARD SETTINGS Arduino Board Settings: ESP32 WROVER Module Port: COMx Core Debug Level: None Erase All Flash Before Sketch Upload: Disabled Flash Frequency: 80MHz Flash Mode: QIO Partition Scheme: Huge APP (3MB No OTA/1MB SPIFFS) Upload Speed: 921600 Programmer: Esptool */ /* BOARD SETTINGS Settings for ESP32-A1S v2.2 (ES8388) Switch 2, 3 ON 1, 4, 5 OFF */ // INCLUDES #include "Arduino.h" #include "WiFi.h" #include "Audio.h" #include "ES8388.h" // DEFINES // Power amplifier pins #define PA_EN 21 // low = enabled, high = disabled // DAC pins #define I2S_DSIN 26 #define I2S_BCLK 27 #define I2S_LRC 25 #define I2S_MCLK 0 #define I2S_DOUT 35 #define IIC_CLK 32 #define IIC_DATA 33 // Button pins #define BTN_VOLUME_DOWN_PIN 19 // key 3 #define BTN_VOLUME_UP_PIN 23 // key 4 #define BTN_STATION_PREV_PIN 18 // key 5 #define BTN_STATION_NEXT_PIN 5 // key 6 #define BTN_DEBOUNCE_CNT 10 // LED pins #define LED_WIFI_PIN 22 // LED 4 #define LED_RADIO_PIN 22 // LED 4 // Station list size #define STATIONS 5 // Volume step count #define VOLUME_STEPS 21 // WiFi connection tries #define WIFI_CONNECTION_TRIES 10 // GLOBAL VARIABLES static ES8388 dac; Audio audio; String ssid = "asdf"; String password = "1234"; String ssid2 = "qwert"; String password2 = "5678"; uint8_t btn_volume_down_cnt = 0; uint8_t btn_volume_up_cnt = 0; uint8_t btn_station_prev_cnt = 0; uint8_t btn_station_next_cnt = 0; uint8_t connectionCnt = 0; uint8_t stationNumber = 0; const char* stationUrls[STATIONS] = { "http://ors-sn05.ors-shoutcast.at/oe3-q1a", "http://ors-sn05.ors-shoutcast.at/oe1-q1a", "http://ors-sn05.ors-shoutcast.at/fm4-q1a", "http://ors-sn05.ors-shoutcast.at/noe-q1a", "http://ors-sn05.ors-shoutcast.at/wie-q1a" }; String stationNames[STATIONS] = { "OE3", "OE1", "FM4", "Radio NOE", "Radio Wien" }; void setup() { // Initialize debug terminal interface Serial.begin(115200); // Initialize pins digitalWrite(PA_EN, HIGH); // disable power amplifier pinMode(PA_EN, OUTPUT); digitalWrite(LED_WIFI_PIN, HIGH); // disable LEDs digitalWrite(LED_RADIO_PIN, HIGH); pinMode(LED_WIFI_PIN, OUTPUT); pinMode(LED_RADIO_PIN, OUTPUT); pinMode(BTN_VOLUME_DOWN_PIN, INPUT_PULLUP); // button pins used as input pins pinMode(BTN_VOLUME_UP_PIN, INPUT_PULLUP); pinMode(BTN_STATION_PREV_PIN, INPUT_PULLUP); pinMode(BTN_STATION_NEXT_PIN, INPUT_PULLUP); // Initialize WIFI // Set station mode WiFi.disconnect(); WiFi.mode(WIFI_STA); // Connect to first WIFI network WiFi.begin(ssid.c_str(), password.c_str()); Serial.print("Connecting "); do { connectionCnt++; Serial.print("."); delay(500); } while ((WiFi.status() != WL_CONNECTED) && (connectionCnt < WIFI_CONNECTION_TRIES)); if (WiFi.status() == WL_CONNECTED) { Serial.printf("\n"); Serial.printf("Connected WiFi: %s\n", ssid); digitalWrite(LED_WIFI_PIN, LOW); } // In case of connection failures, connect to second WIFI else { connectionCnt = 0; WiFi.disconnect(); WiFi.begin(ssid2.c_str(), password2.c_str()); do { connectionCnt++; Serial.print("."); delay(500); } while ((WiFi.status() != WL_CONNECTED) && (connectionCnt < WIFI_CONNECTION_TRIES)); if (WiFi.status() == WL_CONNECTED) { Serial.printf("\n"); Serial.printf("Connected WiFi: %s\n", ssid2); digitalWrite(LED_WIFI_PIN, LOW); } else { ESP.restart(); } } Serial.print("IP-Address: "); Serial.println(WiFi.localIP()); delay(2000); digitalWrite(LED_RADIO_PIN, HIGH); while (!dac.begin(IIC_DATA, IIC_CLK)) { Serial.println("DAC connection failure!"); delay(1000); } audio.i2s_mclk_pin_select(I2S_MCLK); audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DSIN); audio.setVolumeSteps(VOLUME_STEPS); audio.setVolume((VOLUME_STEPS>>1) + (VOLUME_STEPS>>2)); Serial.printf("Volume [0-%d]: %d\n", VOLUME_STEPS-1, audio.getVolume()); //audio.setTone(low, middle, high); audio.connecttohost(stationUrls[stationNumber]); Serial.printf("Active station: %s\n", stationNames[stationNumber]); digitalWrite(LED_RADIO_PIN, LOW); } void loop() { // Run audio player audio.loop(); // UI handling if (LOW == digitalRead(BTN_VOLUME_DOWN_PIN)) { btn_volume_down_cnt++; if (btn_volume_down_cnt >= BTN_DEBOUNCE_CNT) { btn_volume_down_cnt = 0; uint8_t vol = audio.getVolume(); if (vol > 0) { vol--; } audio.setVolume(vol); Serial.printf("Volume [0-%d]: %d\n", VOLUME_STEPS-1, vol); } } else { btn_volume_down_cnt = 0; } if (LOW == digitalRead(BTN_VOLUME_UP_PIN)) { btn_volume_up_cnt++; if (btn_volume_up_cnt >= BTN_DEBOUNCE_CNT) { btn_volume_up_cnt = 0; uint8_t vol = audio.getVolume(); if (vol < (VOLUME_STEPS-1)) { vol++; } audio.setVolume(vol); Serial.printf("Volume [0-%d]: %d\n", VOLUME_STEPS-1, vol); } } else { btn_volume_up_cnt = 0; } if (LOW == digitalRead(BTN_STATION_PREV_PIN)) { btn_station_prev_cnt++; if (btn_station_prev_cnt >= BTN_DEBOUNCE_CNT) { btn_station_prev_cnt = 0; delay(500); if (stationNumber > 0) { stationNumber--; } else { stationNumber = STATIONS-1; } audio.connecttohost(stationUrls[stationNumber]); Serial.printf("Active station: %s\n", stationNames[stationNumber]); } } else { btn_station_prev_cnt = 0; } if (LOW == digitalRead(BTN_STATION_NEXT_PIN)) { btn_station_next_cnt++; if (btn_station_next_cnt >= BTN_DEBOUNCE_CNT) { btn_station_next_cnt = 0; delay(500); if (stationNumber < (STATIONS-1)) { stationNumber++; } else { stationNumber = 0; } audio.connecttohost(stationUrls[stationNumber]); Serial.printf("Active station: %s\n", stationNames[stationNumber]); } } else { btn_station_next_cnt = 0; } }