WLAN Lautsprecher auf ESP8266 Basis

Begonnen von chunter1, 25 April 2017, 16:06:20

Vorheriges Thema - Nächstes Thema

chunter1

Bin grade auf ein interessantes Projekt gestoßen mit dem man im einfachsten Fall nur ein ESP8266 Modul benötigt um einen MP3 stream auszugeben.
Benutzt wird in diesem Fall ein GPIO mit einer PWM als analoger Ausgang.
(Für bessere Qualität wäre ein externer I2S decoder und ein RAM nötig.)
https://github.com/espressif/esp8266_mp3_decoder



========== UPDATE 15.05.2017 ============

Inzwischen habe ich eine eigene Version erstellt.
Als Hardware wird nur ein ESP8266, ein Transistor/FET, Widerstand, Diode und ein Lautsprecher benötigt.
Da somit KEIN Audio Codec, externes RAM oder Verstärker benötigt werden, kostet das ganze < 3,-€   :D
Für alle die es gerne ausprobieren möchten (und gerne auch verbessern möchten), hier der Link zum Download:

https://github.com/chunter1/ESP8266_WLAN_speaker

Schaltplan, Foto und Youtube Video findet ihr hier ab Post #7.

Enjoy!  ;)

Edi77

Master FHEM 6 als VM auf ESX Ubuntu 20.04 LTS mit MAXCube/MAX!/FS20|TabletUI|Flightradar|Tasmota|TTN Lora|CCU3 HomematicIP|RPi mit GammaScout|MQTT EasyESP 8266|LuftdatenInfo|deCONZ HUEDev|probemon|Siemens Logo|P4D|3D PRINTER RAISE3D

chunter1

Zitat von: Edi77 am 25 April 2017, 18:47:45
Hallo,

Es gibt einige Projekte mit dem VS1053 als Webradio/MP3 Player
Vielleicht hilft dir das weiter
http://www.instructables.com/id/Wifi-Webradio-With-ESP8266-and-VS1053/
https://github.com/Edzelf/Esp-radio

Cooles Projekt!
Ich versuch allerdings den Aufwand so gering wie möglich zu halten - also nur ein ESP12F Modul mit einem FET am PWM Ausgang und einen Lautsprecher dran.
Soll als billiger kleiner WLAN Lautsprecher für Text2Speech Durchsagen dienen.

Die Frage ist nur, ob und wie man die generierte mp3 Datei an den ESP übergeben kann.

Wuppi68

Schick doch direkt WAF / PWM zu dem ESP ... dann braucht er nichts mehr decodieren :-) Für Sprachausgaben sollte die Benutzte WLAN Bandbreite ziemlich egal sein
Jetzt auf nem I3 und primär Homematic - kein Support für cfg Editierer

Support heißt nicht wenn die Frau zu Ihrem Mann sagt: Geh mal bitte zum Frauenarzt, ich habe Bauchschmerzen

fstefan1960

Hi,
klingt klasse. Wenn Du da was ans Laufen kriegst, interessiert es mich (und sicher andere) auch.
FHEM auf PC: CUL868, CUL 443, HM_LAN, JeeLink
FHEM auf Raspi: CUL868
div. LaCrosse Temp/Hum-Sensoren, HM-Heizkörperventile, Schaltaktoren, etc.

machnetz

Geil,

genau was ich für meinen Sohn gesucht habe. Die Bestellung von 2x VS1053-Boards aus dem Land der aufgehenden Sonne ist schon unterwegs :-)

Gruß - machnetz

chunter1

#6
Das hier klingt interessant.
https://gist.github.com/me-no-dev/e8b5131f840822cdd14b

Zum Abspielen einer mp3 Datei einfach folgendes Kommando aufrufen:

avconv -i "$file" -f s32be -acodec pcm_s32be -ar 44100 -af "volume=volume=0.5" tcp://espip:5522

Könnte das Anstelle vom mplayer als TTS-Ausgabe funktionieren?

UPDATE:

Der Code von oben lässt sich schon mal fehlerfrei compilieren. :)
Fragt sich nur wie der folgende Fake-PWM Ausgang Code exakt eingebaut werden muss.
Ich nehme an, er macht nichts anderes als die I2C Daten in eine pseudo PWM Bitfolge zu konvertieren damit am I2S-Data Pin eine fake PWM anliegt.


//Array with 32-bit values which have one bit more set to '1' in every consecutive array index value
const unsigned int ICACHE_RODATA_ATTR fakePwm[]={ 0x00000010, 0x00000410, 0x00400410, 0x00400C10, 0x00500C10, 0x00D00C10, 0x20D00C10, 0x21D00C10, 0x21D80C10,
0xA1D80C10, 0xA1D80D10, 0xA1D80D30, 0xA1DC0D30, 0xA1DC8D30, 0xB1DC8D30, 0xB9DC8D30, 0xB9FC8D30, 0xBDFC8D30, 0xBDFE8D30,
0xBDFE8D32, 0xBDFE8D33, 0xBDFECD33, 0xFDFECD33, 0xFDFECD73, 0xFDFEDD73, 0xFFFEDD73, 0xFFFEDD7B, 0xFFFEFD7B, 0xFFFFFD7B,
0xFFFFFDFB, 0xFFFFFFFB, 0xFFFFFFFF};

static int sampToI2sPwm(short s)
{
//Okay, when this is enabled it means a speaker is connected *directly* to the data output. Instead of
//having a nice PCM signal, we fake a PWM signal here.
static int err=0;
int samp=s;
samp=(samp+32768); //to unsigned
samp-=err; //Add the error we made when rounding the previous sample (error diffusion)

//clip value
if (samp>65535) samp=65535;
if (samp<0) samp=0;

//send pwm value for sample value
samp=fakePwm[samp>>11];
err=(samp&0x7ff); //Save rounding error.
return samp;
}

chunter1

#7
Hab in der Zwischenzeit eine erste Version meines ESP8266 WLAN Lautsprechers am laufen. :)

Ziel war mit minimalen Aufwand maximale Qualität zu erreichen um TTS-Durchsagen, Signaltöne und sogar "Musik" in jedem Raum via WLAN zu ermöglichen.

Ergebnis:
Hardware Kosten: < 3,-€
7 Bit PWM (8 Bit dithered) mit relativ guter Klangqualität

Aufruf in FHEM mittels Konsolen-Kommando z.B.:

system("avconv -i /opt/fhem/sounds/gong.mp3 -f s32be -acodec pcm_u8 -ac 1 -ar 33000 tcp://192.168.1.100:5522&")

Anbei der really quick&dirty Schaltplan damit man einen Eindruck von der Einfachheit bekommt.
Statt der 5V kann man auch z.B. 12V einspeisen um eine höhere Lautstärke zu erhalten.
Aber Achtung!
Solange das Streaming aktiv ist, liegt auf Grund der PWM (50% PWM entspricht Signal "Null") am Lautsprecher eine "DC"-Spannung in der Größe der halben Versorgungsspannung an.
Dadurch fließt bei einem 8 Ohm Lautsprecher und 5V Spannung ein konstanter Strom von ca. (5 / 2) / 8 = 313 mA (man müsste hier eigentlich die Impedanz des Lautsprechers bei 33kHz verwenden).

Besser ist, eine Halb-oder Vollbrücke zu verwenden und den Lautsprecher über einen Kondensator DC-frei anzuschließen.
Zusätzlicher Vorteil einer Vollbrücke ist, dass man bei gleicher Spannung die vierfache Leistung erhält.

chunter1

#8
Entwicklungsumgebung ist die Standard Arduino IDE.
Software Tester und Gurus die Interesse haben sind herzlich willkommen.  ;)

Im Bild unten ist mein Test-Setup zu sehen.
Dort verwende ich einen FET (8-pin Baustein) aus einer alten Festplatte mit einem 4,7 kOhm pulldown am Gate.

chunter1

#9
Für alle die es gerne ausprobieren möchten (und gerne auch verbessern möchten), hier der Link zum Download:

https://github.com/chunter1/ESP8266_WLAN_speaker

Enjoy!  ;)


EDIT:

Wer so wie ich TTS (Text2speech) darüber nutzen will, könnte die Sprachdatei im TTS cache z.B. so in FHEM weiterleiten:


define TTSforward DOIF ([myTTS:lastFilename])
({
my $filename = ReadingsVal("myTTS","lastFilename",0);;
system("avconv -i /opt/fhem/$filename -f s32be -acodec pcm_u8 -ac 1 -ar 33000 tcp://192.168.1.100:5522&");;
})

attr TTSforward checkReadingEvent 1
attr TTSforward do always


Bapt. Reverend Magersuppe

Mal eine Frage zum elektrischen Aufbau von einem Laien. Wozu die Diode über den Lautsprecher? Bei einem Relais kenne ich das, hier staunt der Laie (und der Fachmann weiss Bescheid).
--
If I was born in 1453, Leonardo da Vinci would be jealous of me.
Reverend Paul Egon Magersuppe
Aus versicherungstechnischen Gründen sind sämtliche Beiträge von mir rein spekulativer und theoretischer Natur und sollten nicht in die Tat umgesetzt werden!
Bin hier selten DRIN. AUS GRÜNDEN!

Otto123

Na generell bei induktiven Lasten zum Schutz des Transistors gegen Überspannung.
Auch ein Lautsprecher ist eine induktive Last genau wie ein Relais.

Stichwort Freilaufdiode für Details :)

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Bapt. Reverend Magersuppe

Ja, bei Relais kannte ich das. Aber Lautsprecher haben auch eine Spule, stimmt. Das macht Sinn.
--
If I was born in 1453, Leonardo da Vinci would be jealous of me.
Reverend Paul Egon Magersuppe
Aus versicherungstechnischen Gründen sind sämtliche Beiträge von mir rein spekulativer und theoretischer Natur und sollten nicht in die Tat umgesetzt werden!
Bin hier selten DRIN. AUS GRÜNDEN!

Otto123

#13
Hi,

Ich finde den Ansatz sehr interessant. Mir fällt dazu gerade ein: Ich habe mal einen "Wrapper" für mplayer gemacht, weil mir der Original mplayer unter Jessie mit seiner Startverzögerung etwas auf die Nerven ging. Nach einem Hinweis hier im Forum habe ich dann play aus dem sox (sox libsox-fmt-all) paket verwendet. Analog dazu könnte man doch die Ausgabe von Text2Speech abfangen und umleiten.
attr MyTTS TTS_MplayerCall /opt/fhem/mplayer.sh


Den Code müsste man in etwa so anpassen: (sorry ist noch mein ganzer Code inklusiver Testzeilen einfach die letzte Zeile Ausgabe angepasst, aber vielleicht hilft ja genau das beim probieren)
#!/bin/sh
# zum Test ausgeben
# echo Parameteranzahl $# > /tmp/mplay.txt

# falls volume nicht vorhanden = 1
volume=1
# Alsa Device, Volume und Dateinamen ermitteln
while [ $# -gt 0 ]
do
# echo $1 >> /tmp/mplay.txt
if [ $1 = -ao ]
then
shift
# echo $1 >> /tmp/mplay.txt
device=$(echo $1|cut -d= -f2)
# echo $device >> /tmp/mplay.txt
elif [ $1 = -volume ]
then
shift
# echo $1 >> /tmp/mplay.txt
if [ $1 -lt 100 ]
then
volume=0.$(($1))
fi   
elif [ -e $1 ]
then
file=$1
fi
shift
done
# zum Test ausgeben
#echo $volume $file >> /tmp/mplay.txt
#play -q -v $volume $file
avconv -i $file -f s32be -acodec pcm_u8 -ac 1 -ar 33000 tcp://192.168.1.100:5522
exit 0

Das ist jetzt auch nur schnell dahin geschrieben und nicht getestet, also nur als Idee. Ich muss erstmal die Hardware zusammenstricken  ;)

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

chunter1

Zitat von: Otto123 am 15 Mai 2017, 12:17:37
Ich finde den Ansatz sehr interessant. Mir fällt dazu gerade ein: Ich habe mal einen "Wrapper" für mplayer gemacht, weil mir der Original mplayer unter Jessie mit seiner Startverzögerung etwas auf die Nerven ging. Nach einem Hinweis hier im Forum habe ich dann play aus dem sox (sox libsox-fmt-all) paket verwendet. Analog dazu könnte man doch die Ausgabe von Text2Speech abfangen und umleiten.

Das wäre schon mal eine wesentlich bessere Lösung.
Noch besser würde mir gefallen, wenn man den Aufruf "avconv -i filename.mp3 -f s32be -acodec pcm_u8 -ac 1 -ar 33000 tcp://192.168.1.100:5522&" gleich direkt in FHEM im Text2Speech eintragen könnte?