Forum: Mikrocontroller und Digitale Elektronik ESP8266 Webradio Stream


von Thom E. (chrises)


Lesenswert?

Hallo Forum,

ich benutzte das ESP8266 in Verbindung mit dem STM32F7-Discoverey board, 
um mit einem Webradio zu verbinden und den mp3 Stream auszugeben.

Ich steuere das ESP mit AT Befehlen, es klappt auch für normale Text 
Dateien wie .m3u diese herunter zu laden.

Wenn ich per Laptop mit einem Webradio verbinde, sehe ich, dass alles 
mit TCP abläuft, der Handshake geht auch mit dem ESP und AT Befehlen.

Jetzt das Problem:
Laut Wireshark wird einfach ein GET- Befehl geschickt.

Wenn ich diesen 1:1 so übernehme und ans ESP per AT Befehle schicke, 
bekomme ich leider keine brauchbaren Daten.


Kann mir jemand sagen, welche GET Anfrage ich senden muss, damit ich den 
direkten Datenstrom der mp3 Datei empfangen kann? Ich speichere alle 
Empfangenen Bits per Interrupt in einem array.

Vielen Dank für eure Zeit!

von TestX (Gast)


Lesenswert?

Wie kommst du dadrauf, dass Radio-Streams über HTTP laufen (mit Ausnahme 
von HLS oder shoutcast..)?

Die Playlist wird so übertragen aber nicht die Daten. Hier solltest du 
sich erstmal ein wenig mit den Techniken vertraut machen. Letztendlich 
wirst du das Protokoll selber implementieren müssen über einen tcp/udp 
Socket.

von Pete K. (pete77)


Lesenswert?

Vielleicht hilft Dir das weiter, ist aber ein etwas anderer Ansatz:
https://github.com/karawin/Ka-Radio

von Thom E. (chrises)


Lesenswert?

Danke für den Link, ich bin zuerst davon ausgegangen, dass es über UDP 
läuft, hab mir dann eben Wireshark angesehen, wo man nur TCP findet.
Ich schaue mir den Link mal an.

Ich schätze das wird relativ schwer, das Protokoll selbst zu 
implementieren.

von Thom E. (chrises)


Angehängte Dateien:

Lesenswert?

hat vielleicht noch jemand eine Idee? habe nun viele weitere Sender und 
Arten versucht, aber so recht funktioniert es nicht.

ich habe hier eine Anleitung gefunden:

http://www.ethernut.de/en/documents/webradio.html

in dieser schreibt der Autor, dass es leicht ist und am ende von Punkt 
1, dass er jetzt einen stream aufgebaut hat und DANACH der HTTP Header 
angefragt wird.

Ist der HTTP header dann überhaupt nötig, um den Datenstrom zu empfangen 
und wie hat er diesen Stream "gestartet"?

Sollte beim ESP8266 das nicht mit

  uint8_t 
*tcpverbindung="AT+CIPSTART=\"TCP\",\"swr-swr3-live.cast.addradio.de\",8 
0\r\n";

gehen? volle adresse wäre
http://swr-swr3-live.cast.addradio.de/swr/swr3/live/mp3/128/stream.mp3

daher dachte ich, nach dem CIPSTART noch die GET anfrage mit
GET/swr/swr3/live/mp3/128/stream.mp3 HTTP1.1\r\n


funktioniert so aber nicht, ausgabe ist dann wie im screenshot

Bin für jeden Hinweis dankbar, LG Chris

von Sascha W. (sascha-w)


Lesenswert?

Chris E. schrieb:
> funktioniert so aber nicht, ausgabe ist dann wie im screenshot
das passt schon was du siehst.
Die Verbindung wird per HTTP hergestellt, du bekommst den HTTP-Result 
Header (HTTP 200 OK), und nach dem doppelten CRLF beginnen die Daten den 
mp3-Streams.
Ich weiß ja nicht wie du die Daten die vom ESP kommen parst, aber der 
Stream besteht natürlich ausschließlich aus Binärdaten die du 1:1 an 
deinen mp3 Dekoder weiterreichen musst.

Sascha

von K. M. (Gast)


Lesenswert?

Ich bin jetzt nicht gerade ein Experte in der Netzwerktechnik, aber wäre 
es nicht sinnvoller, die Pakete über UDP zu übertragen. Es handelt sich 
ja um einen Stream von Audiodaten, oder irre ich mich.

von Thom E. (chrises)


Angehängte Dateien:

Lesenswert?

Sascha W. schrieb:
> Chris E. schrieb:
>> funktioniert so aber nicht, ausgabe ist dann wie im screenshot
> das passt schon was du siehst.
> Die Verbindung wird per HTTP hergestellt, du bekommst den HTTP-Result
> Header (HTTP 200 OK), und nach dem doppelten CRLF beginnen die Daten den
> mp3-Streams.
> Ich weiß ja nicht wie du die Daten die vom ESP kommen parst, aber der
> Stream besteht natürlich ausschließlich aus Binärdaten die du 1:1 an
> deinen mp3 Dekoder weiterreichen musst.
>
> Sascha


Stimmt, mit Docklight kann man es sich ja auch als Hex-Zahlen ansehen, 
das Problem ist aber: ich bekomme nur ein einziges mal diese Antwort, 
also ein paar Zeichen im Buffer, danach empfängt das ESP nichts mehr. 
Der Stream, wenn diese paar Zeichen denn der Stream sein sollen, müsste 
ja automatisch immer weiter gehen.

Ich habe zum obigen Beispiel, da im Docklight-Screenshot im vorherigen 
Post im HTTP Header der Teil: Server:
sichtbar ist, auch mal das hier versucht:

uint8_t *getanfragehttp="GET /swr/swr3/live/mp3/128/stream.mp3 
HTTP/1.1\r\nServer: 
dg-swr-http_dus-dtag_edge_1c578a1c46f2c8c01cf246adf834ac5\r\n\r\n";


Hierbei emfange ich tatsächlich lange zeit immer wieder daten, was man 
auch an der blauen LED des ESP erkennen kann.

Könnte es sein, dass das die Audio-Daten sind? Hilft es, wenn ich einen 
Screenshot davon mache? Vermutlich nicht. Aber was könnte es sonst sein, 
was ständig gesendet wird?



Zur zweiten Antwort bezüglich UDP:

Ich habe nun 2 Screenshots von der Wireshark Aufzeichnung angehängt, 
damit die ungläubigen es mit eigenen Augen sehen, die Verbindung 
erfolgt, wenn man sie vom Laptop/PC aus herstellt, anscheinend, 
zumindest laut Wireshark, ausschließlich mit TCP und einer einzigen HTTP 
GET request.

Oder kann man sich das beliebig aussuchen?


Danke schonmal für die Hilfe, ich bin schon lange dran und habe 
eigentlich gehofft, man findet sowas auf google, aber es scheint doch 
ein größeres Problem zu sein :/

: Bearbeitet durch User
von Sascha W. (sascha-w)


Lesenswert?

Maha S. schrieb:
> Ich bin jetzt nicht gerade ein Experte in der Netzwerktechnik, aber wäre
> es nicht sinnvoller, die Pakete über UDP zu übertragen. Es handelt sich
> ja um einen Stream von Audiodaten, oder irre ich mich.
Das geht natürlich auch, aber ich kenne keinen I-Net-Radioanbieter der 
den Stream per UDP verteilen würde.
Bei UDP benötigt man zusätzlich noch eine Kontrollverbindung per TCP 
sonst könnte der Sender ja nicht feststellen das der Empfänger 
vielleicht gar nicht mehr da ist und würde die UDP-Pakete (ewig) weiter 
senden.
Des weiteren muss sich der Empfänger was einfallen lassen wie er die von 
aussen eingehenden Pakete durch die zumindest noch bei IP4 durch die NAT 
der üblichen Router bekommt.

Sascha

von Sascha W. (sascha-w)


Lesenswert?

Chris E. schrieb:
> Stimmt, mit Docklight kann man es sich ja auch als Hex-Zahlen ansehen,
> das Problem ist aber: ich bekomme nur ein einziges mal diese Antwort,
> also ein paar Zeichen im Buffer, danach empfängt das ESP nichts mehr.
> Der Stream, wenn diese paar Zeichen denn der Stream sein sollen, müsste
> ja automatisch immer weiter gehen.
ja es sollte weitergehen, es sei denn du holst die Daten vom ESP nicht 
ab dann wird er wohl die Verbindung beenden?!
Sendet die AT Firmware die Daten kontinuierlich oder werden die 
irgendwie segmentiert ausgegeben?

> ...
>
> Hierbei emfange ich tatsächlich lange zeit immer wieder daten, was man
> auch an der blauen LED des ESP erkennen kann.
>
> Könnte es sein, dass das die Audio-Daten sind?
davon ist auszugehen
> Hilft es, wenn ich einen
> Screenshot davon mache? Vermutlich nicht. Aber was könnte es sonst sein,
> was ständig gesendet wird?
Ein paar 100kByte als mp3 abspeichern und einem Player vorwerfen - 
sollte gehen.

Sascha

von Thom E. (chrises)


Lesenswert?

Sascha W. schrieb:
> Chris E. schrieb:
>> Stimmt, mit Docklight kann man es sich ja auch als Hex-Zahlen ansehen,
>> das Problem ist aber: ich bekomme nur ein einziges mal diese Antwort,
>> also ein paar Zeichen im Buffer, danach empfängt das ESP nichts mehr.
>> Der Stream, wenn diese paar Zeichen denn der Stream sein sollen, müsste
>> ja automatisch immer weiter gehen.
> ja es sollte weitergehen, es sei denn du holst die Daten vom ESP nicht
> ab dann wird er wohl die Verbindung beenden?!
> Sendet die AT Firmware die Daten kontinuierlich oder werden die
> irgendwie segmentiert ausgegeben?
>
>> ...
>>
>> Hierbei emfange ich tatsächlich lange zeit immer wieder daten, was man
>> auch an der blauen LED des ESP erkennen kann.
>>
>> Könnte es sein, dass das die Audio-Daten sind?
> davon ist auszugehen

Ich meinte damit, dass dann der Zusatz im GET Request mit den Server: 
Teil das ausschlaggebende ist? Beim Docklight Screen den ich hier 
gepostet habe, ist das mit dem Server nicht dabei und hier bekomme ich 
nur eine einzige Antwort.
Aber ja, was sollte es sonst sein, mich wunder nur, dass man das mit 
Server: dazu schreiben muss, sowas steht niergends im Netz.



>> Hilft es, wenn ich einen
>> Screenshot davon mache? Vermutlich nicht. Aber was könnte es sonst sein,
>> was ständig gesendet wird?
> Ein paar 100kByte als mp3 abspeichern und einem Player vorwerfen -
> sollte gehen.
>
> Sascha


Hierzu eine Frage, ich müsste dann ja beim empfangen in der IRQ alle 
Steuerzeichen entfernen lassen, da ja viele PSH ACK STX etc drinnen 
enthalten sind, die nicht in das mp3_array hinein gelangen dürfen. Dies 
könnte ich mit einer IF Abfrage machen, wenn ich das recht sehe.

Wie könnte ich die Empfangenen Daten dann als mp3 Datei speichern? Die 
ausgelesenen Werte als Hexzahlen in einem Editor?
Welchen Player könnte man verwenden?


Danke für die bisherigen Antworten und eure Zeit!


ich hänge nochmal den C Code hier an, ist etwas lange wegen vieler 
kommentare, aber falls es hilft, ich bin für alles dankbar.
1
/**
2
  ******************************************************************************
3
  * File Name          : main.c
4
  * Description        : Main program body
5
  ******************************************************************************
6
  ** This notice applies to any and all portions of this file
7
  * that are not between comment pairs USER CODE BEGIN and
8
  * USER CODE END. Other portions of this file, whether 
9
  * inserted by the user or by software development tools
10
  * are owned by their respective copyright owners.
11
  *
12
  * COPYRIGHT(c) 2017 STMicroelectronics
13
  *
14
  * Redistribution and use in source and binary forms, with or without modification,
15
  * are permitted provided that the following conditions are met:
16
  *   1. Redistributions of source code must retain the above copyright notice,
17
  *      this list of conditions and the following disclaimer.
18
  *   2. Redistributions in binary form must reproduce the above copyright notice,
19
  *      this list of conditions and the following disclaimer in the documentation
20
  *      and/or other materials provided with the distribution.
21
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
22
  *      may be used to endorse or promote products derived from this software
23
  *      without specific prior written permission.
24
  *
25
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
  *
36
  ******************************************************************************
37
  */
38
/* Includes ------------------------------------------------------------------*/
39
#include "main.h"
40
#include "stm32f7xx_hal.h"
41
#include <string.h>
42
43
/* USER CODE BEGIN Includes */
44
45
/* USER CODE END Includes */
46
47
/* Private variables ---------------------------------------------------------*/
48
49
UART_HandleTypeDef huart1;
50
UART_HandleTypeDef huart6;
51
uint8_t empfangsbuffer[10000];
52
int receivezaehler=0;
53
54
/* USER CODE BEGIN PV */
55
/* Private variables ---------------------------------------------------------*/
56
57
/* USER CODE END PV */
58
59
/* Private function prototypes -----------------------------------------------*/
60
void SystemClock_Config(void);
61
static void MX_GPIO_Init(void);
62
static void MX_USART1_UART_Init(void);
63
static void MX_USART6_UART_Init(void);
64
65
/* USER CODE BEGIN PFP */
66
/* Private function prototypes -----------------------------------------------*/
67
68
/* USER CODE END PFP */
69
70
/* USER CODE BEGIN 0 */
71
72
73
void USART6_IRQHandler(void)
74
{
75
                uint8_t DataRx;
76
                if( __HAL_UART_GET_IT(&huart6, UART_IT_RXNE) != RESET ) {  // Receive interrupt triggered
77
78
                               //DataRx = huart6.Instance->RDR;  // Receive Data Register
79
                               //printf("%Interrupt empfängt: %c",DataRx);
80
                               empfangsbuffer[receivezaehler]=huart6.Instance->RDR;
81
                               receivezaehler=receivezaehler+1;
82
83
                               if (receivezaehler==9999)
84
                                 receivezaehler=0;
85
                    
86
                }
87
88
}
89
90
/* USER CODE END 0 */
91
92
int main(void)
93
{
94
95
  /* USER CODE BEGIN 1 */
96
97
  /* USER CODE END 1 */
98
99
  /* MCU Configuration----------------------------------------------------------*/
100
101
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
102
  HAL_Init();
103
104
  /* USER CODE BEGIN Init */
105
106
  /* USER CODE END Init */
107
108
  /* Configure the system clock */
109
  SystemClock_Config();
110
111
  /* USER CODE BEGIN SysInit */
112
113
  /* USER CODE END SysInit */
114
115
  /* Initialize all configured peripherals */
116
  MX_GPIO_Init();
117
  MX_USART6_UART_Init();
118
  MX_USART1_UART_Init();
119
120
  /* USER CODE BEGIN 2 */
121
122
  HAL_NVIC_SetPriority(USART6_IRQn,1,0);
123
124
  HAL_NVIC_EnableIRQ(USART6_IRQn);
125
126
  __HAL_UART_ENABLE_IT(&huart6, UART_IT_RXNE);  // Enable receive interrupt request
127
  /* USER CODE END 2 */
128
129
  /* Infinite loop */
130
  /* USER CODE BEGIN WHILE */
131
  uint8_t i=0;
132
  uint8_t *setbaudrate="AT+CIOBAUD=115200\r\n"; //19
133
  uint8_t *baudrateabfrage="AT+CIOBAUD?\r\n"; //13
134
  uint8_t *sendebuffer3="AT+RST\r\n";
135
136
137
138
139
140
141
142
143
144
145
146
  uint8_t *restart="AT+RST\r\n"; //8
147
  uint8_t *wifimode="AT+CWMODE=1\r\n"; //13
148
  uint8_t *connect="AT+CWJAP=\"test\",\"53793043047734343304343\"\r\n"; //44 ?
149
  //uint8_t *sendebuffer13="AT+CWLAP\r\n"; //10   FUNKTIONIERT MIT DEM EMPFANGEN NICHT
150
  uint8_t *getip="AT+CIFSR\r\n"; //10
151
  uint8_t *multiconnection="AT+CIPMUX=0\r\n"; //13
152
  //uint8_t *setastcpserver="AT+CIPSERVER=1,80\r\n"; //19
153
154
155
  //uint8_t *send29bytes="AT+CIPSEND=0,29\r\n"; //17
156
  //uint8_t *helloworldhtml="<h1>Hello</h1><h2>World!</h2>\r\n"; //31
157
158
 // uint8_t *tcpverbindung="AT+CIPSTART=\"TCP\",\"212.227.144.45\",\"80\"\r\n"; //41  so richtig?
159
  //uint8_t *tcpverbindung="AT+CIPSTART=\"TCP\",\"sunshine-live.de\",80\r\n"; //41
160
  //uint8_t *tcpverbindung="AT+CIPSTART=\"TCP\",\"stream.sunshine-live.de/90er/mp3-128/stream.sunshine-live.de/\",80\r\n"; //76
161
    uint8_t *tcpverbindung="AT+CIPSTART=\"TCP\",\"swr-swr3-live.cast.addradio.de\",80\r\n"; //43
162
  //uint8_t *tcpverbindung="AT+CIPSTART=\"UDP\",\"http://br-b5aktuell-live.cast.addradio.de/br/b5aktuell/live/mp3/128/stream.mp3\",80\r\n"; //103
163
  uint8_t *anzahlzusendenderbytes="AT+CIPSEND=125\r\n"; //15
164
  //uint8_t *getanfragehttp="GET /b5aktuell_2.m3u HTTP/1.1"; //29
165
  //uint8_t *getanfragehttp="GET http://streams.br.de/b5aktuell_2.m3u HTTP/1.1\r\n"; //51
166
  //uint8_t *getanfragehttp="GET /b5aktuell_2.m3u HTTP/1.1\r\n"; //31
167
  //uint8_t *getanfragehttp="GET http://server231.radiostreamserver.de/wunschradio-80er.mp3 HTTP/1.0\r\n\r\n"; //75
168
169
  //uint8_t *getanfragehttp="GET http://mp3channels.webradio.antenne.de/antenne HTTP/1.1\r\n\r\n"; //74
170
171
  //uint8_t *getanfragehttp="GET /antenne HTTP/1.1\r\nHost: mp3channels.webradio.antenne.de\r\nConnection: keep-alive\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webb,image/apng,*/*:q=0.8\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4\r\n\r\n"; //74
172
173
174
  uint8_t *getanfragehttp="GET /swr/swr3/live/mp3/128/stream.mp3 HTTP/1.1\r\nHost: swr-swr3-live.cast.addradio.de\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n"; //74
175
176
  //uint8_t *getanfragehttp="GET http://server74.radiostreamserver.de/wunschradio-80er.mp3 HTTP/1.1\r\nContent-Type: application/json\r\nConnection: keep-alive\r\n\r\n"; //98
177
  //uint8_t *getanfragehttp="GET /90er/mp3-128/stream.sunshine-live.de/ HTTP/1.0\r\n\r\n"; //55
178
  //uint8_t *getanfragehttp="GET http://sunshinelive.hoerradar.de/sunshinelive-90er-mp3-mq?sABC=59np0o05%230%23p453po8on067s02964491r2803n0n7qr%23fgernz.fhafuvar-yvir.qr&amsparams=playerid:stream.sunshine-live.de;skey:1504447237 HTTP/1.0\r\n\r\n"; //55
179
  //uint8_t *getanfragehttp="GET http://sunshine-live.de/sunshinelive-live-mp3.hq?sABC=59nosq01%230%23p75s14ssr3p58npqq718ns0oq945r735%23Jroenqvb-Cynlre&amsparams=playerid:Webradio-Player;skey:1504443649 HTTP/1.1\r\n\r\n"; //187
180
181
182
  //http://mp3channels.webradio.antenne.de:80/antenne
183
184
185
 // http://br-b5aktuell-live.cast.addradio.de/br/b5aktuell/live/mp3/128/stream.mp3
186
int hilf=strlen(getanfragehttp);
187
printf("anfragelaenge: %i",hilf);
188
////http://  /b5aktuell_2.m3u
189
190
191
192
193
//<<<<<<<<<<<<<<<<<<<<<<<<  ESP Initialisieren >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
194
  /*HAL_UART_Transmit(&huart6,sendebuffer1,13,1000);
195
  HAL_Delay(1000);
196
  printf("\n\n\n\n\n\n\nAn ESP gesendet: %s",sendebuffer1);
197
  printf("ESP Antwort: %s \n\n\n\n\n\n", empfangsbuffer);
198
199
  HAL_Delay(1000);
200
  HAL_UART_Transmit(&huart6,sendebuffer2,8,1000);
201
  HAL_Delay(1000);
202
  printf("An ESP gesendet: %s",sendebuffer2);
203
  printf("ESP Antwort: %s \n\n\n\n\n\n", empfangsbuffer);
204
/*
205
  HAL_Delay(1000);
206
  HAL_UART_Transmit(&huart6,sendebuffer3,8,1000);
207
  HAL_Delay(1000);
208
  printf("An ESP gesendet: %s",sendebuffer3);
209
  printf("ESP Antwort: %s \n\n\n\n\n\n", empfangsbuffer);*/
210
/*
211
  HAL_Delay(1000);
212
  HAL_UART_Transmit(&huart6,sendebuffer4,10,1000);
213
  HAL_Delay(1000);
214
  printf("An ESP gesendet: %s",sendebuffer4);
215
  printf("ESP Antwort: %s \n\n\n\n\n\n", empfangsbuffer);*/
216
217
218
219
220
221
222
223
   HAL_UART_Transmit(&huart6,restart,8,1000);
224
   HAL_Delay(1000);
225
   printf("\n\n\nAn ESP gesendet: %s",restart);
226
   printf("ESP Antwort: %s \n\n\n", empfangsbuffer);
227
   receivezaehler=0;
228
   memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
229
/*
230
   HAL_Delay(5000);
231
   HAL_UART_Transmit(&huart6,setbaudrate,19,1000);
232
   HAL_Delay(1000);
233
   printf("An ESP gesendet: %s",setbaudrate);
234
   printf("ESP Antwort: %s \n\n\n", empfangsbuffer);
235
   receivezaehler=0;
236
   memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
237
238
   HAL_Delay(3000);
239
   HAL_UART_Transmit(&huart6,baudrateabfrage,13,1000);
240
   HAL_Delay(1000);
241
   printf("An ESP gesendet: %s",baudrateabfrage);
242
   printf("ESP Antwort: %s \n\n\n", empfangsbuffer);
243
   receivezaehler=0;
244
   memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
245
246
*/
247
   HAL_Delay(3000);
248
   HAL_UART_Transmit(&huart6,wifimode,13,1000);
249
   HAL_Delay(1000);
250
   printf("An ESP gesendet: %s",wifimode);
251
   printf("ESP Antwort: %s \n\n", empfangsbuffer);
252
   receivezaehler=0;
253
   memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
254
255
256
   HAL_Delay(1000);
257
   HAL_UART_Transmit(&huart6,connect,44,1000);
258
   HAL_Delay(1000);
259
   printf("An ESP gesendet: %s",connect);
260
   printf("ESP Antwort: %s \n\n", empfangsbuffer);
261
   receivezaehler=0;
262
   memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
263
/*
264
   HAL_Delay(1000);
265
   HAL_UART_Transmit(&huart6,sendebuffer13,10,1000);
266
   HAL_Delay(1000);
267
   printf("An ESP gesendet: %s",sendebuffer13);
268
   printf("ESP Antwort: %s \n\n\n\n\n\n", empfangsbuffer);
269
   receivezaehler=0;
270
*/
271
272
   HAL_Delay(3000);
273
   HAL_UART_Transmit(&huart6,multiconnection,13,1000);
274
   HAL_Delay(1000);
275
   printf("An ESP gesendet: %s",multiconnection);
276
   printf("ESP Antwort: %s \n\n", empfangsbuffer);
277
   receivezaehler=0;
278
   memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
279
/*
280
   HAL_Delay(1000);
281
   HAL_UART_Transmit(&huart6,setastcpserver,19,1000);
282
   HAL_Delay(1000);
283
   printf("An ESP gesendet: %s",setastcpserver);
284
   printf("ESP Antwort: %s \n\n\n\n\n\n", empfangsbuffer);
285
   receivezaehler=0;
286
287
*/
288
   HAL_Delay(1000);
289
   HAL_UART_Transmit(&huart6,getip,10,1000);
290
   HAL_Delay(1000);
291
   printf("An ESP gesendet: %s",getip);
292
   printf("ESP Antwort: %s \n\n", empfangsbuffer);
293
   receivezaehler=0;
294
   memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
295
296
   HAL_Delay(1000);
297
   HAL_UART_Transmit(&huart6,tcpverbindung,strlen(tcpverbindung),1000);
298
   HAL_Delay(1000);
299
   printf("An ESP gesendet: %s",tcpverbindung);
300
   printf("ESP Antwort: %s \n\n", empfangsbuffer);
301
   receivezaehler=0;
302
   memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
303
304
   HAL_Delay(500);
305
   HAL_UART_Transmit(&huart6,anzahlzusendenderbytes,strlen(anzahlzusendenderbytes),1000);
306
   HAL_Delay(1000);
307
   printf("An ESP gesendet: %s",anzahlzusendenderbytes);
308
   printf("ESP Antwort: %s \n\n", empfangsbuffer);
309
   receivezaehler=0;
310
   memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
311
312
   HAL_Delay(500);
313
   HAL_UART_Transmit(&huart6,getanfragehttp,strlen(getanfragehttp),1000);
314
   HAL_Delay(1000);
315
   printf("An ESP gesendet: %s",getanfragehttp);
316
   printf("ESP Antwort: %s \n\n", empfangsbuffer);
317
   receivezaehler=0;
318
   memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
319
320
321
322
323
324
325
326
327
328
  while (1)
329
  { /* USER CODE END WHILE */
330
331
    /* USER CODE BEGIN 3 */
332
    if(receivezaehler>1000)
333
    {
334
    printf("ESP Antwort nach 1000 Zeichen: %s \n", empfangsbuffer);
335
    receivezaehler=0;
336
    memset(&empfangsbuffer[0], 0, sizeof(empfangsbuffer));
337
    }
338
          //UART6_SendData('A','T','\r','\n');
339
        //printf("Hallo: %d\n", i++);
340
        //HAL_Delay(100);
341
342
      HAL_GPIO_TogglePin(GPIOI, GPIO_PIN_1);
343
      HAL_Delay(1);
344
345
346
347
  }

: Bearbeitet durch User
von Sascha W. (sascha-w)


Lesenswert?

Hallo,

das nächste mal den Quellcode als Datei anhängen!

Die URL wird immer aufgeteilt, der Domainname als Host: xx und der Rest 
der URL als GET /xx

bezüglich der Steuerzeichen, woher weißt du das diese Zeichen nicht Teil 
des Streams sind?

Sascha

von Thom E. (chrises)


Angehängte Dateien:

Lesenswert?

Sascha W. schrieb:
> Hallo,
>
> das nächste mal den Quellcode als Datei anhängen!
>
> Die URL wird immer aufgeteilt, der Domainname als Host: xx und der Rest
> der URL als GET /xx


Also in der GET Request

GET /swr/swr3/live/mp3/128/stream.mp3 HTTP/1.1\r\nHost: 
swr-swr3-live.cast.addradio.de\r\n

so habe ich das ja oder?




> bezüglich der Steuerzeichen, woher weißt du das diese Zeichen nicht Teil
> des Streams sind?
>
> Sascha

also im Docklight sieht man ja gut die Unterscheidung zwischen 
Steuerzeichen und Daten, ich dachte die grün markierten sind alles 
Steuerzeichen, die ich heraustrennen müsste?

Sry das mit den C-code wäre als Datei schlauer gewesen, anbei nochmal

von Sascha W. (sascha-w)


Lesenswert?

Chris E. schrieb:
> Also in der GET Request
>
> GET /swr/swr3/live/mp3/128/stream.mp3 HTTP/1.1\r\nHost:
> swr-swr3-live.cast.addradio.de\r\n
>
> so habe ich das ja oder?
genau

> also im Docklight sieht man ja gut die Unterscheidung zwischen
> Steuerzeichen und Daten, ich dachte die grün markierten sind alles
> Steuerzeichen, die ich heraustrennen müsste?
wie gesagt, die mp3-Daten sind Binärdaten und das Docklight fügt für 
benannte Steuerzeichen halt diese Platzhalter ein. Das heißt aber nicht 
das die nicht zu den Nutzdaten gehören.
Wie unterscheidet denn die AT-Firmware zwischen Nutz und Steuerdaten? 
Hab damit noch nicht gearbeitet sondern immer eigene Firmware auf den 
ESP geladen.


Sascha

von Thom E. (chrises)


Lesenswert?

Sascha W. schrieb:
> Chris E. schrieb:
>> Also in der GET Request
>>
>> GET /swr/swr3/live/mp3/128/stream.mp3 HTTP/1.1\r\nHost:
>> swr-swr3-live.cast.addradio.de\r\n
>>
>> so habe ich das ja oder?
> genau
>
>> also im Docklight sieht man ja gut die Unterscheidung zwischen
>> Steuerzeichen und Daten, ich dachte die grün markierten sind alles
>> Steuerzeichen, die ich heraustrennen müsste?
> wie gesagt, die mp3-Daten sind Binärdaten und das Docklight fügt für
> benannte Steuerzeichen halt diese Platzhalter ein. Das heißt aber nicht
> das die nicht zu den Nutzdaten gehören.
> Wie unterscheidet denn die AT-Firmware zwischen Nutz und Steuerdaten?
> Hab damit noch nicht gearbeitet sondern immer eigene Firmware auf den
> ESP geladen.
>
>
> Sascha


Stimmt, eigentlich sollten die "Steuerdaten" des TCP/IP Protokolls vom 
ESP selbst herausgefiltert und nur die eigentlichen Nutzdaten 
herausgegeben werden.

Das heißt, ich kann die Daten einfach nehmen. Aber wie könnte ich sie 
Testweise als MP3 Daten speichern und zum Test abspielen?
Einfach in Editor speichern und mit winamp oder so öffnen wird nicht 
gehen oder?

Wie das ESP die Daten weiter gibt weis ich leider nicht. Hat jemand 
damit Erfahrung? Ich habe gehofft, das schickt sie einfach weiter und da 
ich sie per Interrupt Empfange und in den Empfangsbuffer speichere, 
sollte sich da nichts anstauen, hoffe ich.


Ok ich habe nun versucht die Baudrate hochzustellen, vielleicht liegt es 
wirkich daran, dass das ESP die Daten nicht schnell genug weiter geben 
kann und deshalb die Verbindung beendet.

: Bearbeitet durch User
von Sascha W. (sascha-w)


Lesenswert?

Chris E. schrieb:
> Stimmt, eigentlich sollten die "Steuerdaten" des TCP/IP Protokolls vom
> ESP selbst herausgefiltert und nur die eigentlichen Nutzdaten
> herausgegeben werden.
nicht die Steuerdaten vom TCP/IP, sondern die der AT-Firmware des ESP.

> Das heißt, ich kann die Daten einfach nehmen. Aber wie könnte ich sie
> Testweise als MP3 Daten speichern und zum Test abspielen?
wie kommen die denn vom STM ins Docklight?
Wenn Seriell dann z.B. mit Hterm die empfangenen Daten in eine Datei 
schreiben lassen.

> Einfach in Editor speichern und mit winamp oder so öffnen wird nicht
> gehen oder?
Oder VLC, weiß nicht ob Player die erst mal die die Tags lesen wollen 
(die ja nicht da sind) mit der Datei ein Problem haben.

> Wie das ESP die Daten weiter gibt weis ich leider nicht. Hat jemand
> damit Erfahrung? Ich habe gehofft, das schickt sie einfach weiter und da
> ich sie per Interrupt Empfange und in den Empfangsbuffer speichere,
> sollte sich da nichts anstauen, hoffe ich.
Zur Kommunikation mit dem ESP verwendest du wohl eine fertige Lib auf 
dem STM?

Sascha

von Thom E. (chrises)


Lesenswert?

Guten Abend,

Die Kommunikation zwischen ESP und STMF327 erfolgt über UART6, habe ich 
eingerichtet. Die Übertragung von STM an PC erfolgt über die UART1, 
welche mit printf gekoppelt ist. Dies war im Beispielprojekt schon so 
gemacht, nicht von mir.

Ich habe heute daher die Vermutung bekommen, dass die UART6 Receive ISR 
den µC ziemlich blockiert: ab der GET Request werden auch ganz simple 
printf Befehle in der while(1) Schleife nur noch alles ~20 Sekunden 
ausgeführt.

Das gute daran ist, dass das wohl heißt, der mp3-stream kommt 
tatsächlich an.

Die Ausgabe dessen war bisher aber wohl wenig sinnvoll umgesetzt...

Ich bin gerade am überlegen, ob ich es nicht auch so testen kann, dass 
ich den Empfangsbuffer einfach an die MP3-Decode Funktion übergeben kann 
und so testen kann.

Allerdings weis ich ja nicht, wie viel/wie groß die Daten sind, die ich 
da Empfange und ob die MP3-Dekode-Funktion und Audio-Wiedergabe 
überhaupt so schnell funktionieren.

Wäre schon hilfreich, mir die empfangenen Daten mal ansehen zu können, 
ist echt schwierig, da ich im Moment überhaupt nicht weis was/ob 
überhaupt etwas vom Internetsender ankommt.

: Bearbeitet durch User
von Marco H. (damarco)


Lesenswert?

Genau das wird das Problem sein. Du müsstest die Daten über ein FIFO 
Buffern und diese auch noch an den Decoder übertragen.  Gut dass könnte 
man per DMA lösen aber das FIFO Problem bleibt. In der Form das nicht 
genug RAM da ist um zwischen zu Buffern. Außerdem den ESP über AT 
Kommandos anzusprechen ist nicht gerade vorteilhaft.

von macload1 (Gast)


Lesenswert?

Was du eventuell tun kannst, ist einen FTDI UART/USB Converter mit 
seinem RX Port parallel zum RX von deinem UART6 schalten. Dann könntest 
du gleichzeitig wie der STM32F7 die Daten auf deinem PC auslesen und 
abspeichern.
Vielleicht hilft Audacity zum abspielen der Dateien. Ich hab das mal 
gebraucht, um MP3s in WAVE in verschiedenen Frequenzen umzuwandeln.

von Minetti (Gast)


Lesenswert?

Ich glaube, du hast derzeit zu viele Baustellen offen. Versuch doch 
erstmal, ein paar grundsätzliche Verständnisprobleme zu lösen.

Erste Aufgabe: starte Wireshark, lass so etwas wie VLC den Stream 
wiedergeben und schau dir an, was da gesendet und empfangen wird.

Zweite Aufgabe: schreibe ein einfaches Programm unter Windows, dass die 
Anfragen analog zu VLC ausführt und speichere die binärdaten in eine 
Datei und probiere, diese Datei dann wiederzugeben (mit eben jenem VLC).

Erst wenn dir das gelungen ist macht es überhaupt Sinn, an das embedded 
system zu denken.

Ein Hinweis noch: zwischen den Binärdaten kommen irgendwann nochmal HTTP 
Header mit frischen Metadaten für die Titelanzeige.

von Sascha W. (sascha-w)


Lesenswert?

Minetti schrieb:
> Ein Hinweis noch: zwischen den Binärdaten kommen irgendwann nochmal HTTP
> Header mit frischen Metadaten für die Titelanzeige.
nein, HTTP kommt da nicht noch mal. Die ICY-Metadaten im Stream haben 
nur 1Byte Header und dann die Daten variabler Länge als Text. Allerdings 
baut die der Server nur ein wenn der Client die Daten in der Anfrage 
auch angefordert hat.

Sascha

von Minetti (Gast)


Lesenswert?

Ah, genau, so war das. Irgendwie hatte ich im Kopf, dass die als HTTP 
kommen. Muss ein anderes Protokoll sein, mit dem ich das verwechselt 
hab.

Hier ist das übrigens gut beschrieben:
http://thecodeartist.blogspot.de/2013/02/shoutcast-internet-radio-protocol.html

von Thom E. (chrises)


Lesenswert?

Ich habe es nun geschafft, per Hterm ein paar empfangene Daten zu 
speichern (Format RAW) und mit VLC Player abzuspielen, danke für den 
Tipp!

Was ich feststelle: es sind einige "Lücken" im Lied und ich empfange nur 
rund 45 000 Byte, möchte ich 50 000 oder mehr empfangen (in den Buffer 
schreiben) bekomme ich nicht so viele.

Entweder liegt es an der HTTP GET Request, dass ich da einen anderen 
header oder so brauche, oder an Baudrate oder sonstwas.

Hoffentlich geht das alles von der Rechenleistung her auf, dass das ESP 
die Daten lückenlos empfangen und per Uart an den µC übertragen kann.


Achja: ich lasse den Empfangsbuffer nun nur einmal beschreiben statt 
zyklisch und übertrage die Daten an den PC mittels HAL_Transmit anstelle 
von printf und UART1.


Edit: bei höherer Baudrate empfängt man auch mehr, da muss ich wohl noch 
etwas rumtesten. Jedoch bleiben die kurzen Lücken im Stream, könnte wohl 
doch aufgrund von irgendwelchen Steuerzeichen sein, oder?
Es wird ja immer sowas wie +IPD1142 etc gesendet, was nicht zum Lied 
dazugehört.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Gewöhnliche MP3 Streams haben mehr als 100.000 Bits pro Sekunde.

Die Kommunukation zwischen dem ESP Chip und dem µC läuft mit 115200 Baud 
ab, und da sind nicht nur die Rohdaten sondern auch Statusmeldungen mit 
drin.

Könnte knapp werden, findest du nicht?

von Thom E. (chrises)


Lesenswert?

Stefan U. schrieb:
> Gewöhnliche MP3 Streams haben mehr als 100.000 Bits pro Sekunde.
>
> Die Kommunukation zwischen dem ESP Chip und dem µC läuft mit 115200 Baud
> ab, und da sind nicht nur die Rohdaten sondern auch Statusmeldungen mit
> drin.
>
> Könnte knapp werden, findest du nicht?

Hallo,

ich habe die Baudrate nun auf 921600 erhöht und kann schnell genug 
empfangen, denke ich. Derzeit habe ich es so gelöst, dass ich den 
Empfangsbuffer nur einmal mit 300kB beschreibe und dann per Hterm 
auslese.

Das klappt soweit auch, einziges Problem ist, bei der Wiedergabe des 
Ausschnitts sind alle ~500ms Lücken, also hört man zwar alles aber mit 
Mini-Unterbrechungen.
Aber von der Geschwindikeit scheint es zu klappen, habe nun auch die 
Variante mit den 128kbps stream verwendet.

Die Ausgabe klingt mit Winamp besser als mit VLC.

Jetzt bin ich erstmal am rätseln, wieso diese Lücken in der Ausgabe 
sind.

Anschließen muss ich dann schauen, ob die Audio-Ausgabe und das 
Empfangen parallel gut laufen können und wie ich die beiden Buffer 
handeln kann.

: Bearbeitet durch User
von Sascha W. (sascha-w)


Lesenswert?

Chris E. schrieb:
> Ich habe es nun geschafft, per Hterm ein paar empfangene Daten zu
> speichern (Format RAW) und mit VLC Player abzuspielen, danke für den
> Tipp!
wie? parallel vom ESP abgegriffen?

> Edit: bei höherer Baudrate empfängt man auch mehr, da muss ich wohl noch
> etwas rumtesten. Jedoch bleiben die kurzen Lücken im Stream, könnte wohl
> doch aufgrund von irgendwelchen Steuerzeichen sein, oder?
> Es wird ja immer sowas wie +IPD1142 etc gesendet, was nicht zum Lied
> dazugehört.
vielleicht solltest du dir doch mal die Doku der AT-Firmware ansehen, 
das könnte schon dazugehören

Sascha

Edit:
noch mal geschaut ...
https://github.com/espressif/ESP8266_AT/wiki/IPD

: Bearbeitet durch User
von thom (Gast)


Lesenswert?

Habe den Live-Stream nun zum laufen gebracht.
Das ESP schickt immer wieder diese +IPD dazu, welche herausgefiltert 
werden müssen, dann wird das Lied richtig wiedergegeben.

Ich hätte noch eine Frage, falls das jemand überblickt. Der Stream hängt 
sich ziemlich selten mal auf, ich vermute, wenn ein Teilstring vom +IPD 
am Ende oder am Anfang meines Empfangsbuffers steht.


der ganze String, der herausgefiltert wird, lautet wie folgt: (1412 kann 
manchmal auch was anderes sein, je nach länge der daten, aber zu 98% ist 
es 1412)

\r\nOK\r\n\r\n+IPD,1412:

diesen Filtere ich innerhalb der ISR mit den IF-Abfragen.
Wie man sieht, gibt es ein Problem, wenn z.B. an Stelle 
empfangsbuffer[239997] das \r\nOK anfängt, da es dann nicht mehr 
herausgefiltert wird und bei empfangsbuffer[0] ebenfalls nicht.

Hätte jemand eine Idee, wie ich das umgehen könnte?

LG
1
char empfangsbuffer[240000];
2
uint32_t receivezaehler=0;
3
4
void USART6_IRQHandler(void)
5
{
6
  if( __HAL_UART_GET_IT(&huart6, UART_IT_RXNE) != RESET ) {  // Receive interrupt triggered
7
8
    if(  receivezaehler < sizeof(empfangsbuffer) )
9
    {
10
          empfangsbuffer[receivezaehler]=huart6.Instance->RDR;
11
12
13
          if(receivezaehler>=17){
14
          if((empfangsbuffer[receivezaehler]==':'&&empfangsbuffer[receivezaehler-2]==','&&empfangsbuffer[receivezaehler-3]=='D'&&empfangsbuffer[receivezaehler-4]=='P'&&empfangsbuffer[receivezaehler-5]=='I'&&empfangsbuffer[receivezaehler-4]=='+'))
15
              {receivezaehler-=14;trashflag=1;}
16
17
          if((empfangsbuffer[receivezaehler]==':'&&empfangsbuffer[receivezaehler-3]==','&&empfangsbuffer[receivezaehler-4]=='D'&&empfangsbuffer[receivezaehler-5]=='P'&&empfangsbuffer[receivezaehler-6]=='I'&&empfangsbuffer[receivezaehler-7]=='+'))
18
              {receivezaehler-=15;trashflag=1;}
19
20
          if((empfangsbuffer[receivezaehler]==':'&&empfangsbuffer[receivezaehler-4]==','&&empfangsbuffer[receivezaehler-5]=='D'&&empfangsbuffer[receivezaehler-6]=='P'&&empfangsbuffer[receivezaehler-7]=='I'&&empfangsbuffer[receivezaehler-8]=='+'))
21
              {receivezaehler-=16;trashflag=1;}
22
23
          if((empfangsbuffer[receivezaehler]==':'&&empfangsbuffer[receivezaehler-5]==','&&empfangsbuffer[receivezaehler-6]=='D'&&empfangsbuffer[receivezaehler-7]=='P'&&empfangsbuffer[receivezaehler-8]=='I'&&empfangsbuffer[receivezaehler-9]=='+'))
24
              {receivezaehler-=17;trashflag=1;}
25
          }
26
27
          if(trashflag!=1)
28
            receivezaehler=receivezaehler+1;
29
          else
30
            trashflag=0;
31
32
          if(receivezaehler==240000)
33
            receivezaehler=0;
34
    }
35
36
37
  }
38
39
}

von Stefan F. (Gast)


Lesenswert?

Ich würde das anders angehen. Der ESP Chip empfängt den Stream in Form 
von Paketen. Jedes Paket wird durch eine +IPD Nachricht signalisiert und 
hat eine maximale Größe von WIFICLIENT_MAX_PACKET_SIZE (1460 Bytes). Die 
konkrete Anzahl der Bytes steht inter +IPD.

Ich würde die Endlos-Schleife im Programm also mit folgenden 
Arbeitsschritten füllen:

1) Warte auf +IPD,
2) Warte auf noch ein Komma
3) Warte auf den Doppelpunkt
4) Die Anzahl der Bytes steht zwischen dem zweiten Komma und dem 
Doppelpunkt
5) Warte auf genau so viele Bytes und leite diese an den MP3 Decoder 
weiter

Danach geht es wieder bei 1 weiter.
Wenn das "Warten" länger als 1 Sekunde dauert, breche ab und fange 
wieder bei 1 an.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.