Audio-Ansage-Player mit Esp8266

OP (Firma: Q3) #5526466
Lesenswert?

Ich bastele an einer Audio-Ansage (ca. 1 Min), die von einem ESP8266 auf 
Knopfdruck per PWM abgespielt werden soll. Ich kenne die Beispiele mit 
externen MP3-Chips oder wenigstens einer SD-Karte, aber ...

Auf dem Wege zu einer möglichst minimalistischen Lösung, versuche ich 
gerade mal ein binäres Array mit den 8-Bit-PCM-Werten in PROGMEM 
unterzubringen. Meine Daten sind ca. 850k groß und ich habe mir ein Tool 
programmiert, was mir die in diese Form bringt:
1
const byte data[] PROGMEM = {0x80,0x80,0x80, ... ,0x80,0x7F,0x80}

Zum Lesen der Bytes verwende ich diese Syntax, die auch problemlos durch 
den Compiler (Arduino IDE) läuft:
1
myChar =  pgm_read_byte(data[pos]);
2
Serial.println(myChar);

Leider zeigt der serielle Monitor nicht testweise die gelesenen Werte 
an, sondern (für mich) sofort nach dem Hochladen wilde Fehlermeldungen:
1
Exception (3):
2
epc1=0x40201c32 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4022e6cc depc=0x00000000
3

4
ctx: cont 
5
sp: 3ffef1c0 end: 3ffef390 offset: 01a0
6

7
>>>stack>>>
8
3ffef360:  3fffdad0 00000000 3ffee35c 40201c27  
9
3ffef370:  feefeffe feefeffe 3ffee35c 4020201c  
10
3ffef380:  feefeffe feefeffe 3ffee370 40100114  
11
<<<stack<<<

Ist das ein Syntax-Problem oder hängt das mit dem zu großen Datenblock 
im PROGMEM zusammen? Die IDE ziegt nach dem Compilieren, dass (nur) 70% 
belegt wären ... Danke für Tips.
OP (Firma: Q3) #5526999
Lesenswert?

Michael U. schrieb:
> Hallo,
>
> wenn es ein ESP8266-12 mit 4MB Flash ist, pack den Kram doch als
> passendes Wave in das SPIFFS.
> Ansonsten schau Dir die ESP8266Audio-Lib an, die enthält eigentlich
> alles schon.
>
> Gruß aus Berlin
> Michael

Ok, danke für den Hinweis ... "SPIFFS" war mir bisher nicht so richtig 
ein Begriff, werde mich damit beschäftigen. Kann man von dort aus 
byteweise lesen?

Es ist ein "Wemos D1 Mini", ist das der genannte ESP8266-12 ... ?
#5527485
Lesenswert?

Hallo,

Frank E. schrieb:
> Ok, danke für den Hinweis ... "SPIFFS" war mir bisher nicht so richtig
> ein Begriff, werde mich damit beschäftigen. Kann man von dort aus
> byteweise lesen?

File öffnen und dann eben readBytes() usw.
Mein Vorschlag zur ESP8266Audio kam nur deshalb, weil Du da in den 
Beispielen vermutlich schon passendes für alles findest.
Ausgabe vom Flash, vom SPIFFS, von SD-Card, von Webstream. Format wave, 
flac, mp3 usw. in Software (MP3 besser mit einem ESP32), Ausgabe per 
I2S, Software-DAC usw.

https://github.com/earlephilhower/ESP8266Audio

Ist nur ein Vorschlag, kann man natürlich auch "zu Fuß" selber machen.
Vor Jahren habe ich ähnliches mal für einen Bekannten auf einem Mega88 
mit externem SPI-Flash und DAC gemacht, 22kHz/16Bit WAV-Files. Hatte ich 
auch mit 8Bit Samples und PWM-Ausgabe auf einem Tiny85 bei 64MHz 
PLL-Takt laufen, der hat 4 kurze Sounds aus dem Flash gespielt.
Oha, ich sehe gerade: das ist ja schon 10 Jahre her...

Gruß aus Berlin
Michael
OP (Firma: Q3) #5530257
Lesenswert?

Danke, in der Audio.Lib gibt es ein Beispiel "PlayWavefromProgmem", was 
meiner Absicht recht nahe kommt.

Allerdings konnte ich eine Info nirgendwo im Web finden: Wie groß dürfen 
Daten im Progmem des ESP8266 (Wemos D1 Mini) eigentlich sein? Trial & 
Error ist mir zu mühselig, weil ja auch das Compilieren richtig lange 
dauert ...

Danke für Info.
#5530501
Lesenswert?

Hallo,

mehr als 1MB hast Du als Programmflash und damit auch als Progmem nicht 
zur Verfügung. Davon belegen die Standardroutinen ohnehin schon rund 
250kB.
Leg Deine Daten als Datei ins SPIFFS, da hast Du knapp 3MB als Filegröße 
verfügbar. Beispiel müßte in der Lib auch dabei sein, zumindest ist es 
kein größeres Problem, die Komponenten der Lib passend 
zusammenzustellen.

Compilieren: Was ist bei Dir "richtig lange"? Ich habe gerade mal meinen 
Webserver compiliert, mit OTA, SPIFFS usw., Durchlauf 1m 5s, geflasht 
habe ich jetzt nicht, mache ich generell mit 921600 bei den ESP8266.

Gruß aus Berlin
Michael
#5530506
Lesenswert?

Mit plattform io ist das Kompilieren in ein paar Sekunden durch. Arduino 
IDE ist arg lahm. Gerade mal Tasmota kompilieren lassen, das dauert 
keine 30 Sekunden.
Wenn du dann noch das example vom ESP8266webserver einbindest kannst du 
deine Wav-Files bequem via webinterface ins SPIFFS hochladen
#5530900
Lesenswert?

Hallo,

30s oder hut 1min ist doch "jammern auf hohem Niveau" ;-).
Ich frage mal meinen Bekannten, wie lange so ein Linux-Kernel 
compiliert...

Timmo H. schrieb:
> Wenn du dann noch das example vom ESP8266webserver einbindest kannst du
> deine Wav-Files bequem via webinterface ins SPIFFS hochladen

Genau das wäre mein Ansatz. Zumal die ESP8266Audio die üblichen Formate 
direkt lesen und ausgeben kann.

Gruß aus Berlin
Michael
OP (Firma: Q3) #5844592
Lesenswert?

Der Threat ist schon älter, ich weiss, aber ich habe noch eine (neue) 
Frage dazu:

Ich habe das oben genannte Projekt mit der Audio-Lib (MP3 in SPIFFS) 
umgesetzt und es funktioniert auch ganz grundsätzlich. Zur Soundausgabe 
benutze ich den RX-Pin ("fake DAC").

Was auf die Dauer doch ein wenig nervt, sind die enormen Störgeräusche 
(auch wenn gerade kein File gespielt wird). Die Audio-Ausgabe klingt, 
wie neben einem Lagerfeuer am Bach. Also ständiges Kinstern, Zischeln 
etc., obwohl ich ein RC-Glied (10k in Reihe, 100nF nach Masse) zumm 
Verstärker dran habe und sämtliche WLAN-Funktionen (soweit das mit der 
Arduino-Lib möglich ist), deaktivert sind.

Aus Gründen der Dateigröße habe ich meine MP3-Files nur mono mit 22kHz 
codiert. Aber das ist es nicht. Höre ich mir die auf dem PC an, klingen 
sie zwar nicht besonders brilliant - logisch - aber sind frei von 
Störgeräuschen.

Was könnte man noch tun (abgesehen von externem DAC oder 
MP3-Player-Chip)?
#5844654
Lesenswert?

Hallo,

Frank E. schrieb:
> Ich habe das oben genannte Projekt mit der Audio-Lib (MP3 in SPIFFS)
> umgesetzt und es funktioniert auch ganz grundsätzlich. Zur Soundausgabe
> benutze ich den RX-Pin ("fake DAC").

ich habe die Ausgabe damals nur kurz getestet und auch keine anhörbaren 
Ergebnisse erziehlt. Allerdings nur kurz weil ohnehin ein I2S-DAC bei 
mir dranhängt. Wenn es in Dein Projkt passt, nimm sowas und gebe über 
I2S aus:
https://www.amazon.de/s?k=B01GFNYKK6

Die MAX98357A Module sind leider nicht ganz so super billig.

Gruß aus Berlin
Michael
#7432065
Lesenswert?

Hallo, ich bekomme leider keinen Ton raus mit der ESP8266Audio Library in der Arduino IDE. Habe nun schon alles neu installiert, keine Besserung. Ich sehe zwar die Sample Rate 48 KHz der MP3-Datei auf dem Oszilloskop, aber da ist nichts "aufmoduliert". Wenn ich die Sample Rate der Datei "pno-cs.mp3" mit Audacity auf 16 KHz ändere, sehe ich auf dem Oszilloskop nun die 16 Khz. Laut Serial Monitor läuft auch etwas. Hören kann man aber nichts.

Ich nutze die Arduino IDE weil das nur ein Teilprojekt ist, welches später zu einem Arduino Projekt hinzugefügt werden soll.

1
#include <Arduino.h>
2
#if defined(ARDUINO_ARCH_RP2040)
3
void setup() {}
4
void loop() {}
5
#else
6

7
#ifdef ESP32
8
  #include <WiFi.h>
9
  #include "SPIFFS.h"
10
#else
11
  #include <ESP8266WiFi.h>
12
#endif
13
#include "AudioFileSourceSPIFFS.h"
14
#include "AudioFileSourceID3.h"
15
#include "AudioGeneratorMP3.h"
16
#include "AudioOutputI2S.h"
17

18
// To run, set your ESP8266 build to 160MHz, and include a SPIFFS of 512KB or greater.
19
// Use the "Tools->ESP8266/ESP32 Sketch Data Upload" menu to write the MP3 to SPIFFS
20
// Then upload the sketch normally.  
21

22
// pno_cs from https://ccrma.stanford.edu/~jos/pasp/Sound_Examples.html
23

24
AudioGeneratorMP3 *mp3;
25
AudioFileSourceSPIFFS *file;
26
AudioOutputI2S *out;
27
AudioFileSourceID3 *id3;
28

29

30
// Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc.
31
void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
32
{
33
  (void)cbData;
34
  Serial.printf("ID3 callback for: %s = '", type);
35

36
  if (isUnicode) {
37
    string += 2;
38
  }
39
  
40
  while (*string) {
41
    char a = *(string++);
42
    if (isUnicode) {
43
      string++;
44
    }
45
    Serial.printf("%c", a);
46
  }
47
  Serial.printf("'\n");
48
  Serial.flush();
49
}
50

51

52
void setup()
53
{
54
  WiFi.mode(WIFI_OFF); 
55
  Serial.begin(115200);
56
  delay(1000);
57
  SPIFFS.begin();
58
  Serial.printf("Sample MP3 playback begins...\n");
59

60
  audioLogger = &Serial;
61
  file = new AudioFileSourceSPIFFS("/pno-cs.mp3");
62
  id3 = new AudioFileSourceID3(file);
63
  id3->RegisterMetadataCB(MDCallback, (void*)"ID3TAG");
64
  out = new AudioOutputI2S();
65
  mp3 = new AudioGeneratorMP3();
66
  mp3->begin(id3, out);
67
}
68

69
void loop()
70
{
71
  if (mp3->isRunning()) {
72
    if (!mp3->loop()) mp3->stop();
73
  } else {
74
    Serial.printf("MP3 done\n");
75
    delay(1000);
76
  }
77
}
78
#endif

Mir ist nicht ganz klar ob ich AudioOutputI2S() oder AudioOutputI2SNoDAC() verwenden muss, läuft aber auf beiden nicht.

Es handelt sich um einen PC-Speaker 1.5W, 8 Ohm, mit einem BC547 Transistor und 1k als Basis-Widerstand. Der ist direkt an den internen 8-Bit DAC des NodeMCU ESP32s angeschlossen. Mit einem Test-Ton höre (und sehe) ich aber etwas.

1
#include <driver/dac.h>
2

3
const int sampleRate = 48000;   // Sample rate in Hz
4
const int frequency = 1000;     // Frequency of the sine wave in Hz
5
const int amplitude = 127;      // Amplitude of the sine wave
6

7
void setup() {
8
  dac_output_enable(DAC_CHANNEL_1);  // Enable DAC channel 1
9
}
10

11
void loop() {
12
  for (int t = 0; t < sampleRate; t++) {
13
    int value = amplitude * sin(2 * PI * frequency * t / sampleRate);
14
    dac_output_voltage(DAC_CHANNEL_1, value + 127);  // Adjust the offset to output in the range 0-255
15
    delayMicroseconds(1000000 / sampleRate);  // Delay to maintain the desired sample rate
16
  }
17
}

An der Sample Rate wird es somit nicht liegen. Die ESP32-audioI2S Library ist leider mit meinem single-core ESP32s Devboard nicht kompatibel, bekomme ich auch nicht kompiliert.

Wenn jemand Ahnung hat von Audio und helfen möchte, einen NodeMCU ESP32s kann ich spenden und per Brief zusenden.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren