2. Advent: Neues Internetradio mit ESP32 und MAX 98357A - AZ-Delivery

After the Blog post Internet-radio with dem ESP32 a great echo hervoWe are now presenting a second variant, which has received numerous improvements and enhancements. The most significant change is the use of the I2S digital amplifier MAX98357A instead of the analog amplifier. The display was to 4 lines with 20 characters vergröures. Next to the station just played wou will find Date and time, and the current volume are displayed. The two lower lines show the Information about the current program that is sent along with the audio stream. The volumercontrol takes place justas well as the station selection via a rotary encoder. The configuration can be made, as with the improved version of Mr. Schröder (see update in the old post), via a Browser can be done. The channel list can also be changed and extended in this way.extended. Since some URLs are notplayable, a URL can now be tested via the browser configuration before it is saved.rt is saved. The supply via battery has been omitted, because the power consumption was too high. Additionally, a firmware update can be done via WLAN (Over The Air = OTA).


Required hardware

Number Component Note

1

ESP32 Development Board


2

I2S digital amplifier with MAX98357A


1

Loudspeaker set of 2


1

Resistor 470 kOhm


1

Resistor 10 kOhm


1

Elko 1000uF / 10V


1

DC-receptacle


2

Rotary encoder Encoder


1

breadboard 50x70


2

Female connector 19-pole


2

Female connectors 7-pole

 

1

Male header 3-pole


1

Male header 4-pole


2

Male header 5-pole


2

Rotary knobs for 6mm axis


Multiple

Jumper cable female to female


1

Bult housing from 3D printer


1

Case bottom from 3D printer

 


Circuit

 circuit

The following table shows the use of the Pins of the ESP32

Device

Designation

ESP32

Amplifier left

LRC

25

BCLK

26

DIN

27


GAIN

GND


SD

+5V

 

GND

GND

VIN

+5V

Amplifier right

LRC

25

BCLK

26


DIN

27


GAIN

GND


SD

+5V via 470kΩ


GND

GND


VIN

+5V

LCD display

GND

GND


VCC

+5V


SDA

21


SCL

22

Encoder volume

CLK

14


DT

13


SW



+

+3.3V


GND

GND

Encoder Transmitter selection

CLK

33


DT

32


SW

35 3.3V above10kΩ


+

+3.3V


GND

GND

Supply

+5V

VIN


GND

GND

 

The ESP32 is assembled with the resistors and pin headers for the peripherals on a 50x70 mm breadboard. For the two 7-pin female connectors are used for the two amplifier modules.


The image shows the assembly and the wiring on the bottom side


The image shows the realization on a breadboard 50 x 70 mm

The wiring could also be done by a one-sided printedcircuit printed on one side. Only the red marked connection must be realized via a free connection. Three wire bridges are used for the I2S bus.
The two amplifier modules are plugged into the two 7-pin female connectors. The two rotary encoders and the display are connected with jumper wire cable F2F to the corresponding pin headers on the breadboard. The loudspeakers are connected to the screw terminals of the amplifier modules.




Software

The sketch was split into several parts for clarity. For this purpose a function is used, which is provided by the Arduino IDE. If there are other ".ino" or ".h" files in the same folder besides the main sketch, which has the same name as the folder, the compiler appends them to the main sketch in alphabetical order.
Since the whole code has become very large, it is only available for download.

Sketch for download

The ZIP file contains the folder with all related files. It has to be unpacked into the working directory of the Arduino IDE (mostly documents\Arduino\). In the following, the individual parts are briefly described. A detailed description can be found as comments in the code.

  • ino: This is the main sketch. Global variables and data structures are defined.
    • setup() after initializing the serial interface the configuration data is read from the preferences. Then the setup functions of the individual program parts are called, with the exception of web server and OTA. The connection to the local WLAN is established. If the connection was not successful, information about the configuration is shown on the display. If the connection is successful, the real-time clock is initialized and playback of the last station listened to is started. Now the setup for web server and OTA can also be called up.
    • loop() first checks if there are OTA requests and then if there are requests for the web server. It checks if the connection to the WLAN still exists. If the connection exists, the audio stream and the two encoders are checked for events. Once per minute the display of the time is updated. If the connection was interrupted for more than 5 minutes, the ESP32 is restarted.
  • ino: In this part all functions related to the audio streams are implemented.
    • setup_audio() prepares the system. Buffer and stream output are initialized.
    • audio_loop() checks the status of the audio stream.
    • MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
      is called whenever new metadata is available in the received stream. Metadata of type "Title" will be shown on the display.
    • stopPlaying() stops playing the stream and releases the associated resources.
    • bool startUrl(String url) Starts playing a stream from a given URL. If the start is not successful, false is returned.
    • setGain() sets the volume to the value of the global variable currentGain.
  • ino: Contains functions to control the display and the definition of special characters like speaker and German umlauts.
    • setup_display() initializes the display and creates the special characters in the display RAM.
    • String extraChar(String text) replaces the German umlauts in the passed UTF8 text with the corresponding special character code.
    • showStation() shows the name of the current radio station in the second line of the display. The display starts at position 2 and is truncated to 18 characters. If the current station is also the active station, the speaker symbol is displayed at position 0.
    • displayMessage2(uint8_t line, String msg) the given string is displayed in two lines starting from the given line. Both lines will be deleted before. If the string has more than 20 characters, a line break occurs. The second line will be truncated after 20 characters.
    • displayDateTime() The first line displays the date and time. In the rightmost position the current volume is displayed in percent.
    • displayMessage(uint8_t line, String msg) the given string will be displayed in the given line. The line will be deleted before. The string will be truncated to a maximum of 20 characters.
    • displayClear() deletes all four lines.
    • clearLine(uint8_t line) deletes the specified line
  • ino: Controls the volume control with a rotary encoder.
    • gain_loop() checks if the value of the rotary encoder has changed. If it has, the new volume value is saved and set.
    • IRAM_ATTR readGainISR() Interrupt handling for the encoder
    • setup_gain() starts the encoder, registers the interrupt routine, sets the limits and the current value as default.
  • h: Contains the HTML pages for the web server. With the command sequence
    const char MAIN_page[] PROGMEM = R"=====(
    any text.........
    )=====";

    an arbitrary text can be inserted directly as a constant into the program memory. This is very handy for HTML pages, as they can then be designed and tested outside the IDE. The present pages use jQuery, Ajax and JavaScript. The advantage of Ajax for interactive pages is that when changes are made, only the changed part of the page is updated. Three HTML constants are defined.
    • OPTION_entry a template for entries in the radio station selection list
    • MAIN_page the main page with configuration and maintenance of the station list
    • CONFIG_page Page for entering the access data if the ESP32 is in access point mode for initial configuration.
  • ino: Here you can find the functions to update the firmware via WLAN.
    • setup_ota() the host name and password are set. Then callback functions are registered.
    • ota_onStart() is called at the start of an OTA upload. The display is cleared and a corresponding message is shown in the first line
    • ota_onEnd() is called after the upload is finished. A corresponding message is displayed in the third line.
    • ota_onProgress(unsigned int progress, unsigned int total) is called at regular intervals during the upload and provides information about the progress. The second line of the display shows the progress in percent.
    • ota_onError(ota_error_t error) is called when an error occurs. The error message is then displayed in the fourth line.
  • ino controls the station selection with a rotary encoder
    • rotary_loop() checks if the value of the rotary encoder has changed. If it has, the next station from the station list is displayed. If the button on the encoder is pressed within 10 seconds, the new station is switched to. If the button is not pressed, there is no change and the current station is displayed again.
    • IRAM_ATTR readRotaryISR() Interrupt handling for the encoder
    • setup_rotary() starts the encoder, registers the interrupt routine, sets the limits and the current value as default.
  • ino: defines a program memory constant with the default transmitter list.
    • setup_senderlist() fills the station list in RAM with the station list from the preferences. If there is no station list there, the default station list is used.
  • ino: Contains the setup and functions to respond to http requests.
    • setup_webserver(): Registers the individual functions to handle http requests and starts the server on port 80.
    • webserver_loop() it is checked if there are new requests.
    • handleRoot() handles a request for the main page. If there is a connection to the local WLAN, the main page is sent to the client. If the ESP32 is in access point mode for the basic configuration, the configuration page is transmitted. In this case, any existing parameters must also be processed in order to save the access data or trigger a restart.
    • sendStations() responds to the Ajax command with the URL /cmd/stations. Sends the list of stations as HTML optionlist. This list is then built into the dropdown element via javascript in the client.
    • setAccessData() responds to the Ajax command with the URL /cmd/setaccess. The configuration data SSID, PKEY and NTP server are stored in the preferences.
    • getAccessData() responds to the Ajax command with the URL /cmd/getaccess. The configuration data SSID, PKEY and NTP server are sent as response. The end of line is used as the separator.
    • getStationData() responds to the Ajax command with the URL /cmd/getstation. The ID of the desired station is expected as argument. The name, URL and enable flag of the specified station is sent as response. The end of line is used as separator.
    • setStationData() responds to the Ajax command with the URL /cmd/setstation. The ID of the desired station is expected as argument. If the ID is valid, the data passed as argument for the name, the URL and the enable flag will be stored in the station list.
    • testStation() responds to the Ajax command with the URL /cmd/teststation. The URL to be tested is expected as an argument. An attempt is made to start the replay of the specified URL. If the attempt is not successful, it switches back to the current station and responds with "ERROR".
    • endTest() responds to the Ajax command with the URL /cmd/endtest. The test is terminated by starting the playback of the current station.
    • restart() responds to the Ajax command with the URL /cmd/restart. The ESP32 is restarted.
  • ino: Contains the function to connect to the local WLAN or to provide an access point if a connection is not possible.
    • boolean initWiFi(String ssid, String pkey) Attempts to connect to the local WLAN using the specified credentials. If no SSID is specified or the connection attempt fails, an access point is started. This access point can then be used to access the configuration page from a browser at the address 192.168.4.1.

In order to compile the sketch, the Arduino IDE must be prepared accordingly. The Arduino IDE supports a large number of boards with different microcontrollers by default, but not the ESP32. Therefore, in order to be able to create and upload programs for these controllers, a software package for support must be installed.

First you need to tell the Arduino IDE where to find the additional data it needs. To do this open in the menu File open the item Preferences. In the Preferences window there is the input field called "Additional board administrator URLs". If you click on the icon to the right of the input field, a window will open where you can enter the URL https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json can be entered.

Now select the board management in the Arduino IDE under Tool → Board.

A window will open listing all available packages. To narrow down the list, you enter "esp32" in the search field. Then you get only one entry in the list. Install the package "esp32". If the package was already installed, please check if you have the latest version.

 

For the display you need a library that can be installed via the Arduino library management. This is the library "LiquidCrystal I2C" by Marco Schwartz in version 1.1.2.

 

Another library is needed for the rotary encoder. Its name is "AiEsp32RotaryEncoder" by Igor Antolic in version 1.4.0.

But the core of this project is the library "ESP8266Audio" by Earle F. Philhower in version 1.9.7.

This library allows to read and decode different digital audio streams and play them back over different output channels. As input, the program memory, the internal RAM', a file system, an SD card, an HTTP stream, or an ICY stream can be used. The ICY stream is typically used by Internet radios.
WAV, MOD, MIDI, FLAC, AAC and MP3 files can be decoded. MP3 is required for web radio. Finally, the output can be in memory, files or I2S.

When all libraries are installed, the sketch can be compiled and uploaded to the hardware.

Attention. Since the sketch is composed of numerous parts, compiling can take a long time, especially the first time. In the preferences "Compiler Warnings" should be set to "none", because the LCD library will give a warning by mistake

Commissioning

At the first startup there are no preferences yet. Therefore no connection to the local WLAN can be established. An access point with the SSID "webradioconf" without password is started. A connection to this access point can now be established with a smartphone, for example. Afterwards, the configuration page can be called up in a browser via the address 192.168.4.1.

After the restart, the connection to the local WLAN should be established successfully. The playback of station 0 from the default list (NDR2) should start with a volume of 50%. The volume encoder can be used to set the gain. Changes are saved in the preferences so that the same volume is set the next time the device is switched on. The other encoder can be used to select a station from the list. When turning the encoder, the second line of the display shows the name of the station. By pressing the head on the encoder, the currently displayed station becomes the current station and playback starts. This value is also stored in the preferences. At the next start, the last selected station is automatically played back. If the button on the encoder is not pressed within 10 seconds, the display jumps back to the current station.

Configuration and editing of the station list

The configuration page should be accessible via the URL http://webradio/. In the upper part the access data and the NTP server can be changed. The changes will not take effect until the "Save" button has been clicked.
With the button "Restart" a restart can be triggered.

The drop-down list contains all stations of the station list. Selectable stations have a black dot in front of the name. In the form below, the data for the selected station is displayed and can be changed. If the "Use" check mark is not set, the station cannot be selected in the device. Since some URLs do not work, a new URL should be tested with the "Test" button. Clicking this button starts the playback of the URL on the device. If playback does not work, the device immediately switches back to the current station and displays a message. If playback is possible, a box with a button is displayed. Clicking on this button closes the box and ends the test. The current station is played again. The "Change" button can be used to permanently change the changes for the selected station.

Firmware update via OTA

To update the program it is not necessary to open the device and establish a USB connection. In the Arduino IDE you should see the following entry at the ports.

You can now upload a sketch via this port. For protection, the password "radioupdate" must be entered when prompted. Since the serial port cannot be used, messages are shown on the display.

Notes

The ESP32 has a CPU with two cores. With Internet Radio the web data stream must be read from the Internet via the http protocol. This is done in the system thread running on core 0. The application must decode the received stream and write it to the buffer, from which the data is then output via DMA without CPU intervention. The decoding is done in the application thread running on core 1. If additional CPU time is now used for display and encoder, short interruptions occur that can be heard acoustically when the encoders are turned.

A power supply via the USB bus of the ESP32 module is possible. The supply via the external input is only a recommendation.

The 3D object to the console housing is arranged in such a way that 3D printing is possible without support structures. The link to the print files can be found in the component list at the beginning of the article.

Have fun with the radio!

Contribution as PDF

DisplaysEsp-32Specials

132 commenti

Siegfried

Siegfried

@ Torsten Krämer bei mir gibt es solch Reaktion, wenn der 10 k Widerstand am GPIO 35 zum 3,3 V Anschluss fehlt (Encoder Sender SW muss ja nicht unbedingt angeschlossen sein)

Torsten Krämer

Torsten Krämer

Hallo zusammen,

lange Geschichte kurz: Ich habe ein Stottern auf der Audioausgabe. grob alle 200ms Aussetzer und Neustart. Ich habe sowohl 5102A, als auch die Verstärker aus dem Artikel probiert. Kann das am ESP32 Modul liegen? Gerne Tipps aller Art. Danke Euch….

Manfred Süsens

Manfred Süsens

Ich habe das Internet-Radio in den Versionen V1 und V2 nachgebaut. Aber nicht um damit Internet-Radio zu hören, denn ich habe 4 Internet Radios von AUNA, die wunderbar funktionieren und einen guten Klang haben. Allerdings haben die auch einen Nachteil: Alle Radios holen ihre Daten selbst, d.h. bei gleichen eingestellten Sender werden die Daten viermal geholt!
Aber ich habe auch eine FRITZ!BOX, die einen internen Media-Server hat. Also könnte der jeweilige Sender doch einmal geholt werden und dann im Haus verteilt werden. Funktioniert mit den AUNA-Internet-Radios auch prima, wenn ich dort auf Media-Server umschalte. Allerdings verlieren die AUNA-Radios beim AUS/EIN-schalten die Einstellung auf Media-Server und ich muss mich nach Einschalten wieder durch alle Menüs durchhangeln.
Das wollte ich dann mal mit den ESP32-Internet Radios probieren. Also habe ich einfach die URL vom Deutschlandfunk mit der URL meines Media-Server ersetzt (http:\\192.168.X.X:49200\ST\AUDIO\DLNA-1-0\icecast.ndr.de\ndr\ndr1niedersachsen\oldenburg\mp3\128\stream.mp3).
Leider mit mäßigen Erfolg. Es gibt eine Verbindung und auch Daten, allerdings gibt es auch nach kurzer Zeit jede Menge Aussetzer und Krächzer.
Hat vielleicht ein wissender eine Ahnung woran das liegt?

Achim Kleine

Achim Kleine

Ich habe mich mal am Script von Andreas Kühn versucht und die Anzeige auf ein ILI9341 Anzeigemodul angepasst,
welches in verschiedenen Größen erhältlich ist, da auch ich das 1,8" ewas klein finde.

Das ILI9341 hat ein paar Vorteile zum ST7735, die wichtigste ist, das die Auflösung höher ist mit 320×240 Pixeln.
Desweiteren ist es in verschiedenen Dispaygrößen erhältlich, sodaß ein wechsel auf ein größeres Display bei gleicher Auflösung einfach ist.
Bedingt durch die höhere Auflösung habe ich ein wenig mit den Schriften gespielt, wodurch nun bis zu fünf Zeilen im Radiotext angezeigt werden.
Ich habe das farblich ein wenig umgestaltet, die Anzeige für den Senderwechsel erfolgt nun durch Farbwechsel in der Senderanzeige.
Außerdem habe ich die Prozentuale Anzeige für die Lautstärke aus der Zeitanzeige herausgenommen und durch einen farbigen Balken
unter der Radiotextanzeige ersetzt, welcher aber noch in kleiner Schrift mit der Ziffernanzeige hinterlegt ist.

Da ich kein Arduinoprofi bin gibt es vielleicht schönere Lösungen für die Änderungen.
Desweiteren habe ich ein Gehäuse für den 3D Druck entworfen, welches in meinem Fall auf der Stereoanlage steht und diese mit der Musik versorgt.
Es sind Frontplatten für das 1,8" und ein 2,2" ILI Display dabei.

@ Gerald Lechner
Bei Interesse kann ich Ihnen die Dateien zum Veröffentlichen zukommen lassen

p.s. Wenn der Aufbau mit dem mal Steckbrett nicht funktioniert, messt mal die verwendeten Drahtbrücken durch, ich habe eine Woche mit Fehlersuche
verbracht, bis das ILI funktionierte, Fehlerquelle waren zwei defekte Brücken ……

Gerd

Gerd

Danke für die neue Version.

Mein Wunsch ist “Ein Knopf für Alles”
Ich meine damit, mit nur einem Rotary Encoder
a) den Sender zu ählen, ein OK-Druck startet den Stream (ist es ja bereits)
b) nun sollte der Rotary Encoder beim drehen die Lautstärke sofort einstellen
erst ein OK-Druck führt zurück zur Senderwahl.
c) Als Zukunftswunsch evtl. ein langer OK-Druck für Deep Sleep

Mangels Know-how kann ich diese Änderungen nicht durchführen,
vielleicht interessiert dieser Wunsch aber jemanden der helfen kann.

Gerd

Uwe Schmidt

Uwe Schmidt

Hallo,

vielen Dank für dieses Projekt.
Hat auch auf Anhieb geklappt. Nur einen Fehler hab ich- ich bekomme noch auf einen Lautsprecher den Ton. Wenn ich den anderen Verstärker anstecke( den mit dem 470k Widerstand) dann gibt es nur lautes Geschäpper. Die Verdrahtung hab ich mehrmals überprüft, auch die Verstärker getauscht – ohne Ergebnis.

Man kann schon mit einem Lautsprecher leben, aber es muss ja funktionieren. Am Sketch kann es wohl kam liegen, das ging alles ohne Probleme.

Vielleicht hat ja noch jemand eine Idee was das sein könnte, ich währe jedenfalls sehr dankbar.

Beste Grüße Uwe

Konrad

Konrad

@Horst Mayer:
1. Das mit dem 2 zeiligen Display mit Laufschrift würde mich sehr interessieren. Bitte gerne hier posten. Vielen Dank.
2. Versorgung mit „Battery Expansion Shield 18650“: Auch das würde mich brennend interessieren. Das Produkt habe ich mir auch zugelegt; – bin aber als selbst definierter Anfänger nicht so richtig klar gekommen damit. Auf Nachfrage an AZ, mehr Daten / Hintergrundinfo dazu zu erhalten habe nicht so viel erhalten. Auch hier gerne mal eine Verdrahtung, gerne mit Erläuterung. Großes Danke auch hier.

@Hr. Lechner: In wieweit macht es nicht schon Sinn, den Flash nun mit zu verwenden? Testweise habe ich es schon mit Erfolg gemacht. ( Siehe auch fipsok.de). Das Hochladenden des Programmes dauert inzwischen bei mir ca. 15 Minuten (im Wiederholungsfall – also nicht beim ersten Mal; – da ist es ja noch länger)! Bei nur kleineren Änderungen im Programm macht das jetzt schon keine Freude

Einfach ein Supertolles Projekt. Und wenn das Ganze dann mit SD-Card (mp3 -Player), Wecker und Touchscreen final gemacht wird…… Woh!!

Wenn jemand dazu dann noch die slt Datei für einen 3D Druck zur Verfügung stellt, würde dich schon von Schwarmintelligenzprojekt reden.

Grüße

Konrad

Thommy

Thommy

@ Achim Agster: Vielleicht hat dein Display eine andere I2C Adresse? Standard bei “display.ino” ist 0×27 diesen Wert kannst du ändern.
Mein Display hatte z.B. die Adresse 0×3f.
Du kannst aber auch testen welche Adresse dein Display hat. Dazu bitte folgendes Script auf deinen ESP32 flashen und dann im Serialmonitor nachschauen. Die Adresse notieren, dann in der display.ino eintragen und den Radiocode flashen:

// -—————————————————-
// i2c_scanner
//
// Version 1
// This program (or code that looks like it)
// can be found in many places.
// For example on the Arduino.cc forum.
// The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
// Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26 2013
// V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
// by Arduino.cc user Krodal.
// Changes by louarnold removed.
// Scanning addresses changed from 0…127 to 1…119,
// according to the i2c scanner by Nick Gammon
// https://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
// As version 4, but address scans now to 127.
// A sensor seems to use address 120.
// Version 6, November 27, 2015.
// Added waiting for the Leonardo serial communication.
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include

void setup()
{
Wire.begin();

Serial.begin(9600); while (!Serial); // Leonardo: wait for serial monitor Serial.println(“\nI2C Scanner”);

}

void loop()
{
byte error, address;
int nDevices;

Serial.println(“Scanning…”); nDevices = 0; for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print(“I2C device found at address 0x”); if (address<16) Serial.print(“0”); Serial.print(address,HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print(“Unknown error at address 0x”); if (address<16) Serial.print(“0”); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println(“No I2C devices found\n”); else Serial.println(“done\n”); delay(5000); // wait 5 seconds for next scan

}

Gerald Lechner

Gerald Lechner

@Achim Agster: Nachdem es beim Kompilieren keinen Fehler gab, nehme ich an, die LCD-Library ist die richtige. Ich habe vielmehr die Vermutung, dass der Kontrast nicht richtig eingestellt ist. Drehen Sie mal am blauen Potentiometer auf der I2C Adapter Platine.

Siegfried

Siegfried

@ Achim Agster: in der Bibliotheksverwaltung gibt es von Marco Schwartz die Version 1.1.2 „LiquidCristal I2C“ , die hatte ich genutzt

Gruß Siegfried

Achim Agster

Achim Agster

Hallo Herr Lechner,

danke für das geniale Projekt. Ich suche schon länger ein minimalistisches Internetradio – dieses hier finde ich klasse.

Ich hab das Radio schrittweise aufgebaut. Momentan ist alles angeschlossen bis auf die beiden Encoder.
Es steigt schon mal kein Rauch auf ;-)
Es kommt sogar Musik und die Webseite meldet sich wie gewünscht.
Ich hab’ nur ein Problem: Das Display zeigt nichts an.
Lötfehler habe ich ausgeschlossen.

Ich verwende ide Library LiquidCrystal I2C von Frank de Brabander Version 1.1.2 (So die Anzeige im Library Manager)
Installiert habe ich die Library manuell nach Download von Github.
Die hat es mir angezeigt als ich nach der von Marco Schwartz gesucht habe. Das repository ist allerdings umgezogen zu John Rickman.
Verwende ich die richtige Library ?

Woran kann es noch liegen ?

Horst Mayer

Horst Mayer

Zunächst ein herzlicher Dank an Herrn Gerald Lechner für dieses tolle Projekt. Vom Sound her ist das mit dem externen I2S Verstärker ja ein ganz gewaltiger Fortschritt gegenüber den internen 8 Bit DACs in der ersten Ausführung.
Aber da es immer noch etwas zu verbessern und weiter zu entwickeln gibt, die folgenden Anmerkungen:
1. „Die Versorgung über Akku wurde weggelassen, da der Stromverbrauch zu hoch war.“ kann ich nicht nachvollziehen. Statt den beiden Modulen „Laderegler und DC/DC Step Up Converter“ habe ich zur Versorgung ein „Battery Expansion Shield 18650“ (gibt es auch bei AZ-Delivery) verwendet. Das vereint beide Funktionen und das Radio spielt damit Stundenlang ohne aufladen.
2. Entgegen dem bzw. zusätzlich zu dem Verdrahtungsplan habe ich den ungenutzten Push Button (SW) des Lautstärke Encoders an den naheliegenden P12 für eine spätere Verwendung angeschlossen. Später habe ich sogar fest gestellt, dass dies in der SW in gain.ino gar auch schon mit „#define ROTARY_ENCODER_BUTTON_PIN 12“ vorgesehen ist. Mit dem high Pegel des nicht gedrückten Push Buttons bootet der ESP32 aber nicht. P12 ist dafür also nicht geeignet und kann zu einer langen Fehlersuche führen.
3. Der externe PullUp nach 3V3 ist bei meinen Rotary Encodern schon auf der Trägerplatine vorhanden. Der externe PullUp ist dann entbehrlich. Doppelt schadet hier aber nicht.
4. Mit der Frage nach dem Pegel-Übergang vom ESP32 mit 3,3 V nach dem Display mit 5 V hat Herr Klaas nicht ganz Unrecht. Für reine Digitalsignale mit TTL-Pegel von 3,3 V nach 5 V ist das unkritisch, wie Herr Lechner in seiner Antwort direkt danach ausgeführt hat. Hier ist der Pegelübergang aber am I2C-Bus. Da wird der I2C Port-Expander am Display mit 5 V und der ESP mit 3,3 V betrieben und die die SDA-Leitung am I2C ist bidirektional. Genau genommen gehört da ein I2C Level Shifter rein. Ich bin das Problem dadurch umgangen, dass ich ein 3,3 V Display verwende und daher alles an 3,3 V betreibe.
5. Die Lautstärkeanzeige mit
lcd.print(" “);
lcd.setCursor(18,0);
lcd.print(g);
zeigt die ein oder zweistellige Lautstärke unschön linksbündig an.
Schöner geht es wie folgt:
if (g < 10) lcd.print(”0");
lcd.print(g);
Also bei Werten von 0 bis 9 ein führende Null oder, wer will, kann auch ein Leerzeichen nehmen, und dann einstellig die Lautstärke und 2 Stellige Werte 1:1 auf die beiden Stellen.
6. Die Drehrichtung des Sender Rotary Encoders ist falsch herum. Eine Rechtsdrehung führt zu niedrigeren statt (wie zu erwarten) höheren Stationsplätzen. Ändern kann man dies durch Vertauschen der Leitungen an den Pins 32 und 33 am ESP32 oder durch entsprechende Anpassung der defines für ROTARY_ENCODER_A und ROTARY_ENCODER_B in rotary.ino (hier ebenfalls 32 und 33 untereinander tauschen)
7. Vermutlich durch Rundungsfehler erzeugt die Lautstärke 1 genauso wie Lautstärke 0 absolute Stille im Lautsprecher. Abhilfe: „float v = curGain / 100.0;“ –> „float v = (curGain + 1) / 100.0;“ in audio.ino.
8. Der String „char title64; //character array to hold meta data message“ im Hauptprogramm ist zu vergrößern, z.B. zu verdoppeln, da die ausgestrahlten Meldungen teilweise länger als 64 Zeichen sind. Bei BR24 habe ich schon über 100 gesehen.
9. Die im Programmlauf asynchrone Ausgabe von Datum und Uhrzeit alle 60 s ist unglücklich ausgeführt und kann dazu führen, dass die angezeigte Zeit um fast eine Minute nachgehen kann. Wird die Zeitanzeige gerade in der 59. Sekunde aktualisiert, bleibt diese falsche Zeit über die Folgeminute falsch stehen. Hier wäre eine Synchronisation auf den Wechsel der „echten“ Zeit angebracht, also die Ausgabe immer dann, wenn ein Wechsel der Minute erkannt wird. Das führt auch nur zu einer Ausgabe pro Minute, aber eben zum richtigen Zeitpunkt.
10. Da 2 Zeilen zu je 20 Zeichen, insgesamt also 40 Zeichen nicht reichen und der Zeilenumbruch beim nächst gelegenen Leerzeichen auch kritisch ist, habe ich die Textausgabe als Laufschrift in einer Zeile realisiert. (dies u.a. weil ich ein 2 zeiliges Display verwendet habe). In der oberen Zeile: Lautstärke, Lautsprechersymbol und dann die Station im Wechsel mit der Zeit. Und in der zweiten Zeile die Textmeldung, bis 20 Zeichen statisch bis zum nächsten Wechsel, bei mehr als 20 Zeichen als Laufschrift. Die Codeänderungen dazu sind etwas zu umfangreich für diese Aufzählung. Auf Wunsch kann ich sie aber in einem separaten Posting nachreichen.
Unabhängig von dieser Aufzählung habe ich kein Gehäuse gedruckt, sondern nach alter Väter Sitte (Bohrer, Fräser etc.) das Radio in eine alte 5 ¼ Diskettenbox aus Kunststoff eingebaut und damit einen Look ähnlich einem alten Autoradio erreicht. (rechts und links ein Drehknopf auf der schmalen Seite und dazwischen das Display) Ein Bild davon kann ich hier wohl nicht posten, aber gerne zur Veröffentlichung am Ende des Beitrags zur Verfügung stellen.
Gruß Horst Mayer

Siegfried

Siegfried

Hallo an Alle,

ich habe das Radio mit dem Display nach Andreas Kühn aufgebaut. Jetzt möchte ich mit einen größeren Display probieren und dazu müssen die Einstellungen in der Display.ino geändert werden. Hat dieses schon mal jemand gemacht und kann Unterstützung geben, an welchen Stellen und welche Werte.

Vielen Dank an Gerald und Herrn Kühn.

Siegfried

Achim Kleine

Achim Kleine

@ Andreas

Habe das nun auch mit dem PCM5102 umgesetzt, funktioniert bei mir, wenn auf der Bestückungsseite die Brücke SCK gesetzt wird.
Gab dazu im Netz eine Beschreibung, da auf der Platine noch mehr Brücken auf der Rückseite sind hab ich das mal hier kopiert.

https://raspberrypi.stackexchange.com/questions/76188/how-to-make-pcm5102-dac-work-on-raspberry-pi-zerow

“On the front (component side) there is one pair of pads which may be bridged to tie the SCK (system clock) low.
This will force the PCM510x to generate the system clock using its internal PLL.
You may bridge these pads to remove the need for an external SCK or connect the SCK pin to ground (0V).
The Raspberry Pi does not supply a system clock so this will be required to connect to the Raspberry Pi.

On the back (non-component side) there are 4 sets of 3 pads for the 4 functions:

FLT – Filter select : Normal latency (Low) / Low latency (High) DEMP – De-emphasis control for 44.1kHz sampling rate: Off (Low) / On (High) XSMT – Soft mute control(1): Soft mute (Low) / soft un-mute (High) FMT – Audio format selection : I2S (Low) / Left justified (High)

The centre pad is connected to the corresponding pin. Each of these function pads may be bridged with solder either high or low (or the pins connected to +3.3V / 0V).
(My board is supplied with 1, 2 & 4 bridged low and 3 bridged high, i.e. normal latency filter, 44.1kHz de-emphasis disabled, soft-mute not asserted, I2S audio format.)

The normal filter is an FIR with good response, delaying the signal by approx. 500us (at 44.1 kHz) which should be fine. The fast filter is an IIR with slightly poorer response and delays the signal approx. 80us. Very few (if any) audio sources have pre-emphasis applied so DEMP should be low. The XSMT pin would allow muting of the output via a GPI (if the solder bridge was removed).
Raspberry Pi supports I2S bitstream so FMT should be low."

Bei meinem Board waren alle Rückseitigen Brücken korrekt gesetzt, einzig SCK auf der Vorderseite musste gelötet werden.

Gerald Lechner

Gerald Lechner

@Andreas: Es sollte mit dem PCM5102 auch funktionieren. Nachdem Sie die Definition der Pins geändert haben, nehme ich an, dass Sie die den PCM5102 dann auch entsprechend angeklemmt haben. Datenleitung an Pin 25 rechts/links Umschaltung an Pin 26 und den Bittakt an Pin 27.
Bezüglich Titel/Interpret.
Im File audio.ino gibt es die Funktion MDCallback, die Metadaten im Stream findet und falls es ein Titel ist die Nachricht in die globale Variable title speichert. Außerdem muss das Flag newTitle auf true gesetzt werden. In der Hauptschleife im File webradio_MAX.ino wird dieses Flag abgefragt. Falls es gesetzt ist, wird die Funktion displayMessage2(2,title) aufgerufen, die den Titel ab der dritten Zeile anzeigt. Diese Funktion befindest sich im File display.ino. Es könnte auch sein, dass die Station, die Sie edmpfangen keine Metadaten mitsendet. Aber ich nehme an, dass Sie verschiedene Stastionen versucht haben.

Andreas

Andreas

Hi Gerald,
super Nummer mit der neuen Soft.
Leider macht der PCM5102 den ich nutze, nur geschtotter.
So angeklemmt: #define DOUT 25, #define LRCLK 26, #define BCLK 27.
Leider kein Titel und Interpret im Display.

Gruß
Andreas

Konrad S.

Konrad S.

Hallo Herr Lechner,

absolut tolles Projekt. Speziell mit der überarbeiteten Codevariante. Die kurzen “Abhacker” sind nun weg! Toll.
Auch dass man die Senderliste umnummerieren kann; – Klasse!

Gestern habe ich von meinem Schwager dann den 3D Druck bekommen. Alles passt jetzt. Wahnsinn. Ich bin total begeistert.
Es gibt somit von meiner Seite fast nichts mehr zu verbessern (eigentlich Schade).

Kleiner Hinweis: OTA habe ich mal ausprobiert. So richtig hat es nicht geklappt. Auch wenn ich das Passwort “radioupdate” eingegeben habe; – nach einer gefühlten halben Stunde mit Warten habe ich abgebrochen und habe das Radio aufgeschraubt und über die übliche USB und serielle Schittstelle hochgeladen; ohne Probleme. Hätte ich noch länger warten sollen?

Weitere Frage: Gibt es zum TFT Display auch eine 3D Druck Datei? Würde mich auch interessieren.

Bezüglich der Platine habe ich schon eine email an Sie geschrieben.

Danke aus dem Süden der Republik

Konrad

Riemi

Riemi

Hat noch jemand eine alternative für die Lautsprecher um noch bessere Qualität zu haben?

Siegfried

Siegfried

Hallo in die Runde,

gibt es hier einen „Mitbauer“, der das Design auf eine Platine zaubern wird und diese evtl. auch produzieren lässt. Ich hab die Variante mit dem 1,8“ Display und würde mich da finanziell beteiligen.

Rutscht gut ins Jahr 23

Vielen Dank an Gerald und das AZ Team

Ulrich Klaas

Ulrich Klaas

Hallo,
mich haben noch ein paar Sachen beim Tuning gestört und deshalb habe ich rotary_loop() etwas geändert.
1) Wenn ein Sender läuft und man sucht durch wählt den Sender dann aber nicht an springt die Anzeige ja wieder auf den aktiven Sender.
Das ist schön. Nur wenn man wieder tunen will geht es diesmal nicht von dem eingestellten Sender weiter sonder von da wo man beim
letzten mal aufgehört hat.
2) Hat man mehrere deaktivierte Sender oder halt am Ende der Liste viele noch nicht definierte so wird der nächste aktivierte angezeigt nur man
muss halt n-mal weiter drehen (also über alle deaktivierten) bis sich die Anzeige wieder ändert.
3) Da ist auch ein Bug drin : Will man rückwärts über einen deaktivierten Sender drehen hängt die Anzeige ! Man kann nur noch vorwärts drehen.
So sieht meine modifizierte rotary_loop() aus :

//handle events from rotary encoder
//called from main loop

uint8_t changedByCode = false;

void rotary_loop()
{
int16_t v;
uint8_t disabledStations;
int16_t richtung;

disabledStations = false; if (changedByCode) { // Value changed by my changes (uk) do not retrigger and clean event rotaryEncoder.encoderChanged(); changedByCode = false; } else { //don’t do anything unless value changed if (richtung = rotaryEncoder.encoderChanged()) { Serial.print(“Encode changed. Richtung:”);Serial.println(richtung); uint8_t cnt = 0; //overflow counter, prevents endless loop if no station is enabled v = rotaryEncoder.readEncoder(); while ((!stationlist[v].enabled) && (cnt < 2)){ disabledStations = true; if ((richtung > 0) && (richtung != STATIONS)) // STATIONS means from 0 to 45 backwards ! { v++; if (v >= STATIONS){ v=0; cnt++; } } else { v—; if (v < 0) { v = STATIONS – 1; cnt++; } } } //set new currtent station and show its name if (v < STATIONS) { curStation = v; showStation(); if (disabledStations) { // found di//no event to handle. rotaryEncoder.encoderChanged() triggers on thissabled stations → correct rotary to jump over rotaryEncoder.setEncoderValue(curStation); //set encoder to the found station changedByCode = true; //no event to handle. rotaryEncoder.encoderChanged() triggers on this } 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(); rotaryEncoder.setEncoderValue(actStation); //start tuning from here again changedByCode = true; //no event to handle. rotaryEncoder.encoderChanged() triggers on this } //react on rotary encoder switch if (rotaryEncoder.isEncoderButtonClicked()) { //set current station as active station and start streaming actStation = curStation; pref.putUShort(“station”,curStation); if (!startUrl(String(stationlist[actStation].url))) { //if start fails we switch back to station 0 actStation = 0; startUrl(String(stationlist[actStation].url)); } //call show station to display the speaker symbol showStation(); } }

}

klaus Treutler

klaus Treutler

@Gerald Lechner Danke für die Erläuterung der Funktion zu Metadaten. Ja, ich habe verschiedene Stationen durchprobiert; nirgendwo melden sich Titel o.ä. in Zeile 3 und 4 des Displays oder im Terminal

Gerald Lechner

Gerald Lechner

@Ulrich Klaas: Bei der Verbindung von 3.3V und 5V Logik ist die Übertragungsrichtung wichtig. Ausgang 3.3 V → Eingang 5V kein Problem. Die 5V Logik erkennt ein High Signal ab etwa 2V. Ausgang 5V → Eingang 3.3V erfordert einen Levelshifter, da die 5V vom Ausgang den 3.3V Eingang schädigen würden. Beim Display werden nur Daten vom Mikrocontroller zum Diplay übertragen, daher keine Levelshifter erforderlich.
@klaus Treutler: Die Warnmeldung hat nichts damit zu tun, sie resultiert aus einem Fehler im Properties File der Bibliothek. Um Ihrem Problem auf die Spur zu kommen, müssen Sie die betroffenen Funktionen überprüfen. Im File audio.ino gibt es die Funktion MDCallback, die Metdaten im Stream findet und falls es ein Titel ist die Nachricht in die globale Variable title speichert. Außerdem muss das Flag newTitle auf true gesetzt werden.
In der Hauptschleife im File webradio_MAX.ino wird dieses Flag abgefragt. Falls es gesetzt ist, wird die Funktion displayMessage2(2,title) aufgerufen, die den Titel ab der dritten Zeile anzeigt. Diese Funktion befindest sich im File display.ino.
Es könnte auch sein, dass die Station, die Sie edmpfangen keine Metadaten mitsendet. Aber ich nehme an, dass Sie verschiedene Stastionen versucht haben.

Ulrich Klaas

Ulrich Klaas

Hallo,
in der Schaltung wird ein 5V Display verwendet. Der ESP arbeitet aber mir 3.3V Logik.
Normalerweise schalte ich da einen Levelshifter zwischen. Sehen Sie da kein Problem ?

Ulrich Klaas

klaus Treutler

klaus Treutler

@Gerald Lechner Danke für die schnelle Antwort und die Erläuterungen. Den Tipp zur Korrektur bzgl der Pins 35/36 hatte ich schon erledigt (ich verwende einen analogen Verstärker), ebenfalls die output-Parameter eingesetzt. Bei meinen Displays bleiben die Zeilen 3 und 4 unbespielt; habe zwei LCD´s ausprobiert mit dem gleichen Verhalten. Kann es an dieser Meldung liegen, die ich beim Kompilieren bekomme. 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.
Die Zeileln 1 und 2 zeigen korrekt Datum, Zeit und auch das Lautsprechersymbol nebst Stationsname.
Danke schonmal und viele Grüße

Gerald Lechner

Gerald Lechner

@Rainer: Die Fehlermeldung bezieht sich auf den WiFi Secure Client, der im Sketch nicht verwendet wird. Es wurde also der Sketch vor dem Kompilieren verändert. Der Secure Client wird benötigt wenn statt http https verwendet werden soll, was in diesem Projekt nicht vorgesehen ist. Laut Fehlermeldung wurde das für SSL notwendige Zertifikat nicht richtig konfiguriert.

Rainer

Rainer

@Gerald Lechner

Vielen Dank für die schnelle Antwort. Ich bin allerdings erst heute dazu gekommen, Ihre Hinweise zu überprüfen.

1. Den Sketch habe ich erneut heruntergeladen und entpackt.
2. Ich verwende das ESP32 Package mit der Version 2.0.5
3. Als Board habe ich ESP32 Dev Module ausgewählt.

Nach erneutem Compilieren mit dem neu heruntergeladenem Skatch erhalte ich jetzt folgende Fehlermeldung:

c:\Users\Rainer\Documents\Arduino\libraries\WiFiClientSecure\src\ssl_client.cpp:23:4: error: #error “Please configure IDF framework to include mbedTLS → Enable pre-shared-key ciphersuites and activate at least one cipher”
exit status 1

Compilation error: exit status 1

Ich bin mit meiner Kunst am Ende.
Ich bitte um Hilfe.

Viele Grüße
Rainer

Ralf Naumann

Ralf Naumann

Ich will ja nicht meckern, aber es ist schon merkwürdig, das die Verlinkung mit den Bauteilen zum Beispiel einen anderen ESP 32 Baustein zum Kauf anbietet als in der Strucktur der Platine und in der Schaltung dann verbaut wurde. Da ich den in der Schaltung verbauten Baustein jetzt erst nachkaufen muss, kann ich mich noch nicht über die Schwierigkeiten beim Laden der Sketche aus der zip Datei aufgetreten sind, auslassen und auf Hilfe hoffen. Wenn ich über diese Tatsachen schlecht denken würde, könnte man in gewisser Weise , an Abzocke denken. Ich bin für Verbesserungen offen. Es sollte dann aber konsequent alles überarbeitet werden. Dann sollte so etwas nicht passieren.
Vielen Dank

Siegfried

Siegfried

@Gerald: ich hatte gedacht, ich kann über Webradio auch den gerade laufenden Sender durch einen in der Sendeliste ändern und den dann hören

Das Neueintragen von Sendern in die Webradioliste funktioniert.

Gruß

Gerald Lechner

Gerald Lechner

@Siegfried: Um einen neuen Sender einzugeben gehen Sie wie folgt vor. Zuerst in der Dropdown-Liste den Sendeplatz auswählen auf dem der neue Sender gespeichert werden soll. Dann die URL mit der des neuen Senders überschreiben und die URL testen. Zum Schluss den Namen nach Wunsch ändern und den Button “Ändern” klicken.

Siegfried

Siegfried

Hallo Herr Lechner,

aufgebaut und es läuft. Allerdings kann ich im „Webradio“ die Sender zwar testen, aber wenn ich den getesteten Sender nutzen möchte, öffnet sich ein Fenster mit „ok“ und „schließen“ . Aber ok ist nicht hinterlegt ( bei mir) .
Ich nutze ein IPad.

Mit freundlichen Grüßen

Siegfried

Rainer Hoffmann

Rainer Hoffmann

@Gerald Lechner
Danke für die schnelle Antwort und die Reproduktion meines Problems. Ihre Analyse (zu hohe Bitrate des streams) ist plausibel.
Frohe Weihnachten.
MfG
Rainer

Gerald Lechner

Gerald Lechner

@Rainer: Soweit ich das dem Protokoll entnehmen kann, wurde nicht der originale Sketch vom Download kompiliert, da dieser nicht das File AudioFileSourceSD.h inkludiert. Zweitens benutzen Sie nicht wwie im Beitrag angegeben das ESP32 Package mit Version2.0.5 sondern die Version 1.0.6. Es könnte außerdem noch sein, dass sie ein falsches Board ausgewählt haben. Es muss ESP32 Dev Module sein.

Rainer

Rainer

Hallo,
mit großer Freude habe ich die Neuauflage des Radio-Projekts gelesen.
das 1. Radioprojekt habe ich mehrfach problemlos gebaut.

Nachdem ich dann alle Bauteile auf meinem Basteltisch liegen hatte, habe ich mit dem Bau begonnen.
So weit, so gut.
Als ich dann den ESP32 programmieren wollte, begannen die Probleme.
Egal ob ich mit der Arduino IDE 1.8.18 oder 2.0.3 programmiert habe, es kamen immer Fehlermeldungen.
Auch auf verschiedenen Rechnern habe ich es versucht.
Immer wieder die nachfolgende Fehlermeldungen:

WARNUNG: Bibliothek LiquidCrystal I2C behauptet auf avr Architektur(en) ausgeführt werden zu können und ist möglicherweise inkompatibel mit Ihrer derzeitigen Platine, welche auf esp32 Architektur(en) ausgeführt wird.
In file included from c:\Users\Rainer\Documents\Arduino\libraries\SD\src/utility/Sd2Card.h:26:0,
from c:\Users\Rainer\Documents\Arduino\libraries\SD\src/utility/SdFat.h:29,
from c:\Users\Rainer\Documents\Arduino\libraries\SD\src/SD.h:20,
from c:\Users\Rainer\Documents\Arduino\libraries\ESP8266Audio\src\AudioFileSourceSD.h:25,
from c:\Users\Rainer\Documents\Arduino\libraries\ESP8266Audio\src\AudioFileSourceSD.cpp:21:
c:\Users\Rainer\Documents\Arduino\libraries\SD\src/utility/Sd2PinMap.h:524:2: error: #error Architecture or board not supported.
#error Architecture or board not supported.
^
Mehrere Bibliotheken wurden für “Preferences.h” gefunden
Benutzt: C:\Users\Rainer\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\Preferences
Nicht benutzt: C:\Users\Rainer\Documents\Arduino\libraries\Preferences
Mehrere Bibliotheken wurden für “HTTPClient.h” gefunden
Benutzt: C:\Users\Rainer\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\HTTPClient
Nicht benutzt: C:\Users\Rainer\Documents\Arduino\libraries\HttpClient
Mehrere Bibliotheken wurden für “FS.h” gefunden
Benutzt: C:\Users\Rainer\Documents\Arduino\libraries\FS
Nicht benutzt: C:\Users\Rainer\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\FS
Mehrere Bibliotheken wurden für “SD.h” gefunden
Benutzt: C:\Users\Rainer\Documents\Arduino\libraries\SD
Nicht benutzt: C:\Users\Rainer\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\SD
Mehrere Bibliotheken wurden für “SPIFFS.h” gefunden
Benutzt: C:\Users\Rainer\Documents\Arduino\libraries\SPIFFS
Nicht benutzt: C:\Users\Rainer\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\SPIFFS
Mehrere Bibliotheken wurden für “Update.h” gefunden
Benutzt: C:\Users\Rainer\Documents\Arduino\libraries\Update
Nicht benutzt: C:\Users\Rainer\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\Update
Mehrere Bibliotheken wurden für “WiFiClientSecure.h” gefunden
Benutzt: C:\Users\Rainer\Documents\Arduino\libraries\WiFiClientSecure
Nicht benutzt: C:\Users\Rainer\Documents\Arduino\libraries\ESP8266WiFi
Nicht benutzt: C:\Users\Rainer\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFiClientSecure
Mehrere Bibliotheken wurden für “WebServer.h” gefunden
Benutzt: C:\Users\Rainer\Documents\Arduino\libraries\WebServer
Nicht benutzt: C:\Users\Rainer\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WebServer
Mehrere Bibliotheken wurden für “ESPmDNS.h” gefunden
Benutzt: C:\Users\Rainer\Documents\Arduino\libraries\ESPmDNS
Nicht benutzt: C:\Users\Rainer\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\ESPmDNS
exit status 1

Compilation error: exit status 1

Ich weiß nicht mehr weiter.
Vielleicht kann mir hier jemand helfen.

Schon jetzt Danke.
Rainer

Gerald Lechner

Gerald Lechner

@Rainer Hoffmann: Es sollte mit jedem ESP32 Modul funktionieren. Ihr Problem hat nichts mit dem ESP32 zu tun. Ich habe die von Ihnen angegebene URL probiert und das selbe Problem festgestellt. Ich vermute, dass bei diesem Stream die Bitrate für den ESP32 zu hoch ist. Aber das ist nur eine Vermutung.

Rainer Hoffmann

Rainer Hoffmann

Ein sehr schönes Projekt Herr Lechner, Danke dafür.
In Abweichung zum angegebenen ESP32-Modul habe ich allerdings das aus dem alten Internetradio-Projekt genommen. Welche Nachteile sich dadurch ergeben könnten weiß ich nicht. Fakt ist aber, dass ich den stream
“http://stream.kontrafunk.radio/listen/kontrafunk/radio.mp3”
zwar einfügen und abrufen kann, jedoch stottert die Ausgabe extrem. Wenn Sie, Herr Lechner, oder aber einer der Mitleser einen Tip für die Lösung dieses Problems haben wäre ich dafür sehr dankbar.
MfG Rainer

Edgar Bauer

Edgar Bauer

Hallo
habe den Fehler gefunden, hatte das falsche Board ausgewählt, ja manchmal ist man blind.
Grüße Edgar Bauer

Edgar Bauer

Edgar Bauer

Guten Abend,
ich habe nochmal alles installiert, hänge aber beim WebServer,welchen soll ich nehmen?
Gruß Edgar Bauer

Edgar Bauer

Edgar Bauer

Guten Tag,
ich bin gerade dabei das Projekt nachzubauen und scheitere schon beim testen des Sketches.
Mir fehlen immer irgendwelche Dateien, einiges habe ich schon gefixt oder auch nicht im Momenthänge ich jetzt am Webserver
Welche Grund Bibliotkeken brauch ich denn? Anbei meine aktuelle Fehlermeldung.

Mehrere Bibliotheken wurden für “WiFi.h” gefunden

webserver:1:10: fatal error: WebServer.h: No such file or directory
Benutzt: C:\Users\edgar\Downloads\arduino-1.8.19-windows\arduino-1.8.19\libraries\WiFi
1 | #include
Nicht benutzt: C:\Users\edgar\OneDrive\Dokumente\Arduino\libraries\WiFiEspAT
| ^~~~~~~~~~~~~
compilation terminated.
exit status 1
WebServer.h: No such file or directory
Kann mir jemand helfen?
Liebe Grüße
Edgar

Ulrich Klaas

Ulrich Klaas

Weil es einfach eleganter ist habe ich meinen Code :
if (inMainLoop)
{
audio_loop();
}
durch Ihren Code :
if (decoder && (decoder→isRunning())) decoder→loop();

ersetzt.
Dann habe ich aber wieder leichte Störgeräusche.
Eventuell habe ich ja was übersehen.

Übrigens der Austausch von Stations.ino,Webserver.ino und index.h in meinem Sketch hat gereicht und
das neue Webinterface zu etablieren. Prima. Genau das hat gefehlt.
Ich bin jetzt angefixt ;-) Ein schönes mehrzeiliges Grafikdisplay würde mir auch noch gefallen. Mal sehen wann ich Zeit habe.

Ulrich Klaas

Ulrich Klaas

Einen hab ich noch ;-) !
Die DisplayUpdate2 hat einen Fehler. Wenn die Infozeile >20 Zeichen ist und in den ersten 20 Zeichen kein Blank ist geht das schief und
schreibt in die zweite Zeile mit rein und ruiniert die Senderanzeige.
Heute gehabt auf WDR 2 : Argentinen-Frankreich 3:3 Das erste Leerzeichen kommt erst nach mehr als 20 Zeichen.
Ich habe es für mich so gelöst das ich gar nicht nach dem Blank scanne weil mir das doch bei manchen Anzeigen zu viel Platz in den mageren 40 Zeichen
der zwei Zeilen weg nimmt.

Und mal eine Frage : Reicht es für die Änderungen am Webinterface die Datei “webserver.ino” auszutauschen ? Ich habe nämlich schon so einige Änderungen gemacht und bin jetzt zu faul das nachzuziehen. (Also Änderungen im Sinne von “personalisiern” ;-) !

Gerald Lechner

Gerald Lechner

Angeregt durch die Verbesserungen von Herrn Klaas, habe ich eine neue Version der ZIP-Datei auf den Download-Link gelegt. Die neue Version verhindert die Störgeräusche durch die Anzeige wie von Herrn Klaas vorgeschlagen.
Weiters gibt es Erweiterungen zum Web-Interface. Mit dem Button “Senderliste zurücksetzen” kann man wieder die Defaultliste zurückholen. Außerdem ist es nun möglich die Sender umzusortieren. Dazu gibt es jetzt ein neues Eingabefeld mit dem Label “Position”. Dies zeigt die aktuelle Position in der Liste an. Um einen Sender umzureihen, muss einfach die gewünschte neue Position in der Liste in das Eingabefeld eingegeben und dann der Button “Ändern” geklickt werden. Die Nummerierung der Positionen beginnt mit 1.

Ulrich Klaas

Ulrich Klaas

Schade das man seine Post nicht nachträglich ändern kann.
Eins noch : in der Rotary.ino sind in den das Displayupdatenden Routinen Serial.print(s) o.Ä.
Diese bitte auch entfernen. Ich glaube auch in Display.ino waren welche. Bitte raus nehmen denn auch die stehlen dem Audiostream Zeit.

Ich habe jetzt einen einfachen Stereowandler ohne Verstärker dran. Das klappt über die große Stereoanlage super und völlig ohne Störungen.
Die Version mit den eingebauten 8-Bit DA-Wandlern klang dagegen besc….en.

Bin ja beim Musikhörern eher der “Analogie” :-) Aber als Berieselungsmaschine mit Vielfalt ist das Dingen klasse !!

Ulrich Klaas

Ulrich Klaas

SO ! Jetzt bin ich auch die Störungen für den Titelupdate los. War gar nicht so schwer.
Das musste nur aus dem Callback raus da ich aus dem Callback heraus nicht “audioUpdate” aufrufen konnte. Das hätte eine unschöne
und sofort den Stack ruinierende Rekursion gegeben.

Erst mal nehmen wir die Funktion clearLineForeground(uint8_t line) wieder raus und ersetzten sie auch an den Aufrufstellen wieder
durch clearLine();
clearLine sieht jetzt so aus :

//clear one line
void clearLine(uint8_t line) {
lcd.setCursor(0,line);
for (uint8_t i = 0; i<20; i++)
{
if (inMainLoop)
{
audio_loop();
}
lcd.print(" ");
}
}

Ansonsten alles wie gestern beschrieben.
In der displayMessage (ohne2) müssen wir nichts ändern da die nur aus Setup aufgerufen wird.
Das inMainLoop brauchen wir weil sonst in den Ausgaberoutinen “updateAudio” aufgerufen würde ohne das die Librarie initialisiert ist → Absturz.

Um jetzt auch das Update der Indozeile störungsfrei zu bekommen deklarieren wir im Hauptmodul webradio_MAX folgende Variable ganz oben
global (am besten hinter inMainLoop) :
boolean connected;
boolean inMainLoop=false;
boolean Message2Flag = false;

Unten in loop() kommt jetzt hinter dem Uhrenupdate :

//timed event updatetime display every minute if ((millis() – tick) > 30000) { // before 60000 if (connected) displayDateTime(1); tick = millis(); } if (Message2Flag) { displayMessage2(2,title); Message2Flag = false; }

Da die Variable char title[] netterweise schon global war müssen wir in Audio.ino nur noch den Callback ändern :

//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)
{
if (strstr_P(type, PSTR)) {
strncpy(title, string, sizeof(title));
title[sizeof(title)-1] = 0;
} else {
// Who knows what to do? Not me!
};
//show the message on the display
Message2Flag = true;
//displayMessage2(2,title);
}

Damit haben wir im Callback nur noch einen Trigger und die Ausgabe erfolgt in der Hauptscheife in der wir dann
wieder nach jedem Zeichen das ans Display geht vorsichtshalber audioUpdate aufrufen dürfen damit uns der Puffer nicht leer läuft.

Was habe ich jetzt eigentlich gemacht. Ich habe die ESP8266 nicht voll analysiert aber ich denke sie wird einen Audiopuffer füllen der dann in
einem Interrupt abgearbeitet wird. D.h. nach audioUpdate läuft die Lib eine Weile (ein paar ms) autark im Hintergrund. Nur irgendwann
braucht sie Datennachschub was updateAudio aus dem Stream erledigt. Wenn wir jetzt mehre 20 Byte lange Strings auf dem Display ausgeben
(erst die Zeile löschen dann der neue Inhalt) dann dauert das über den nicht all zu schnellen I2C Bus zum Display zu lange. Der Audiopuffer wird leer
und es gibt Störgeräusche bis er wieder neu gefüllt ist. Ich sorge jetzt einfach nur dafür das bis auf wenige Ausnahmen nur ein Zeichen zum Display
geschickt wird und dazwischen immer wieder updateAudio aufgerufen wird (also audio_loop) und schon sind die Störungen weg. Die Ausgabe auf
dem Display wird dadurch (für mich) nicht sichtbar langsamer. Man muss auf embedded System immer genau schauen wie man mit Zeiten umgeht ;-)

Ich hoffe die Änderung wird übernommen und macht Spaß !

Frohe Weihnachten und guten Rutsch.

Ulli

Ulrich Klaas

Ulrich Klaas

Hallo,
ich habe mal angefangen was zur Störgeräuschminimierung einzubauen. Beim Tunen und änder der Lautstärke hat mich das kaum gestört aber ich habe
das Displayupdate auf eine halbe Minute gesetzt (weil ich da was geändert habe) und immer bei diesem Update stockte der Ton auch.
Auch wenn die Infozeilen ein update bekommen aber das ist ja seltener.
Folgende fixe Lösung habe ich gefunden.
Zuerst muss im Modul webradio_MAX die Variable “boolean inMainLoop=0 declariert werden”. Am Ende von Setup wird die auf 1 gesetzt !
Dann kommen in Display.ino folgende Funktionen :

void MyLcdPrint(char output)
{
while (
output)
{
lcd.print(*output);
if (inMainLoop)
{
audio_loop();
}
output++;
}
}

void clearLineForeground(uint8_t line) {
lcd.setCursor(0,line);
for (uint8_t i = 0; i<20; i++)
{
if (inMainLoop)
{
audio_loop();
}
lcd.print(" ");
}
}

Die Stringausgabe wird also auf ein Zeichen reduziert bevor wieder die Audioloop gerufen wird.
Die ClearLineForground ist notwendig weil auch Stringroutinen aus der Audioloop aufgerufen werden und das eine unschöne Rekursion gibt.

In ShowStation() und displayDateTime() nutze ich jetzt nur noch clearLineForeground und MyLcdPrint.
Und siehe (und höre vor Allem) → Keine Störgeräusche mehr beim Drehen an den Reglern und kein Aussetzer mehr wenn das Display geupdatet wird.

Dabei reicht schon eine von beiden Maßnahmen also entweder das ClearLineForground oder das MyLcdPrint (geht nur bei char *).

Für die Infozeilen aus der Audioloop muss ich mir noch was einfallen lassen. Da wird für die Zeichenweise Ausgabe, zumindest für das Löschen der Zeilen, nur eine Statemaschine helfen. Wenn Interesse besteht mache ich hier gerne Updates.

Werner

Werner

Dank an Herrn Lechner
Als interessierter Bastler der aber keine Ahnung von programmieren und auch keine Englischkenntnisse hat,hatte ich mich vergeblich an dem webradio MAX versucht. Immer war irgendein Fehler beim kompilieren da. Aber dank der Hilfe von Herrn Lechner via E-Mail läuft das Radio jetzt hervorragend. Danke nochmal an Herr Lechner und das AZ-Delivery Team. Allen Bastlern ein schönes Weihnachtsfest und viel Gesundheit
Werner Herzig

Ulrich Klaas

Ulrich Klaas

Ich muss mich entschuldigen.
Ich hatte nur mal so zum Spaß um Warnings los zu werden die etwas gewagten Zuweisungen in “SendStations”
a la “char *sel” und sel = ""; ersetzt mit Puffern und strcpy’s. Das habe ich dann doch wieder ausgebaut um dem
Originalzustand zu erhalten. Dabei hatte ich ein strcpy auf einen Nullpointer vergessen :-( . Pardon ! Mein Fehler.

Ulli

Gerald Lechner

Gerald Lechner

@Ulrich Klaas: Ich kann mir nicht erklären wie das zustande kam. Ich habe schon einige Sender geändert oder neu gespeichert immer ohne Probleme. Ich werde den Webserver um eine Funktion erweitern mit der man die Präferenzen wieder auf Default setzen kann. Mit der Funktion sender.clear() sollte es möglich sein alle Einträge zu löschen und damit wieder auf die Defaultwerte zurückzuschalten. Das habe ich aber noch nicht probiert!

Ulrich Klaas

Ulrich Klaas

Erst mal danke für die schnelle Antwort.
Jetzt habe ich ein echtes Problem. So läuft erst mal alles nur auf der Website ist das Dropdownmenü für die Stationen immer lehr.
Wenn ich eine neue Eingebe ist nachher die Stationsliste auf dem Gerät hin. Alles über 24 ist gleich und der Eintrag auf 0 ist überschrieben (mit meinem neuen Sender)

Gerald Lechner

Gerald Lechner

@Joachim: Display abschalten könnte man machen, bringt aber nicht viel Ersparnis, da die WLAN Funktionen des ESP32 und ie Verstärker den Hauptteil des Stroms verbrauchen. Ein Sortieren der Senderliste müsste über das Webinterface geschehen. Ich werde mir mal überlegen, wie man das machen könnte.
@Ulrich Klaas: Ja es ist richtig, dass die Funktion setGain() Werte bis 4.0 zulässt. Der Wert wird intern in eine binäre 8-Bit Festkommazahl umgewandelt. Das bedeutet 2 Bit für den Exponenten und 6 Bit für die Mantisse. Damit ist die höchste mögliche Zahl 3.984375 deshalb die Begrenzung auf 4.0. Diese Festkommazahl wird dann mit den Amplitudenwerten der Kanäle multipliziert um die Amplitude zu ermitteln, die an das I2S Interface gesendet wird. Das bedeutet 1.0 liefert genau die Amplitude, die im MP3 Stream empfangen wurde. Ich habe zuerst auch gedacht 4 wäre der Höchstwert, aber bei Werte über 1 funktioniert die Ausgabe nicht mehr richtig.

Ulrich Klaas

Ulrich Klaas

Hallo,

Erst mal : Prima Projekt.

Aber ich habe mal eine Frage zu der Funktion “setGain()”. Hier wird currentGain / 100.0 gerechnet und an out.SetGain() übergeben.
Da currentGain nur Werte zwischen 0 und 100 annehmen kann ist also auch der Maximalwert 1 !
Aber SetGain hat als Maximalwert 4.0. Ist das Absicht ? Meiner Meinung arbeitet so der DA-Wandler nicht optimal (zumindest wenn man
einen mit Verstärkeranschluss benutzt). Bei 1.0 werden ja dann nicht alle 16 Bit des Wandlers benutzt !

Lascia un commento

Tutti i commenti vengono moderati prima della pubblicazione