Forum: PC-Programmierung Visual Basic UDP Empfangen mit ESP8266


von Gusi (Gast)


Lesenswert?

Guten Tag Forumsgemeinde,

mich plagt seit langer Zeit ein großes Problem. Ich habe einen ESP8266 
der mit UDP läuft. Der ESP funktioniert, ich kann via HTerm Kommandos 
per Uart senden, dieser schickt die Nachrichten raus und empfängt auch 
welche. Getestet mit dem PacketSender. Alles super.

Jetzt aber das Problem. ich möchte in meinem eigenen PC Programm in VB 
geschrieben gerne auch etwas empfangen können - das senden klappt auch 
hier problemlos.

Beim Empfangen geht nichts, ich bin ratlos. Die Funktionen laufen 
erstmal so durch aber ich bekomme nur leere Antworten. Hier die 
Funktionen:
1
Beim Start der Form rufe ich entsprechend einmalig InitializeReceiver() auf.
2
3
4
Private Sub InitializeReceiver()
5
        receivingClient = New UdpClient(port) 'Port
6
        receivingClient.EnableBroadcast = True
7
        receivingClient.Client.ReceiveTimeout = 1000
8
        receivePoint = New IPEndPoint(IPAddress.Any, port)
9
10
        Dim readThread As Thread = New Thread(New ThreadStart(AddressOf Receiver))
11
        readThread.Start()
12
    End Sub
13
14
    Private Sub Receiver()
15
        While (True)
16
            Dim recmsg = ""
17
18
            Try
19
                Dim data() As Byte = receivingClient.Receive(receivePoint)   'Receive incoming bytes  'Buffer for storing incoming bytes
20
                recmsg = Encoding.ASCII.GetString(data)       'Convert bytes back to string
21
            Catch ex As Exception
22
            End Try
23
24
            If Not recmsg = "" Then
25
                MsgBox(recmsg)
26
            End If
27
        End While
28
    End Sub


Was könnte das Problem sein?

von c-hater (Gast)


Lesenswert?

Gusi schrieb:

> Was könnte das Problem sein?

Wie so oft: du. Genauer gesagt, deine Faulheit, die dich davon 
abgehalten hat, die Beschreibung der verwendeten Klasse und deren 
Methoden zu lesen, bevor du sie benutzt.

Konkret:

1) Du verpasst der Receive-Methode einen falschen Parameter. Das ist ein 
"byref" Parameter, der dazu dient, etwas zurück zu geben. Und das, was 
da zurück gegeben wird, müsste sinngemäß im Stil deiner Nomenklatur 
"sendingPoint" heissen. Vielleicht wird dir mit dieser Information klar, 
warum es totaler Schwachsinn ist, hier "receivingPoint" zu 
referenzieren...

2) Du setzt einen Timeout, dir ist aber scheinbar nicht klar, dass das 
bedeutet, dass die blockierende Funktion immer nach Ablauf des Timeout 
zurückkehren wird und zwar auch dann, wenn sie nix empfangen hat. Dann 
halt ohne, sprich: mit leerem Ergebnis.

3) Das Gehampele mit einer blockierenden Funktion in einem zusätzlichen 
Thread kannst du dir sparen. Der UDPClient unterstützt nämlich von Hause 
aus asynchrone Zugriffsmethoden. Da macht das System das Gehampele mit 
den zusätzlichen Threads. Sehr viel effizienter als du das kannst...

von Gusi (Gast)


Lesenswert?

c-hater schrieb:
> Gusi schrieb:
>
>> Was könnte das Problem sein?
>
> Wie so oft: du. Genauer gesagt, deine Faulheit, die dich davon
> abgehalten hat, die Beschreibung der verwendeten Klasse und deren
> Methoden zu lesen, bevor du sie benutzt.
Ich bin kein Experte und komme einfach nicht mehr weiter. Ich habe viel 
gelesen, im Netz und auch in den Klassen. Ich weiß es einfach nicht mehr 
an diesem Punkt, sonst würde ich nicht fragen. Ich sitze da bereits 2 
Monate dran.

>
> Konkret:
>
> 1) Du verpasst der Receive-Methode einen falschen Parameter. Das ist ein
> "byref" Parameter, der dazu dient, etwas zurück zu geben. Und das, was
> da zurück gegeben wird, müsste sinngemäß im Stil deiner Nomenklatur
> "sendingPoint" heissen. Vielleicht wird dir mit dieser Information klar,
> warum es totaler Schwachsinn ist, hier "receivingPoint" zu
> referenzieren...
Verstehe ich leider nicht. receivingPoint ist ja nur der IP Endpunkt, 
von dem ich Daten erwarte. Wie muss das denn aussehen? Beispiele wären 
hilfreich.


> 2) Du setzt einen Timeout, dir ist aber scheinbar nicht klar, dass das
> bedeutet, dass die blockierende Funktion immer nach Ablauf des Timeout
> zurückkehren wird und zwar auch dann, wenn sie nix empfangen hat. Dann
> halt ohne, sprich: mit leerem Ergebnis.
Korrekt. Den habe ich gesetzt, weil er die Funktion nie beendet hat. 
Auch wenn ich daten Sende. Nach einem Timeout ist schon klar das das 
Ergebnis leer ist, wenn nichts empfangen wurde, aber ich sende ja alle 
100ms etwas mit 10 bytes. Es ist immer leer, resp. ohne Timeout kommt er 
nie aus der Funktion


> 3) Das Gehampele mit einer blockierenden Funktion in einem zusätzlichen
> Thread kannst du dir sparen. Der UDPClient unterstützt nämlich von Hause
> aus asynchrone Zugriffsmethoden. Da macht das System das Gehampele mit
> den zusätzlichen Threads. Sehr viel effizienter als du das kannst...
Okay und die wären? BeginRecieve und EndReceive? Das hatte ich getestet, 
bekomme da nichts, kann aber auch sein das ich die falsch implementiert 
habe. So oder so müsste ich aber doch was empfangen.

Wie geht es denn richtig?

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

sendet der ESP nur an die Adresse deines Rechners oder als Broadcast?
kommen die Pakete auf deinem Rechner an? Mit Wireshark prüfen.
welche Windowsversion?
die Windows Firewall blockt i.d.R. alle nicht zuordenbaren Eingehenden 
Pakete, wenn du nicht zufällig vorher was von dem selben Port gesendet 
hast kommt nix rein. Dann musst du das Programm in der Firewall 
freigeben, manchmal fragt Windows auch beim ersten Start selbst danach.

Sascha

von Peter Z. (hangloose)


Lesenswert?

Der Grund warum das bei dir nicht funktioniert ist wahrscheinlich 
folgender. Dein VB Socket Programm erstellt automatisch 2 Ports.
Einmal den remotePort und einen zufällig localPort
"Dynamically Allocated Ports (49.152 - 65.535)"
Jetzt sendest du an deinen remotePort deine Daten und dein remoteDevice
sendet Daten an dich zurück auf dem localPort den du aber nicht 
abgefragt hast. Darum empfängst du auch nichts da du wahrscheinlich den 
remotePort ansiehst.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Peter Z. schrieb:

> Der Grund warum das bei dir nicht funktioniert ist wahrscheinlich
> folgender. Dein VB Socket Programm erstellt automatisch 2 Ports.
> Einmal den remotePort und einen zufällig localPort
> "Dynamically Allocated Ports (49.152 - 65.535)"

Nein, sicher nicht. Das gezeigte Programm erstellt genau einen Socket 
und bindet den an alle vorhandenen Interfaces. Außerdem erlaubt es den 
Empfang von Broadcasts. Soweit ist das komplett richtig. Der Receiver 
kann also Unicast- und Broadcast-Pakete aus allen angeschlossenen Netzen 
empfangen, sofern sie an den UDP-Port "port" gerichtet sind, und 
entweder eine korrekte Zieladresse haben oder eben eine 
Broadcast-Adresse.

von Peter Z. (hangloose)


Lesenswert?

Naja, ich vermute mal das er nicht nur den Receiver Teil in seinem VB 
Programm hat, sonder auch den TX Teil.

Wie auch immer bei mir funktioniert das Gehampel mit einem RX Thread
sehr gut.

Hier noch ein Beispiel an dem man sich orientieren kann:
Seite 296, 297

https://books.google.de/books?id=qWzgaTw2s3AC&pg=PA294&lpg=PA294&dq=localEP+udp+vb&source=bl&ots=QLWwFYyci0&sig=ACfU3U2pLE0btFkJuzenD365b-BTIPEkFA&hl=de&sa=X&ved=2ahUKEwiXj_7jr9HmAhVRPFAKHQy2CAMQ6AEwAnoECAoQBA#v=onepage&q=localEP%20udp%20vb&f=false

Vielleicht hat ja c-hater auch noch ein Codebeipiel für eine Async 
Lösung des Problems ala...

Sub receive(ar As IAsyncResult)
Dim res() As Byte = UdpListener.EndReceive(ar, ep)
If ar.IsCompleted Then
UdpListener.BeginReceive(CallBack, "")
End If
End Sub

usw...

Aber egal "Gusi" scheint eh die Schnauze voll zu haben.

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


Lesenswert?

Peter Z. schrieb:
> Naja, ich vermute mal das er nicht nur den Receiver Teil in seinem VB
> Programm hat, sonder auch den TX Teil.
Dem Thread-Titel nach ist davon auszugehen das ein ESP8266 sendet.

Sascha

von Gusi (Gast)


Lesenswert?

Peter Z. schrieb:
> Naja, ich vermute mal das er nicht nur den Receiver Teil in seinem
> VB
> Programm hat, sonder auch den TX Teil.
>
> Wie auch immer bei mir funktioniert das Gehampel mit einem RX Thread
> sehr gut.
>
> Hier noch ein Beispiel an dem man sich orientieren kann:
> Seite 296, 297
>
> 
https://books.google.de/books?id=qWzgaTw2s3AC&pg=PA294&lpg=PA294&dq=localEP+udp+vb&source=bl&ots=QLWwFYyci0&sig=ACfU3U2pLE0btFkJuzenD365b-BTIPEkFA&hl=de&sa=X&ved=2ahUKEwiXj_7jr9HmAhVRPFAKHQy2CAMQ6AEwAnoECAoQBA#v=onepage&q=localEP%20udp%20vb&f=false
>
> Vielleicht hat ja c-hater auch noch ein Codebeipiel für eine Async
> Lösung des Problems ala...
>
> Sub receive(ar As IAsyncResult)
> Dim res() As Byte = UdpListener.EndReceive(ar, ep)
> If ar.IsCompleted Then
> UdpListener.BeginReceive(CallBack, "")
> End If
> End Sub
>
> usw...
>
> Aber egal "Gusi" scheint eh die Schnauze voll zu haben.


Hallo Peter,

könntest du mir deinen vollständigen RX-Teil bitte hier reinstellen? Das 
wäre sehr hilfreich. Einen TX Teil habe ich, dort wird der Port 
geöffnet, die Daten gesendet und der Port wieder geschlossen. Das klappt 
sehr gut. Wie gesagt, mit dem Packet-Sender (PC Programm) sehe ich auch, 
dass der ESP sendet. Klappt alles. Nur ich bekomme nichts.

von Peter Z. (hangloose)


Lesenswert?

Mein RX Teil besteht aus Seite 296 des Links,
angepasst an meine Bedürfnisse.

Damit solltest du eigentlich weiter kommen.

Was du noch machen kannst ist mit dem "Device Monitoring Studio"
die Pakete checken. Das würde ich dir sehr empfehlen.
Und den Log hier mal posten...

Du kannst dich auch hier anmelden und dein VB Projekt posten,
dann kann man es sich ja mal anschauen.

: Bearbeitet durch User
von Gusi (Gast)


Lesenswert?

Peter Z. schrieb:
> Mein RX Teil besteht aus Seite 296 des Links,
> angepasst an meine Bedürfnisse.
>
> Damit solltest du eigentlich weiter kommen.
>
> Was du noch machen kannst ist mit dem "Device Monitoring Studio"
> die Pakete checken. Das würde ich dir sehr empfehlen.
> Und den Log hier mal posten...
>
> Du kannst dich auch hier anmelden und dein VB Projekt posten,
> dann kann man es sich ja mal anschauen.

Hallo Peter und frohes neues Jahr!

Ich habe oben in der Classe wie folgt hinzugefügt:
1
Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)


Dann habe ich unter den Variablen diese sub hinzugefügt:
1
 Public Sub GetWiFi()
2
        Dim localEP As New IPEndPoint(IPAddress.Any, 21105)
3
        listener.Bind(localEP)
4
5
        While True
6
            If listener.Poll(1000, SelectMode.SelectRead) Then
7
                MsgBox("ok")
8
                Dim bytesToRead As Integer = listener.Available
9
                Dim buffer(bytesToRead) As Byte
10
11
                listener.Receive(buffer, bytesToRead, SocketFlags.None)
12
13
                Dim message As String = System.Text.Encoding.ASCII.GetString(buffer, 0, bytesToRead)
14
15
                If Not message = "" Then
16
                    MsgBox(message)
17
                End If
18
            End If
19
20
            Application.DoEvents()
21
        End While
22
23
24
        listener.Close()
25
    End Sub


Wenn ich jetzt vom ESP sende, empfange ich leider nichts. Er geht 
nichtmal in die IF rein, wo "OK" kommen sollte. Der ESP sendet auf Port 
21105, habe ich doch richtig gemacht, oder? Mit der Port angabe? Oder 
muss ich dort meinen Port eintragen, sprich an den Port wo der ESP 
hinsenden soll?

von Gusi (Gast)


Lesenswert?

Ich habe nochmal einen Test gemacht.

VB Programm, ESP und PacketSender Programm.

Sende ich vom PacketSender was an den Port 21105 zum ESP, empfange ich 
die Daten, der ESP sendet was zurück, wird empfangen. Okay.

Dann sende ich mal vom PacketSender was an den Port 1100 (den habe ich 
mal bei dem Receiver eingetragen in meinem VB Programm). Empfange nichts 
:(

von Peter Z. (hangloose)


Lesenswert?

Die Empfangsroutine sieht ok aus.
Wie wird dein ESP32 angesteuert?
Über Arduino? AT Befehle? ESP-IDF?
Wie sieht der Code dazu aus?

Empfängt dein VB Programm etwas wenn du mit dem packetsender etwas 
sendest ohne ESP

von Gusi (Gast)


Lesenswert?

Peter Z. schrieb:
> Die Empfangsroutine sieht ok aus.
> Wie wird dein ESP32 angesteuert?
> Über Arduino? AT Befehle? ESP-IDF?
> Wie sieht der Code dazu aus?
>
> Empfängt dein VB Programm etwas wenn du mit dem packetsender etwas
> sendest ohne ESP

Nein, das ist es ja. Ich habe jetzt mal was anderes gemacht, damit geht 
es jetzt komischerweise, und zwar wie foglt:
1
Public Function InitializeGetUDP()
2
        subscriber = New UdpClient(2000)
3
        subscriber.Client.ReceiveTimeout = 20
4
        subscriber.Client.Blocking = False
5
6
        'Dim readThread As Thread = New Thread(New ThreadStart(AddressOf ReceiveUDP))
7
        'readThread.Start()
8
        Timer7.Start()
9
    End Function
10
11
    Public Function ReceiveUDP()
12
        Try
13
            Dim ep As IPEndPoint = New IPEndPoint(IPAddress.Any, 0)
14
            Dim rcvbytes() As Byte = subscriber.Receive(ep)
15
            TBRcv.Text = Encoding.ASCII.GetString(rcvbytes)
16
        Catch ex As Exception
17
        End Try
18
    End Function

Dann habe ich die ReceiveUDP in einen Timer gepackt, der jede Sekunde 
einmal pollt. Das finde ich aber nicht optimal. Mache ich das wieder mit 
einem Thread (siehe auskommentierte Sachen), dann empfange ich wieder 
nichts, verrückt irgendwie.

von Gusi (Gast)


Lesenswert?

Leider zu früh gefreut. Ich kann zwar damit was empfangen wenn ich von 
meinen PC an meinen PC sende (also über den PacketSender an meine locale 
Ip mit dem Port 2000 wie angegeben) empfange ich Daten. Kein Problem.

Kommen die Daten von einem anderen Gerät, empfange ich wieder nichts. 
Ich werde noch verrückt, was ist das?

von Peter Z. (Gast)


Lesenswert?

Darum sagte ich ja installiere das Device Monitoring Studio und schau 
dir die Datenpakete an was zum Device und vom Device gesendet wird, dann 
bist vielleicht schlauer.

von Sascha W. (sascha-w)


Lesenswert?

Gusi schrieb:
> Ich habe nochmal einen Test gemacht.
>
> VB Programm, ESP und PacketSender Programm.
>
> Sende ich vom PacketSender was an den Port 21105 zum ESP, empfange ich
> die Daten,
am ESP??
> der ESP sendet was zurück, wird empfangen. Okay.
deutet auf ein Problem mit der Win-Firewall hin - meine Fragen vom 
25.12. hast du ja nicht beantwortet.

Sascha

von Gusi (Gast)


Lesenswert?

Sascha W. schrieb:
> Gusi schrieb:
>> Ich habe nochmal einen Test gemacht.
>>
>> VB Programm, ESP und PacketSender Programm.
>>
>> Sende ich vom PacketSender was an den Port 21105 zum ESP, empfange ich
>> die Daten,
> am ESP??
>> der ESP sendet was zurück, wird empfangen. Okay.
> deutet auf ein Problem mit der Win-Firewall hin - meine Fragen vom
> 25.12. hast du ja nicht beantwortet.
>
> Sascha

Ich war ein paar Tage weg, geht immer noch nicht. Ich empfange ja Daten. 
Mit dem PacketSender Programm kann ich Daten an den ESP senden und 
empfangen. Geht. Es liegt an meiner PC Software VB. Senden von dort geht 
ebenso, aber ich bekomme nichts. Nichts von außerhalb des PCs. Komisch 
ist, wenn ich mit dem PaketSender vom PC an mich selber sende, empfängt 
das Programm was. Komisch oder?

von Gusi (Gast)


Lesenswert?

Okay mir kam gerade die Erleuchtung. Wenn ich sende, dann schließe ich 
danach den Port. Sprich der ESP sendet dann aber ins leere. Jetzt habe 
ich es so gemacht, dass ich im VB Programm den gleichen Client für 
Senden und Empfangen nutze, und siehe da, es geht mit der Variante wie 
ich die hatte. Polle per Timer jetzt die Funktion und erhalte meine 
Werte. Danke nochmals.

von Sascha W. (sascha-w)


Lesenswert?

Zum Empfangen brauchst du einen Socket der an dein gewünschtes Port 
gebunden ist. Dieses kannst du auch zum Senden nehmen, aber du kannst 
auch jedes mal ein neues Socket öffnen.

Sascha

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.