UPDATE: Der Leser Andreas Schröder hat das Projekt ein wenig verändert und einige Funktionen Ergänzt. Den Text und Sketch dazu finden Sie am Ende des Beitrags.
Viele Radiosender können als MP3-Stream über das Internet gehört werden. Da der Mikrocontroller ESP32 einerseits WLAN-Fähigkeiten besitzt und andererseits mit zwei eingebauten Digital/Analog-Wandlern den digitalen Datenstrom in ein Analogsignal umwandeln kann, bietet er sich für dieses Projekt als ideale Lösung an. Zusätzlich wird eine Akku-Stromversorgung, ein Audioverstärker, zwei Lautsprecher, ein Display zur Senderanzeige und ein Eingabegerät zur Sendereinstellung benötigt. Abgerundet wird das Ganze mit einem Gehäuse aus dem 3D-Drucker.
Benötigte Hardware
Anzahl | Bauteil | Anmerkung |
---|---|---|
1 |
|
|
1 |
|
|
1 |
|
|
2 |
Widerstände 4.7 kOhm |
|
2 |
Widerstände 22 kOhm |
|
1 |
Widerstand 10 kOhm |
|
1 |
Elko 1000uF / 10V |
|
1 |
|
|
1 |
|
|
1 |
|
|
1 |
|
|
1 |
|
|
1 |
|
|
2 |
Federleisten 19-polig |
|
1 |
Stiftleiste 3-polig |
|
1 |
Stiftleiste 4-polig |
|
1 |
Stiftleiste 5-polig |
|
2 |
Drehknöpfe für 6mm Achse |
|
Mehrere |
Jumperkabel weiblich zu weiblich |
|
1 |
|
|
1 |
|
|
1 |
|
|
diverse |
|
Schaltung
Wichtig!
Sollte der Rotary-Encoder nicht verwendet werden, muss der Pin 34 des ESP32 trotzdem mit dem 10kOhm Widerstand mit 3.3V verbunden werden.
Der ESP32 wird mit den Widerständen und Stiftleisten für die Peripherie auf einer 50x70 mm großen Lochrasterplatte aufgebaut.
Die Abbildung zeigt die Bestückung und die Verdrahtung auf der Unterseite
Verdrahtung
Als erstes wird der Batterieanschluss des Ladereglers mit dem Eingang des DC-DC Step Up Wandlers verbunden. Polung beachten! Der Akku wird über einen geeigneten Steckverbinder ebenfalls mit dem Batterie-Eingang des Ladereglers verlötet. Nun sollte die Ausgangsspannung des Wandlers mit dem blauen Potentiometer auf ca. 5.2 V eingestellt werden. Dazu muss entweder ein Akku angeschlossen oder der USB-Eingang des Ladereglers mit einem USB-Netzgerät verbunden werden.
Wenn die Spannung eingestellt ist, kann der Ausgang des Wandlers mit dem Versorgungseingang des Audioverstärkers verbunden werden. Auf der Rückseite des Verstärkers sind zwei Lötpunkte, wobei der Plus Anschluss über den Schalter des Lautstärkepotentiometer geschaltet wird.
Dieser Anschluss wird zur Versorgung des ESP32 und des Displays verwendet, damit man über das Potentiometer, das Gerät komplett ausschalten kann.
Nun können die Verbindungen zur Steuerplatine auf der Lochrasterplatte hergestellt werden. Am besten werden dazu Jumper-Drähte mit zwei weiblichen Steckern verwendet. Man benötigt eine 3-polige Verbindung vom Audio-Ausgang zum Verstärker, eine 4-polige zum Display und eine 5-polige zum Rotary-Encoder.
Wichtiger Hinweis!
Die Lautsprecher sollten nicht im eingeschalteten Zustand an- oder abgesteckt werden, da induktiver Spannungsspitzen die Verstärkerausgänge zerstören könnten.
Wird das im Blog-Beitrag vorgestellte Gehäuse verwendet, kommt Akku, Laderegler, DC/DC-Wandler und die Steuerplatine auf die Backplane. Die Lautsprecher, der Verstärker, der Rotary-Encoder und das Display kommen auf die Frontplane. Der Deckel wird verwendet, um den Akku zu sichern.
Software
Damit der Sketch kompiliert werden kann, muss die Arduino IDE entsprechend vorbereitet werden. Die Arduino IDE unterstützt standardmäßig eine große Anzahl von Boards mit unterschiedlichen Mikrocontrollern, nicht aber den ESP32. Damit man Programme für diese Controller erstellen und hochladen kann, muss daher je ein Softwarepaket für die Unterstützung installiert werden.
Zuerst müssen Sie der Arduino-IDE mitteilen, wo sie die zusätzlich benötigten Daten findet. Dazu öffnen Sie im Menü Datei den Punkt Voreinstellungen. Im Voreinstellungs-Fenster gibt es das Eingabefeld mit der Bezeichnung „Zusätzliche Boardverwalter URLs“. Wenn Sie auf das Ikon rechts neben dem Eingabefeld klicken, öffnet sich ein Fenster in dem Sie die URL https://dl.espressif.com/dl/package_esp32_index.json für den ESP32 eingeben können. Es sollte für dieses Projekt nicht die Version 2.0.0 oder höher des ESP32 Pakets verwendet werden, da es mit diesen Versionen Probleme im Zusammenhang mit der ESP8266Audio Bibliothek gibt!
Nun wählen Sie in der Arduino IDE unter Werkzeug → Board die Boardverwaltung.
Es öffnet sich ein Fenster, in dem alle zur Verfügung stehenden Pakete aufgelistet werden. Um die Liste einzugrenzen, gibt man im Suchfeld „esp32“ ein. Dann erhält man nur noch einen Eintrag in der Liste. Installieren Sie das Paket „esp32“.
Für das Display benötigen Sie eine Bibliothek, die über die Arduino Bibliotheksverwaltung installiert werden kann. Das ist die Bibliothek „LiquidCrystal I2C“.
Eine weitere Bibliothek wird für den Rotary-Encoder benötigt. Ihr Name ist „AiEsp32RotaryEncoder“.
Kernstück dieses Projekts ist aber die Bibliothek „ESP8266Audio“.
Diese Bibliothek ermöglicht es verschiedene digitale Eingangsströme zu lesen, zu dekodieren und über verschiedene Ausgangskanäle wiederzugeben. Als Eingang, kann der Programmspeicher, der interne RAM ein Filesystem, eine SD-Karte, ein HTTP-Stream oder ein ICY-Stream genutzt werden. Der ICY-Stream wird typisch von Internet-Radios genutzt.
Dekodiert werden können WAV, MOD, MIDI, FLAC, AAC und MP3 Dateien. Für das Webradio wird MP3 benötigt. Die Ausgabe kann schließlich in Speicher, Files oder I2S erfolgen. Eine Besonderheit gibt es für den ESP32. Der I2S Output kann auf den internen Digital-Analog-Wandler ausgegeben werden. An den Ausgangs-Pins des DAW (Pin 25 und Pin 26) steht dann ein analoges Stereosignal zur Verfügung. Dieses Feature wird im vorliegenden Projekt genutzt.
Wenn alle Bibliotheken installiert sind, kann der Sketch kompiliert und auf die Hardware hochgeladen werden.
Der Sketch
#include <WiFi.h> //Includes from ESP8266audio #include "AudioFileSourceICYStream.h" //input stream #include "AudioFileSourceBuffer.h" //input buffer #include "AudioGeneratorMP3.h" //decoder #include "AudioOutputI2S.h" //output stream //library for LCD display #include <LiquidCrystal_I2C.h> //library for rotary encoder #include "AiEsp32RotaryEncoder.h" //esp32 library to save preferences in flash #include <Preferences.h> //WLAN access fill with your credentials #define SSID "************" #define PSK "*************" //used pins for rotary encoder #define ROTARY_ENCODER_A_PIN 33 #define ROTARY_ENCODER_B_PIN 32 #define ROTARY_ENCODER_BUTTON_PIN 34 #define ROTARY_ENCODER_VCC_PIN -1 /* 27 put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */ //depending on your encoder - try 1,2 or 4 to get expected behaviour //#define ROTARY_ENCODER_STEPS 1 //#define ROTARY_ENCODER_STEPS 2 #define ROTARY_ENCODER_STEPS 4 //structure for station list typedef struct { char * url; //stream url char * name; //stations name } Station; #define STATIONS 24 //number of stations in tzhe list //station list can easily be modified to support other stations Station stationlist[STATIONS] PROGMEM = { {"http://icecast.ndr.de/ndr/ndr2/niedersachsen/mp3/128/stream.mp3","NDR2 Niedersachsen"}, {"http://icecast.ndr.de/ndr/ndr1niedersachsen/hannover/mp3/128/stream.mp3","NDR1 Hannover"}, {"http://wdr-1live-live.icecast.wdr.de/wdr/1live/live/mp3/128/stream.mp3","WDR1"}, {"http://wdr-cosmo-live.icecast.wdr.de/wdr/cosmo/live/mp3/128/stream.mp3","WDR COSMO"}, {"http://radiohagen.cast.addradio.de/radiohagen/simulcast/high/stream.mp3","Radio Hagen"}, {"http://st01.sslstream.dlf.de/dlf/01/128/mp3/stream.mp3","Deutschlandfunk"}, {"http://dispatcher.rndfnk.com/br/br1/franken/mp3/low","Bayern1"}, {"http://dispatcher.rndfnk.com/br/br3/live/mp3/low","Bayern3"}, {"http://dispatcher.rndfnk.com/hr/hr3/live/mp3/48/stream.mp3","Hessen3"}, {"http://stream.antenne.de/antenne","Antenne Bayern"}, {"http://stream.1a-webradio.de/saw-deutsch/","Radio 1A Deutsche Hits"}, {"http://stream.1a-webradio.de/saw-rock/","Radio 1A Rock"}, {"http://streams.80s80s.de/ndw/mp3-192/streams.80s80s.de/","Neue Deutsche Welle"}, {"http://dispatcher.rndfnk.com/br/brklassik/live/mp3/low","Bayern Klassik"}, {"http://mdr-284280-1.cast.mdr.de/mdr/284280/1/mp3/low/stream.mp3","MDR"}, {"http://icecast.ndr.de/ndr/njoy/live/mp3/128/stream.mp3","N-JOY"}, {"http://dispatcher.rndfnk.com/rbb/rbb888/live/mp3/mid","RBB"}, {"http://dispatcher.rndfnk.com/rbb/antennebrandenburg/live/mp3/mid","Antenne Brandenburg"}, {"http://wdr-wdr3-live.icecastssl.wdr.de/wdr/wdr3/live/mp3/128/stream.mp3","WDR3"}, {"http://wdr-wdr2-aachenundregion.icecastssl.wdr.de/wdr/wdr2/aachenundregion/mp3/128/stream.mp3","WDR 2"}, {"http://rnrw.cast.addradio.de/rnrw-0182/deinschlager/low/stream.mp3","NRW Schlagerradio"}, {"http://rnrw.cast.addradio.de/rnrw-0182/deinrock/low/stream.mp3","NRW Rockradio"}, {"http://rnrw.cast.addradio.de/rnrw-0182/dein90er/low/stream.mp3","NRW 90er"}, {"http://mp3.hitradiort1.c.nmdn.net/rt1rockwl/livestream.mp3","RT1 Rock"}}; //buffer size for stream buffering const int preallocateBufferSize = 80*1024; const int preallocateCodecSize = 29192; // MP3 codec max mem needed //pointer to preallocated memory void *preallocateBuffer = NULL; void *preallocateCodec = NULL; //instance of prefernces Preferences pref; //instance for rotary encoder AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS); //instance for LCD display LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display //instances for audio components AudioGenerator *decoder = NULL; AudioFileSourceICYStream *file = NULL; AudioFileSourceBuffer *buff = NULL; AudioOutputI2S *out; //Special character to show a speaker icon for current station uint8_t speaker[8] = {0x3,0x5,0x19,0x11,0x19,0x5,0x3}; //global variables uint8_t curStation = 0; //index for current selected station in stationlist uint8_t actStation = 0; //index for current station in station list used for streaming uint32_t lastchange = 0; //time of last selection change //callback function will be called if meta data were found in input stream void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) { const char *ptr = reinterpret_cast<const char *>(cbData); (void) isUnicode; // Punt this ball for now // Note that the type and string may be in PROGMEM, so copy them to RAM for printf char s1[32], s2[64]; strncpy_P(s1, type, sizeof(s1)); s1[sizeof(s1)-1]=0; strncpy_P(s2, string, sizeof(s2)); s2[sizeof(s2)-1]=0; Serial.printf("METADATA(%s) '%s' = '%s'\n", ptr, s1, s2); Serial.flush(); } //stop playing the input stream release memory, delete instances void stopPlaying() { if (decoder) { decoder->stop(); delete decoder; decoder = NULL; } if (buff) { buff->close(); delete buff; buff = NULL; } if (file) { file->close(); delete file; file = NULL; } } //start playing a stream from current active station void startUrl() { stopPlaying(); //first close existing streams //open input file for selected url Serial.printf("Active station %s\n",stationlist[actStation].url); file = new AudioFileSourceICYStream(stationlist[actStation].url); //register callback for meta data file->RegisterMetadataCB(MDCallback, NULL); //create a new buffer which uses the preallocated memory buff = new AudioFileSourceBuffer(file, preallocateBuffer, preallocateBufferSize); Serial.printf_P(PSTR("sourcebuffer created - Free mem=%d\n"), ESP.getFreeHeap()); //create and start a new decoder decoder = (AudioGenerator*) new AudioGeneratorMP3(preallocateCodec, preallocateCodecSize); Serial.printf_P(PSTR("created decoder\n")); Serial.printf_P("Decoder start...\n"); decoder->begin(buff, out); } //show name of current station on LCD display //show the speaker symbol in front if current station = active station void showStation() { lcd.clear(); if (curStation == actStation) { lcd.home(); lcd.print(char(1)); } lcd.setCursor(2,0); String name = String(stationlist[curStation].name); if (name.length() < 15) lcd.print(name); else { uint8_t p = name.lastIndexOf(" ",15); //if name does not fit, split line on space lcd.print(name.substring(0,p)); lcd.setCursor(0,1); lcd.print(name.substring(p+1,p+17)); } } //handle events from rotary encoder void rotary_loop() { //dont do anything unless value changed if (rotaryEncoder.encoderChanged()) { uint16_t v = rotaryEncoder.readEncoder(); Serial.printf("Station: %i\n",v); //set new currtent station and show its name if (v < STATIONS) { curStation = v; showStation(); lastchange = millis(); } } //if no change happened within 10s set active station as current station if ((lastchange > 0) && ((millis()-lastchange) > 10000)){ curStation = actStation; lastchange = 0; showStation(); } //react on rotary encoder switch if (rotaryEncoder.isEncoderButtonClicked()) { //set current station as active station and start streaming actStation = curStation; Serial.printf("Active station %s\n",stationlist[actStation].name); pref.putUShort("station",curStation); startUrl(); //call show station to display the speaker symbol showStation(); } } //interrupt handling for rotary encoder void IRAM_ATTR readEncoderISR() { rotaryEncoder.readEncoder_ISR(); } //setup void setup() { Serial.begin(115200); delay(1000); //reserve buffer für for decoder and stream preallocateBuffer = malloc(preallocateBufferSize); // Stream-file-buffer preallocateCodec = malloc(preallocateCodecSize); // Decoder- buffer if (!preallocateBuffer || !preallocateCodec) { Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize+preallocateCodecSize); while(1){ yield(); // Infinite halt } } //start rotary encoder instance rotaryEncoder.begin(); rotaryEncoder.setup(readEncoderISR); rotaryEncoder.setBoundaries(0, STATIONS, true); //minValue, maxValue, circleValues true|false (when max go to min and vice versa) rotaryEncoder.disableAcceleration(); //init WiFi Serial.println("Connecting to WiFi"); WiFi.disconnect(); WiFi.softAPdisconnect(true); WiFi.mode(WIFI_STA); WiFi.begin(SSID, PSK); // Try forever while (WiFi.status() != WL_CONNECTED) { Serial.println("...Connecting to WiFi"); delay(1000); } Serial.println("Connected"); //create I2S output do use with decoder //the second parameter 1 means use the internal DAC out = new AudioOutputI2S(0,1); //init the LCD display lcd.init(); lcd.backlight(); lcd.createChar(1, speaker); //set current station to 0 curStation = 0; //start preferences instance pref.begin("radio", false); //set current station to saved value if available if (pref.isKey("station")) curStation = pref.getUShort("station"); if (curStation >= STATIONS) curStation = 0; //set active station to current station //show on display and start streaming actStation = curStation; showStation(); startUrl(); } void loop() { //check if stream has ended normally not on ICY streams if (decoder->isRunning()) { if (!decoder->loop()) { decoder->stop(); } } else { Serial.printf("MP3 done\n"); // Restart ESP when streaming is done or errored delay(10000); ESP.restart(); } //read events from rotary encoder rotary_loop(); }
Vor dem Kompilieren muss die SSID und das Passwort für das WLAN gesetzt werden. Am Anfang des Sketchs ist eine Liste mit 24 deutschen Radiostationen. Sie können diese beliebig editieren oder erweitern, um Ihr gewünschtes Programm zu hören. Es können maximal 100 Stationen definiert werden.
Nach dem Hochladen kann das Programm gestartet werden. Mit dem Rotary-Encoder kann durch die Senderliste gescrollt werden. Drückt man den Knopf des Rotary-Encoder, wird der gerade angezeigte Sender als aktiv gesetzt. Diese Auswahl wird im Flash gespeichert, sodass nach einer Stromunterbrechung das Programm wieder mit dem ausgewählten Sender gestartet wird. Die gerade wiedergegebene Station wird im Display durch ein vorangestelltes Lautsprecher-Symbol angezeigt.
Viel Vergnügen mit dem Internet Radio
Update von unserem Leser Andreas Schröder
(danke an dieser Stelle)
Mit geschnittener schwarzer Folie auf weißem Gehäuse sieht es echt gut aus.
Weil das auf- und zuschrauben nicht prickelnd ist, habe ich den Code um folgendes erweitert:
1. einen automatischen AP-Modus bei fehlender WLAN-Verbindung, der dann per Webserver die Zugangsdaten abfragt.
2. Im normalen Betrieb kann die Senderliste über ein Webfrontend gepflegt werden. Hätte hier gerne den Code, Screenshots und die Plotterdatei für die Folie bereitgestellt.
Die WLAN-Konfiguration wird im internen Flash-Speicher vorgehalten. Diese kann per Weboberfläche konfiguriert werden. Der Konfigurationsablauf ist wie folgt:
-
Laden der gespeicherten Login-Daten
-
Versuch der Verbindungs-Herstellung (Display zeigt „WLAN“)
-
Wenn das nicht möglich ist
-
Wechsel in den AP-Modus und erzeugen des WLANs „WEBRADIO“
-
Erwarten der Dateneingabe unter http://192.168.4.1
-
Neustart mit neuen Daten
-
==> Das ganze wiederholt sich, bis eine Verbindung möglich ist
Senderliste
Die Liste der hinterlegten Sender kann über http:// angepasst werden.
288 commentaires
ElPaul
Second situation. I added another station. Sitll reboot.
logs:
…Connecting to WiFi
Connected
Active station http://sluchaj.radiorodzina.pl/RadioRodzinaWroclawLIVE.mp3
sourcebuffer created – Free mem=162584
created decoder
Decoder start…
Guru Meditation Error: Core 1 panic’ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0×400014fd PS : 0×00060230 A0 : 0×800fc494 A1 : 0×3ffb18c0
A2 : 0×00000000 A3 : 0xfffffffc A4 : 0×000000ff A5 : 0×0000ff00
A6 : 0×00ff0000 A7 : 0xff000000 A8 : 0×00000000 A9 : 0×3ffb1cd0
A10 : 0×00000001 A11 : 0×00000000 A12 : 0×3ffe0798 A13 : 0×00000000
A14 : 0×00000000 A15 : 0×00000118 SAR : 0×00000008 EXCCAUSE: 0×0000001c
EXCVADDR: 0×00000000 LBEG : 0×400014fd LEND : 0×4000150d LCOUNT : 0xffffffff
ELF file SHA256: 0000000000000000
Backtrace: 0×400014fd:0×3ffb18c0 0×400fc491:0×3ffb18d0 0×40103a3a:0×3ffb1be0 0×40103a76:0×3ffb1c70 0×400ddaae:0×3ffb1cb0 0×400d12fb:0×3ffb1d50 0×400d32f5:0×3ffb1de0 0×400d2b45:0×3ffb1f30 0×400d29db:0×3ffb1f50 0×400d3ae5:0×3ffb1f70 0×400d1241:0×3ffb1f90 0×400dec31:0×3ffb1fb0 0×4008a392:0×3ffb1fd0
Rebooting…
ElPaul
Hi. Everything works great right after build.
But how to add a station, e.g. http://waw01-03.ic.smcdn.pl/2330-1.mp3
ESP keeps restarting. In my logs I have:
…Connecting to WiFi
Connected
Active station http://waw01-03.ic.smcdn.pl/2330-1.mp3
sourcebuffer created – Free mem=162272
created decoder
Decoder start…
MP3 done
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0×13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0×00,q_drv:0×00,d_drv:0×00,cs0_drv:0×00,hd_drv:0×00,wp_drv:0×00
mode:DIO, clock div:1
load:0×3fff0018,len:4
load:0×3fff001c,len:1216
ho 0 tail 12 room 4
load:0×40078000,len:10944
load:0×40080400,len:6388
entry 0×400806b4
Connecting to WiFi
And such a loop all the time.
Can you help me?
Christian
Mit der Modifikation einer externen 5.02V USB-Stromversorgung am Verstärkereingang habe ich das Radio gebaut. Wegen eines Kompilierungsfehlers (meine Arduino IDE: 1.8.13) musste ich die Sketch-Zeile 237 von „lcd.init()“ auf „lcd.begin()“ ändern damit war auch das Upload problemlos.
Das Radio hat gleich bestens funktioniert: sofort wurde ein Sender gespielt, ok waren die Encoder-Sendersuche & Lautstärkeregulierung (nur das Lautsprechersymbol fehlte am LCD).
Dann wollte ich die Senderliste erweitern („define STATIONS 25“ und unter Beachtung der Syntax). Übersehen habe ich, dass es eine m3u und nicht mp3 URL war: natürlich keine Funktion – und das war es mit dem Radio. Upload des original-Sketch‘s: Keine Reaktion auf den Encoder – aber seither ist das Lautsprechersymbol am Display!
Nach Löschen des Bordverwalters und seinem Link in den Voreinstellungen habe ich alles laut Blog neu installiert: Lautsprechersymbol am LCD, keine Reaktion auf Encoder, nur ein ~1sec periodisches Blinken der ESP32-LED und synchron ein sehr leises tok, tok, aus dem Lautsprecher. Upload des neu vom Blog heruntergeladen Sketch’s, dann auch direktes copy and paste vom Blog: wie gehabt.
Alle Uploads funktionierten mit der Änderung in Zeile 237. Laut Serial Monitor ist die WIFI Verbindung ok, aber ich bekomme einen „Guru Meditation Error: Core1…“ Trotz Recherche fange ich demit nichts an (ich bin Laie; Kopien des Upload Loggings und des Seriellen Monitors sind unten – und für mich unverständlich).
Habe ich den ESP32 abgeschossen? Der USB zwischen PC und ESP32 hat 5+/-0.05V, der Strom schwankt zwischen ca. 70 und 150 mA. Dann habe ich den Funktionsgenerator-Sketch am ESP32 geladen, der funktioniert problemlos am seibst gebauten Hackster-Oszilloskop. ESP32 doch nicht abgeschossen? Dann wieder Bordverwalter gelöscht, neu installiert, Webradio-Sketch geladen: wie gehabt. Alle Verbindungskabel und Platine gemessen, ok. Verkabelung des Webradio am Steckbrett nachgebaut: wie gehabt. Wieder Funktionsgenerator geladen und Oszilloskop meiner Enkelin gezeigt: ok!
Was kann ich tun? Bitte um einen Ratschlag!
Christian
Protokoll Hochladen:
Der Sketch verwendet 876682 Bytes (66%) des Programmspeicherplatzes. Das Maximum sind 1310720 Bytes.
Globale Variablen verwenden 40280 Bytes (12%) des dynamischen Speichers, 287400 Bytes für lokale Variablen verbleiben. Das Maximum sind 327680 Bytes.
esptool.py v3.0-dev
Serial port COM11
Connecting…..
Chip is ESP32-D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: c8:c9:a3:c8:70:98
Uploading stub…
Running stub…
Stub running…
Changing baud rate to 921600
Changed.
Configuring flash size…
Auto-detected Flash size: 4MB
Compressed 8192 bytes to 47…
Writing at 0×0000e000… (100 %)
Wrote 8192 bytes (47 compressed) at 0×0000e000 in 0.0 seconds (effective 2978.9 kbit/s)…
Hash of data verified.
Compressed 18656 bytes to 12053…
Writing at 0×00001000... (100 %)
Wrote 18656 bytes (12053 compressed) at 0×00001000 in 0.2 seconds (effective 988.4 kbit/s)…
Hash of data verified.
Compressed 876800 bytes to 493948…
Writing at 0×00010000... (3 %)
Writing at 0×00014000... (6 %)
Writing at 0×00018000... (9 %)
Writing at 0×0001c000… (12 %)
Writing at 0×00020000... (16 %)
Writing at 0×00024000... (19 %)
Writing at 0×00028000... (22 %)
Writing at 0×0002c000… (25 %)
Writing at 0×00030000... (29 %)
Writing at 0×00034000... (32 %)
Writing at 0×00038000... (35 %)
Writing at 0×0003c000… (38 %)
Writing at 0×00040000... (41 %)
Writing at 0×00044000... (45 %)
Writing at 0×00048000... (48 %)
Writing at 0×0004c000… (51 %)
Writing at 0×00050000... (54 %)
Writing at 0×00054000... (58 %)
Writing at 0×00058000... (61 %)
Writing at 0×0005c000… (64 %)
Writing at 0×00060000... (67 %)
Writing at 0×00064000... (70 %)
Writing at 0×00068000... (74 %)
Writing at 0×0006c000… (77 %)
Writing at 0×00070000... (80 %)
Writing at 0×00074000... (83 %)
Writing at 0×00078000... (87 %)
Writing at 0×0007c000… (90 %)
Writing at 0×00080000... (93 %)
Writing at 0×00084000... (96 %)
Writing at 0×00088000... (100 %)
Wrote 876800 bytes (493948 compressed) at 0×00010000 in 9.3 seconds (effective 757.1 kbit/s)…
Hash of data verified.
Compressed 3072 bytes to 128…
Writing at 0×00008000... (100 %)
Wrote 3072 bytes (128 compressed) at 0×00008000 in 0.0 seconds (effective 1536.0 kbit/s)…
Hash of data verified.
Leaving…
Hard resetting via RTS pin…
Protokoll Serial Monitor:
Rebooting…
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0×13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0×00,q_drv:0×00,d_drv:0×00,cs0_drv:0×00,hd_drv:0×00,wp_drv:0×00
mode:DIO, clock div:1
load:0×3fff0018,len:4
load:0×3fff001c,len:1216
ho 0 tail 12 room 4
load:0×40078000,len:10944
load:0×40080400,len:6388
entry 0×400806b4
Connecting to WiFi
…Connecting to WiFi
…Connecting to WiFi
…Connecting to WiFi
Connected
Guru Meditation Error: Core 1 panic’ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0×400014dc PS : 0×00060c30 A0 : 0×800ddf51 A1 : 0×3ffb1ef0
A2 : 0×000000ff A3 : 0×000000fb A4 : 0×000000ff A5 : 0×0000ff00
A6 : 0×00ff0000 A7 : 0xff000000 A8 : 0×800ddd55 A9 : 0×3ffb1ec0
A10 : 0×00000000 A11 : 0×00000000 A12 : 0×00000000 A13 : 0×00000000
A14 : 0×00000000 A15 : 0×00000002 SAR : 0×00000006 EXCCAUSE: 0×0000001c
EXCVADDR: 0×000000ff LBEG : 0×4000c2e0 LEND : 0×4000c2f6 LCOUNT : 0×00000000
ELF file SHA256: 0000000000000000
Backtrace: 0×400014dc:0×3ffb1ef0 0×400ddf4e:0×3ffb1f00 0×400d0ed5:0×3ffb1f20 0×400d120c:0×3ffb1f80 0×400debfa:0×3ffb1fb0 0×4008a392:0×3ffb1fd0
Andreas Wolter
@Andreas Schröder: gerne nehmen wir die Ergänzung zum Projekt als Update mit in den Beitrag rein.
Ich habe Ihnen dazu eine Mail geschickt. Wir werden die Daten dann hier zur Verfügung stellen.
Grüße,
Andreas Wolter
AZ-Delivery Blog
holm / Christian Müller
Vielen Dank für das nette Projekt! Es ist eine gute Erweiterung unseres Tonuino Hörspielboxbastelprpjekts für Kinder.
Andreas Schröder
> Hätte hier gerne den Code, Screenshots und die Plotterdatei für die Folie bereitgestellt … Bei Interesse einfach melden :)
Ich wäre interessiert! Möchten Sie sich bitte bei mir melden? Gerne auf einem der Wege die unter https://mueller.network aufgelistet sind. Vielen Dank im Voraus!
Andreas Schröder
Super Projekt – nettes kleines Webradio mit Bauteilen aus der Schublade (und dem Drucker). Habe schon zwei davon gebaut. Mit geschnittener schwarzer Folie auf weißem Gehäuse sieht es echt gut aus.
Weil das auf- und zuschrauben nicht prickelnd ist, habe ich den Code um folgendes erweitert:
1. einen automatischen AP-Modus bei fehlender WLAN-Verbindung, der dann per Webserver die Zugangsdaten abfragt.
2. Im normalen Betrieb kann die Senderliste über ein Webfrontend gepflegt werden.
Hätte hier gerne den Code, Screenshots und die Plotterdatei für die Folie bereitgestellt … Bei Interesse einfach melden :)
Danke für das schöne Projekt :)
Nico
@Thomas:
Das Problem mit dem “…iskey”… hatte ich auch.
Die Abhilfe bestand bei mir darin, die aktuellen esp32 board-downloads zu machen, wie im Artikel beschrieben.
Achim
Hallo Zusammen,
Ich habe das Radio nun auch fertig gebaut, allerdings noch für mich ein paar kleine Änderungen vorgenommen.
Da ich das Radio nicht Mobil brauche, habe ich ein anderes Gehäuse an die Bauteile angepasst.
https://www.thingiverse.com/thing:5336137
Da habe ich dann wie beschrieben einen externen Verstärker benutzt und die NF-Ausgänge vom ESP
zu den Chinch Buchsen mit zwei Kondensatoren 4,7µF 16V gleichspannungsmäßig entkoppelt.
Das funktioniert ganz gut und durch den Verstärker und größere Boxen hat das Radio einen richtig guten Klang.
Bei den MP3-Streams habe ich, sofern vorhanden die High Streams genommen.
Das Problem mit fehlerhaften Streams habe ich auch beobachtet, einige Radiosstreams sind
offenbar nicht für dieses Projekt geeignet, muss man halt Testen ;-)
Vielen Dank an den Autor für dieses super Projekt.
Achim
Philippe D
Lieber Herr, Ich hatte viel Spaß beim bauen Internetradio mit dem ESP32. Alles funktioniert gut.
Ich erwähnte den Verstärker, weil er zufiel Parasiten produzierte. Eventuell wäre ein Trenntransformator sinnvoll. Verweise?
Alle Radios, die Sie geben, funktionieren gut und werden schnell gefunden.
Auf der anderen Seite funktionieren meine französischen Webradio-Favoriten trotz vieler Versuche nicht, oder sogar manchmal für einige, erst nach langem Warten.
Radio Classic, France Culture, France Inter, France Musique, TSF Jazz und Radio Swiss Jazz. sind meine Radiofavoriten.
Können Sie mir in diesem Punkt bitte weiterhelfen.
Andererseits, wenn das Programm beim Start die zuvor verwendete Station nicht findet, sucht es immer wieder und startet auch neu (reboot).
At this time, Das rotierende xxx ist nicht effektiv, um ein anderes funktionierendes Radio zu finden. Es ist Schade.
Vielen Dank im Voraus für Ihre Hilfe und für dieses sehr interessante Programm. Herzliche Grüße.
Zum beispiel : von http://fluxradios.blogspot.com/p/flux-radios-francaise.html#Nationales%20DEF
https://www.radioswissjazz.ch/fr/reception/internet
http://radioclassique.ice.infomaniak.ch/radioclassique-high.mp3
http://direct.franceculture.fr/live/franceculture-midfi.mp3
Gerald Lechner
Eine Versorgung über den USB-Anschluss des ESP32 ist ohne Verdrahtungsänderung möglich. Allerdings ist dann der Ein- Aus-Schalter am Lautstärke-Potentiometer ohne Funktion. Eine andere Möglichkeit wäre am 5V Eingang des Verstärkers statt des StepUp-Converters eine externe 5V-Spannungsquelle (z.B. USB Netzgerät) anzuschließen. Dann funktioniert der Ein- Aus-Schalter.
Siggi
Hallo,
schönes Projekt. Eine Frage:
Wenn man das Ganze ohne Akku, Laderegler und Step up Converter aufbauen möchte:
Reicht es dann denn ESP32 über die USB Buchse mit Spannung zu versorgen, oder muss dann an der Verdrahtung noch etwas geändert werden?
Gruß SP
Sigi
Hallo, wollte vorab mal das Gehäuse drucken, aber bei allen Teilen gibt es Probleme. Es wird zwar etwas gedruckt, paßt aber irgendwie nicht zur Vorlage. Beim Vorderteil zb. wird nach einiger Zeit der Druck ohne Filamentnachschub ausgeführt! Habe einen Artillery Sidewinder X1 der an sich sehr gut funktioniert.
Gerald Lechner
@Julian. Der ESP32 hat gegenüber dem ESP8266 einen gravierenden Vorteil. Die Ausgabe des Streams egal ob Analog oder I2S erfolgt über direkten Speicherzugriff auf Hardwarebasis im Hintergrund. Die Software muss nur dafür sorgen, dass ausreichend Daten im Buffer sind die kontinuierliche Ausgabe des Streams wird nicht beeinflusst. Beim ESP8266 erfolgt die Ausgabe an RX über die Programmsoftware, daher können parallell laufende Aktionen im Programm zu kurzen Unterbrechungen des Streams führen, was als Knack Geräusch gehört wird.
Andreas Wolter
@Gerhard Spinker: “invalid conversion from int to …” bedeutet, dass ein Datentyp nicht korrekt verwendet wurde. Da das Programm aber problemlos laufen sollte, vermute ich, dass etwas mit der Installation der Arduino IDE bzw. des ESP Cores nicht korrekt ist. Ich schreibe ihnen dazu eine E-Mail.
Grüße,
Andreas Wolter
Julian
Ich hatte hier vor einiger Zeit einige ESP8266 d1 minis erworben. Damit geht das im Prinzip auch (Output über RX). Hatte dafür einen PAM8302A Verstärker benutzt (einfacher, nur mono) und ein OLED Display per I2C.
Will ich aber im Loop beispielsweise die Uhrzeit aktualisieren oder Senderinformationen anzeigen, gibt es bei jedem print()/sendBuffer() eine Störung auf dem Audiosignal (knacken, kurze pause).
Das habe ich auch mit Kondensatoren und Widerständen am PAM-Eingang nicht weg bekommen.
Norbert
Hallo
habe alles bestellt und aufgebaut. Funktionierte sofort nach dem ersten einschalten. Stationen können gewählt werden . Aber nach einer nicht bestimmbarer Zeit ist keine Wiedergabe mehr vorhanden. Entweder Stille oder ein 50 Hz Brummton. Die Bedienelemente funktionieren nicht mehr, der Reset Taster reagiert nicht. Erst ein “Power Reset” bringt Abhilfe, aber leider nur für kurze Zeit. Wo liegt der Fehler??
Bitte um Hilfe.
Gruß
Norbert Schrills
Gerhard Spinker
Vielen Dank für Ihre schnelle Antwort.
Die von Ihnen angegebene Voreinstellung ist bereits vorhanden gewesen. Viele Sketche mit dem ESP32 habe ich bereits benutzt.
In diesem speziellen Fall bekomme ich bei der Kompilierung in Zeile 76 die Fehlermeldung:
invalid conversion from ‘int’ to ‘backlighPol’ [-fpermissive]
Leider reichen meine Kenntnisse nicht aus um damit etwas anzufangen.
Mir ist aufgefallen, dass in der Bibliothek-Verwaltung nachdem ich im Suchfenster ESP32 eingebe, der espressive Eintrag nicht erscheint.
Vielleicht hilft diese Info bei der Lösung der Probleme.
Ich bin sehr an diesem Programm interessiert und würde es sehr gerne zum Laufen bringen.
Vielen Dank für Ihre Mühe.
Mit freundlichen Grüßen
Andreas Wolter
@Gerhard Spinker: für die Einrichtung des ESP32 Arduino Cores in der Arduino IDE folgen Sie bitte diesem Link: https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html
In den Voreinstellungen der Arduino IDE tragen Sie diesen Link in als Boardverwalter URL ein: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Anschließend müssen Sie unter Werkzeuge → Board → Boardverwalter nach ESP32 suchen und installieren. Sollten Sie bereits etwas installiert haben und eine andere Boardverwalter-URL verwendet haben, empfehle ich eine Deinstallation, bevor Sie es neu installieren.
Danach müsste als Board unter ESP32 Arduino “ESP32 Dev Modul” ausgewählt werden, wenn Sie den hier im Beitrag verlinkten ESP32 NodeMCU verwendet haben.
Grüße,
Andreas Wolter
AZ-Delivery Blog
Gerhard
Guten Tag,
nachdem ich die Bauteile erhalten habe muss ich feststellen, dass ich den heruntergeladenen Sketch nicht kompilieren kann.
Ich weiß auch gar nicht welches Board ich im Bereich Werkzeuge eintragen kann. Esp32 Node MCu gibt es in meinem Bordverwalter nicht.
Trage ich andere ESP32 ein bekomme ich immer wieder Fehlermeldungen beim Versuch den Sketch zu kompilieren.
Z.B. Zeile 12 Fehler Preferences.h wird beanstandet. No such file or directory
Was mache ich falsch?
Mit freundlichen Grüßen
Gerhard Spinker
Gerald Lechner
Hallo Andy, eventuell ist der Kontrast nicht richtig eingestellt. Kann am Potentiometer auf der Adapter-Platine eingestellt werden.
Gerald Lechner
Eine Liste von Stream URLs findet man unter
https://hendrikjansen.nl/henk/streaming3.html#du
Aber Achtung! Es funktionieren nur MP3 Streams und da leider auch nicht alle.
Rene Van Doorn
Tolles Projekt was ich mit Modifikationen (eher ein grafisches Interface wo ich auch Wetterdaten darstellen werde und dem ganzen als Wecker aufbauen) sicherlich selbst auch bauen werde. Nur eine Frage, wo finde ich einem Übersicht der http-Adressen der Streams. Ich werde sicherlich einige andere Sender wählen.
Dake René
Gunther Waage
Ergänzung:
Ich hatte vergessen zu erwähnen, daß ich für den Anschluß des Displays, welches eine Betriebsspannung von 5 V hat, noch zur Anpassung der Pegel des I2C-Signals einen Level-Converter zwischen ESP und Display geschaltet habe.
Gunther Waage
Nachdem ich heute von AZ-Delivery den Drehregler erhalten habe (ohne ihn funktioniert es nicht)
konnte ich ohne Probleme die ersten Sender am NF-Ausgang vorerst über einen anderen Verstärker hören (empfangen kann man hier vielleicht nicht sagen!). Auch das Umschalten auf einen anderen Sender funktioniert wie beschrieben. Ebenfalls konnte ich die Senderliste erfolgreich bearbeiten.
Recht vielen Dank für diesen gut beschriebenen Beitrag.
Andy
Hallo!
Wer kann helfen? Das LCD Display zeigt bei mir nur Karos in der oberen Zeile an.
Danke im voraus
Thomas
Hallo,
beim compilieren kommt die Fehlermeldung Zeile 245 ´class Preferences´ has no member named ´isKey´.
Gibt es ein Problem mit der Preferences.h ?
Beste Grüße, Thomas
Tom
Hallo Gerald,
danke für den richtigen Link – da hab ich dummerweise nicht drauf geachtet und auch keinen anderen Link probiert.
Leider klappt’s aber auch mit diesem oder einem anderen nicht wirklich. Wie es scheint, ist das “Wemos D1 Mini ESP32”-Board dafür nicht geeignet. Auch mit der Widerstandsbeschaltung und einem nachgeschalteten NF-Verstärker kommt bisher kein brauchbares Audio-Signal zustande.
Gruß
Tom
Gerald Lechner
Hallo Tante Rolf,
Die Warnung:
WARNUNG: Bibliothek LiquidCrystal_I2C behauptet auf avr Architektur(en) ausgeführt werden zu können und ist möglicherweise inkompatibel mit Ihrem derzeitigen Board, welches auf esp32 Architektur(en) ausgeführt wird.
kommt daher, dass in den Properties zu dieser Bibliothek angegeben wurde, dass sie nur auf AVR Architektur funktioniert, was aber nicht stimmt. Diese Warnung kann ignoriert werden.
Gerald Lechner
Hallo T.Gelhard,
Preferences.h ist Teil des ESP32 Package und sollte automatisch mit diesem installiert werden.
Bei mir liegt das File auf:
C:\Users\…\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\Preferences\src
Gerald Lechner
Hallo Tom,
mit dem Pin für DT hast du natürlich recht. Bei meinem ESP32-Modul war der Aufdruck am Modul G23 statt G33.
Nun zum Stream von Bayern 1. Es muss der MP3 stream und nicht der AAC Stream verwendet werden. Die richtige URL lautet daher http://dispatcher.rndfnk.com/br/br1/nbopf/mp3/low damit sollte es dann funktionieren.
Gruss Gerald
Gerald Lechner
Hallo Konrad, der Kondensatore kommt zwischen +5V und Masse am ESP32. Ich habe den Kondensator in der Schaltung hinzugefügt. Er ist aber nicht unbedingt notwendig.
Tom
Hallo!
DT an G23 ist wohl ein Typo – lt. Zeichnung müsste DT an G33 führen – auch lt. Code:
#define ROTARY_ENCODER_BUTTON_PIN 34
Ich hab mich auch dran schon versucht. Mangels eines ESP32 NodeMCU Borad habe ich ein Mini D1 ESP32 benutzt. Die nötigen Pins sind an dem Borad ja auch alle vorhanden.
In der Arduino IDE hab ich dazu in der Bordverwaltung auch “WEMOS D1 Mini ESP32” konfiguriert. Kompilieren und Laden auf’s Borad läuft (bis auch ein paar Warnings) tadellos durch.
Nach dem Reset steht kann ich auch erfreulicherweise diese Log-Ausgabe sehen:
Connecting to WiFi
…Connecting to WiFi
…Connecting to WiFi
…Connecting to WiFi
Connected
Active station http://dispatcher.rndfnk.com/br/br1/nbopf/aac/low
sourcebuffer created – Free mem=155840
created decoder
Decoder start…
Leider erhalte ich aber an DAC-Pins 25 bzw. 26 noch kein Audio-Signal.
Noch hab ich keine weitere Peripherie am Borad angeschlossen – weder den Drehgeber, das LCD , noch den Audio-Verstärker, da ich diese Teile noch nicht habe. Die Log-Ausgabe sieht aber so aus, als ob es schon funktionieren sollte.
Kann es an der noch fehlenden Beschaltung am DAC liegen? Mit dem Oszi kann ich an den Pins lediglich einen ca. 22us langen Rechteckpuls feststellen, der mit einer Frequenz von rund 85Hz ansteht.
Um einen Defekt des Bords möglichst auschliessen zu können, hab ich es mit einem zweiten versucht, allerdings mit identischem Ergebnis.
Gruß
Tom
T.Gelhard
Hallo
Wo bekomme ich die datei ( Preferences.h ) her?
Gerald Lechner
Hallo oldman, der Rotary-Encoder wird wie folgt angeschlossen: GND an Masse, + an 3.3V (nicht an 5V, das würde die Eingänge des ESP32 beschädigen), SW an G34 und über einen 10kOhm Widerstand auf 3.3 V, DT an G23 und CLK an G32. Für DT und CLK sind Pullup-Widerstände auf der Platine des Rotary-Encoders vorhanden.
fred
“Eine Frage: Wo in der Schaltung ist der Kondensator drin?”
Das ist im Doppeldiagramm der Lochrasterplatine erkennbar. Der Kondensator ist dort zwischen den Anschlüssen “GND” und “+5V” verbunden.
Tanterolf
Also bei mir läuft der Code nicht durch.
Da hapert es am LiquidCrystal_I2C.
Beste Grüße
Tante Rolf
oldman
Rotary encoder nur +V?
Konrad
Hallo,
Scheint ein Klasse Projekt für schlechtes Wetter zu sein. Bin schon dabei das genau mal zu prüfen.
Eine Frage: Wo in der Schaltung ist der Kondensator drin? Auf den Bildern kann ich Ihn gut erkennen, aber leider bin ich nicht Elekroniker genug, um zu wissen wie die Schaltung dafür sein muss.
Danke im Nachgang.
Konrad