Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery

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

ESP32 Development Board

 

1

Audio-Verstärker 3W

 

1

Lautsprecher

 

2

Widerstände 4.7 kOhm

 

2

Widerstände 22 kOhm

 

1

Widerstand 10 kOhm

 

1

Elko 1000uF / 10V

 

1

3.7V Akku 2000mAh

 

1

Laderegler

 

1

DC-DC Step Up Converter

 

1

LCD-Display mit I2C Interface

 

1

Drehgeber Encoder

 

1

Lochrasterplatte 50x70

 

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

Gehäuse Frontteil aus dem 3D-Drucker

 

1

Gehäuse Rückseite aus dem 3D-Drucker

 

1

Deckel zur Akku-Sicherung aus dem 3D-Drucker

 

diverse

Befestigungsschrauben 2.2mm

 

 

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.

 verstärker unterseite

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.

 backplanezusammenbau

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“.

esp32 lib
Für das Display benötigen Sie eine Bibliothek, die über die Arduino Bibliotheksverwaltung installiert werden kann. Das ist die Bibliothek „LiquidCrystal I2C“.

Liquid crystal lib

Eine weitere Bibliothek wird für den Rotary-Encoder benötigt. Ihr Name ist „AiEsp32RotaryEncoder“.

Rotary encoder lib 

Kernstück dieses Projekts ist aber die Bibliothek „ESP8266Audio“.

 audio lib

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();

} 

Sketch zum Herunterladen

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.

Fertiges Gerät

Viel Vergnügen mit dem Internet Radio

Beitrag als PDF

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.

WLAN

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.

 

Sketches Download

 

Plotterdatei (Silhouette-Format)

DisplaysEsp-32Projekte für anfängerStromversorgung

239 Kommentare

Gerald Lechner

Gerald Lechner

@ElPaul. Die erste URL funktioniert auch im Browser nicht (Fehler zu viele Weiterleitungen) Die zweite URL funktioniert bei mir aber sher schlecht.

ElPaul

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

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

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 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Gerald Lechner

Hallo Andy, eventuell ist der Kontrast nicht richtig eingestellt. Kann am Potentiometer auf der Adapter-Platine eingestellt werden.

Gerald Lechner

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

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

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

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

Andy

Hallo!
Wer kann helfen? Das LCD Display zeigt bei mir nur Karos in der oberen Zeile an.
Danke im voraus

Thomas

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

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

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

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

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

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

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

T.Gelhard

Hallo
Wo bekomme ich die datei ( Preferences.h ) her?

Gerald Lechner

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

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

Tanterolf

Also bei mir läuft der Code nicht durch.
Da hapert es am LiquidCrystal_I2C.

Beste Grüße
Tante Rolf

oldman

oldman

Rotary encoder nur +V?

Konrad

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

Kommentar hinterlassen

Alle Kommentare werden von einem Moderator vor der Veröffentlichung überprüft

Empfohlene Blogbeiträge

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery