Aktuelle Zeit: 18.01.2021 18:06

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Kleiner UDP Server für Arduino & Co Projekte
BeitragVerfasst: 18.07.2020 11:51 
Offline

Registriert: 21.06.2020 20:15
Hallo,

mit einem ESP32 (https://www.espressif.com/en/products/s ... 2/overview) und der Firmware ESP Easy (https://www.letscontrolit.com/wiki/inde ... le=ESPEasy) lese ich die Raumtemperatur aus. Der Sensor ist ein HDC1080, aber das nur am Rande.

Nun wollte ich gerne diese Daten per WLAN (per UDP) auf einen beliebigen Computer senden und dort anzeigen lassen. Da ich ja -Ironie on- der geborene Programmierer bin -Ironie off- habe ich mir ein kleines Programm erstellt welches diese Aufgabe erledigt. Im Endeffekt soll es ja Spaß machen.

Die Software läuft auf einem MAC und ich vermute auf Windows sollte das auch funktionieren. Allerdings habe ich das nicht getestet.

Konstruktive Vorschläge zur Verbesserung sind sehr willkommen. Bashing wird nach >/dev/null befördert.

Mir ist klar das dieses Programm kein Masterpice ist. Aber wenn ich mir die aktuellen Beispiele auf http://www.PureArea.net ansehe (ich mag diese Seite sehr) sind diese extrem alt und funktionieren teilweise nicht mehr mit der aktuellen PB Version. Vielleicht kann ein einfaches Programm wie dieses dem einen oder anderen eine Starthilfe geben.
Gruß Christian

Code:
EnableExplicit

Define param = 0
Define EventID = 0
Define Quit = 0

Global Info$, T$, H$, Window_0, Button_0, String_0, Text_0, String_1, Text_1

Enumeration FormFont
  #Font_Window_0_0
EndEnumeration

LoadFont(#Font_Window_0_0,".SF NS", 14)


Procedure OpenWindow_0(x = 0, y = 0, width = 400, height = 180)
  Window_0 = OpenWindow(#PB_Any, x, y, width, height,  "Thermometer", #PB_Window_SystemMenu)
  Button_0 = ButtonGadget(#PB_Any, 280, 124, 100, 25, "Quit")
  String_0 = StringGadget(#PB_Any, 140, 42, 70, 25, "")
  SetGadgetFont(String_0, FontID(#Font_Window_0_0))
  Text_0 = TextGadget(#PB_Any, 50, 44, 80, 25, "Temperatur")
  String_1 = StringGadget(#PB_Any, 140, 120, 70, 25, "")
  SetGadgetFont(String_1, FontID(#Font_Window_0_0))
  Text_1 = TextGadget(#PB_Any, 50, 123, 80, 25, "Luftfeuchte")
  SetWindowColor(Window_0,  RGB(27,159,186))
EndProcedure

Procedure Window_0_Events(event)
  Select event
    Case #PB_Event_CloseWindow
      ProcedureReturn #False

    Case #PB_Event_Menu
      Select EventMenu()
      EndSelect

    Case #PB_Event_Gadget
      Select EventGadget()
      EndSelect
  EndSelect
  ProcedureReturn #True
EndProcedure





Procedure server(param)
  Define *buffer = 0
  Define server  = 0
  Define size = 0
  Define param = 0
 
   
*buffer = AllocateMemory(2048)
server = CreateNetworkServer(0, 6600, #PB_Network_UDP)

If *buffer And server
  Repeat
    Delay(200)
    If NetworkServerEvent() = #PB_NetworkEvent_Data
      size = ReceiveNetworkData(EventClient(),*buffer,2048)
      Info$ = (PeekS(*buffer,size,#PB_Ascii))
     
     
      If Left(Info$,11) = "Temperature"
          T$=Right(Info$,4)
        EndIf
       
        If Left(Info$,8) = "Humidity"
          H$=Right(Info$,4)
        EndIf
     
     
    EndIf
  ForEver
EndIf
EndProcedure


OpenWindow_0()
If  InitNetwork()<>0
 
  If  CreateNetworkServer(0, 6600, #PB_Network_UDP)<>0
       CreateThread(@server(), param)
   
  EndIf
EndIf




Repeat
   Delay(100)
  EventID =  WaitWindowEvent(50)
 
  SetGadgetText(String_0, T$)
  SetGadgetText(String_1, H$)
 
  Select EventID
    Case #PB_Event_CloseWindow
      Quit = 1
     
      Case 3         
          Quit = 1
   
  EndSelect
 Until Quit = 1 Or EventID = #PB_Event_CloseWindow
 


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Kleiner UDP Server für Arduino & Co Projekte
BeitragVerfasst: 18.07.2020 12:31 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Ein Arduino habe ich nicht,
aber wie man besser mit Threads umgeht schon und wie man dann aus dem Thread die Daten an die GUI bekommt.
Bei macOS und Linux darf man aus Thread nicht die Gadgets aktualisieren.

Siehe Mini Thread Control Beispiel 3

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.7x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf My Webspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Kleiner UDP Server für Arduino & Co Projekte
BeitragVerfasst: 18.07.2020 13:00 
Offline

Registriert: 21.06.2020 20:15
Hallo Michael,

danke für den Hinweis. Wie Du sicher unschwer an meinem Code erkennen kannst wird das etwas dauern bis ich Dein Beispiel verstehen/begreifen kann.


Zitat:
"Bei macOS und Linux darf man aus Thread nicht die Gadgets aktualisieren."

Warum darf man das nicht?

Gruß Christian


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Kleiner UDP Server für Arduino & Co Projekte
BeitragVerfasst: 18.07.2020 13:37 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
ChristianH hat geschrieben:
Hallo Michael,

danke für den Hinweis. Wie Du sicher unschwer an meinem Code erkennen kannst wird das etwas dauern bis ich Dein Beispiel verstehen/begreifen kann.


Zitat:
"Bei macOS und Linux darf man aus Thread nicht die Gadgets aktualisieren."

Warum darf man das nicht?

Gruß Christian

Führt zum Crash da diese vom der OS nicht Threadsafe sind.


Sorry, hatte etwas zu viel Langeweile

Noch nicht getestet
Code:
;-TOP

;- Begin Mini Thread Control

;  by mk-soft, Version 1.08, 20.10.2019

CompilerIf Not #PB_Compiler_Thread
  CompilerError "Use Compiler-Option ThreadSafe!"
CompilerEndIf

Structure udtThreadControl
  ThreadID.i
  UserID.i
  Signal.i
  Pause.i
  Exit.i
EndStructure

Procedure StartThread(*Data.udtThreadControl, *Procedure) ; ThreadID
  If Not IsThread(*Data\ThreadID)
    *Data\Exit = #False
    *Data\Pause = #False
    *Data\ThreadID = CreateThread(*Procedure, *Data)
  EndIf
  ProcedureReturn *Data\ThreadID
EndProcedure

Procedure StopThread(*Data.udtThreadControl, Wait = 1000) ; Void
  If IsThread(*Data\ThreadID)
    *Data\Exit = #True
    If *Data\Pause
      *Data\Pause = #False
      SignalSemaphore(*Data\Signal)
    EndIf
    If Wait
      If WaitThread(*Data\ThreadID, Wait) = 0
        KillThread(*Data\ThreadID)
      EndIf
      *Data\ThreadID = 0
      *Data\Pause = #False
      *Data\Exit = #False
      If *Data\Signal
        FreeSemaphore(*Data\Signal)
        *Data\Signal = 0
      EndIf
    EndIf
  EndIf
EndProcedure

Procedure FreeThread(*Data.udtThreadControl, Stop = #True, Wait = 1000) ; True or False
  If IsThread(*Data\ThreadID)
    If Stop
      StopThread(*Data, Wait)
      FreeStructure(*Data)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  Else
    If *Data\Signal
      FreeSemaphore(*Data\Signal)
    EndIf
    FreeStructure(*Data)
    ProcedureReturn #True
  EndIf
EndProcedure

Procedure ThreadPause(*Data.udtThreadControl) ; Void
  If IsThread(*Data\ThreadID)
    If Not *Data\Signal
      *Data\Signal = CreateSemaphore()
    EndIf
    If Not *Data\Pause
      *Data\Pause = #True
    EndIf
  EndIf
EndProcedure

Procedure ThreadResume(*Data.udtThreadControl) ; Void
  If IsThread(*Data\ThreadID)
    If *Data\Pause
      *Data\Pause = #False
      SignalSemaphore(*Data\Signal)
    EndIf
  EndIf
EndProcedure

;- End Mini Thread Control

; ****

;- UDP Server
InitNetwork()

; ---- String Helper ----

Procedure AllocateString(String.s) ; Result = Pointer
  Protected *mem.string = AllocateStructure(String)
  If *mem
    *mem\s = String
  EndIf
  ProcedureReturn *mem
EndProcedure

Procedure.s FreeString(*mem.string) ; Result String
  Protected r1.s
  If *mem
    r1 = *mem\s
    FreeStructure(*mem)
  EndIf
  ProcedureReturn r1
EndProcedure

; ----


Enumeration #PB_Event_FirstCustomValue
  #MyEvent_ThreadSendString
  #MyEvent_ThreadFinished
EndEnumeration

Enumeration Window
  #Main
EndEnumeration

Enumeration Gadget
  #ListLogging
  #StringData1
  #StringData2
  #ButtonStart
  #ButtonPauseResume
  #ButtonStop
EndEnumeration


; Extends always own data structure with structure from thread control
Structure udtThreadData Extends udtThreadControl
  ; GUI Data
  Window.i
  Logging.i
  Data1.i
  Data2.i
  ; Server
  Server.i
  Port.i
EndStructure

Declare MyThread(*Data.udtThreadData)

; Create Data always with AllocateStructure 
Global *th1.udtThreadData = AllocateStructure(udtThreadData)
*th1\UserID = 1
*th1\Window = #Main
*th1\Logging = #ListLogging
*th1\Data1 = #StringData1
*th1\Data2 = #StringData2
*th1\Port = 6600

Procedure Main()
  Protected info.s
 
  If OpenWindow(#Main, 50, 50, 600, 400, "Mini Thread Control", #PB_Window_SystemMenu)
    ListViewGadget(#ListLogging, 5, 5, 590, 320)
    StringGadget(#StringData1, 5, 330, 290, 25, "", #PB_String_ReadOnly)
    StringGadget(#StringData2, 305, 330, 290, 25, "", #PB_String_ReadOnly)
    ButtonGadget(#ButtonStart, 5, 365, 120, 30, "Start")
    ButtonGadget(#ButtonPauseResume, 130, 365, 120, 30, "Pause")
    ButtonGadget(#ButtonStop, 255, 365, 120, 30, "Stop")
   
    DisableGadget(#ButtonPauseResume, #True)
   
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          FreeThread(*th1)
          Break
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #ButtonStart
              StartThread(*th1, @MyThread())
            Case #ButtonPauseResume
              If IsThread(*th1\ThreadID)
                If Not *th1\Pause
                  ThreadPause(*th1)
                  SetGadgetText(#ButtonPauseResume, "Resume")
                Else
                  ThreadResume(*th1)
                  SetGadgetText(#ButtonPauseResume, "Pause")
                EndIf
              EndIf
            Case #ButtonStop
              StopThread(*th1)
              SetGadgetText(#ButtonPauseResume, "Pause")
             
          EndSelect
         
        Case #MyEvent_ThreadSendString
          Select EventGadget()
            Case #ListLogging
              ; Receive string over event data
              AddGadgetItem(#ListLogging, -1, FreeString(EventData()))
              ; Small trick to move last item
              SetGadgetState(#ListLogging, CountGadgetItems(#ListLogging) - 1)
              SetGadgetState(#ListLogging, -1)
            Case #StringData1
              info = FreeString(EventData())
              SetGadgetText(#StringData1, info + " °C")
            Case #StringData2
              info = FreeString(EventData())
              SetGadgetText(#StringData2, info + " ??")
             
          EndSelect
         
      EndSelect
    ForEver
  EndIf
 
EndProcedure : Main()

End

Procedure MyThread(*Data.udtThreadData)
  Protected stringdata.s, cnt
  Protected *buffer, size
  Protected info.s
 
 
  ; Send string over PostEvent and parameter EventData
 
  With *Data
    stringdata = "Init Server " + \UserID
    PostEvent(#MyEvent_ThreadSendString, \Window, \Logging, 0, AllocateString(stringdata))
    ;TODO
    \Server = CreateNetworkServer(#PB_Any, \Port, #PB_Network_UDP)
    If \Server = 0
      stringdata = "Error: Create Server on Port " + \Port
      PostEvent(#MyEvent_ThreadSendString, \Window, \Logging, 0, AllocateString(stringdata))
      stringdata = "Finished Thread " + \UserID
      PostEvent(#MyEvent_ThreadSendString, \Window, \Logging, 0, AllocateString(stringdata))
      \ThreadID = 0
      ProcedureReturn 0
    EndIf
   
    *buffer = AllocateMemory(2048)
   
    stringdata = "Start Server " + \UserID
    PostEvent(#MyEvent_ThreadSendString, \Window, \Logging, 0, AllocateString(stringdata))
    ;TODO
    Repeat
      ; 1. Query on thread pause
      If \Pause
        stringdata = "Pause Thread " + \UserID
        PostEvent(#MyEvent_ThreadSendString, \Window, \Logging, 0, AllocateString(stringdata))
        WaitSemaphore(\Signal)
        stringdata = "Resume Thread " + \UserID
        PostEvent(#MyEvent_ThreadSendString, \Window, \Logging, 0, AllocateString(stringdata))
      EndIf
      ; 2. Query on thread cancel
      If \Exit
        Break
      EndIf
      ;TODO Cyle Process
      Select NetworkServerEvent()
        Case #PB_NetworkEvent_None
          Delay(100)
        Case #PB_NetworkEvent_Connect ; Only TCP/IP
          ;
        Case #PB_NetworkEvent_Disconnect ; Only TCP/IP
          ;                               ;
        Case #PB_NetworkEvent_Data
          size = ReceiveNetworkData(EventClient(), *buffer, 2048)
          info = (PeekS(*buffer, size, #PB_Ascii))
          If Left(info, 11) = "Temperature"
            stringdata = Right(info, 4)
            PostEvent(#MyEvent_ThreadSendString, \Window, \Data1, 0, AllocateString(stringdata))
          EndIf
          If Left(info, 8) = "Humidity"
            stringdata = Right(info, 4)
            PostEvent(#MyEvent_ThreadSendString, \Window, \Data2, 0, AllocateString(stringdata))
          EndIf
         
        EndSelect
         
    ForEver
   
    If \Exit
      ;TODO Thread Cancel
      stringdata = "Cancel Thread " + \UserID
      PostEvent(#MyEvent_ThreadSendString, \Window, \Logging, 0, AllocateString(stringdata))
    Else
      ;TODO Thread Finished
      stringdata = "Finished Thread " + \UserID
      PostEvent(#MyEvent_ThreadSendString, \Window, \Logging, 0, AllocateString(stringdata))
    EndIf
   
    stringdata = "Close Server " + \UserID
    PostEvent(#MyEvent_ThreadSendString, \Window, \Logging, 0, AllocateString(stringdata))
   
    CloseNetworkServer(\Server)
    FreeMemory(*buffer)
   
    ; 3. Clear ThreadID
    \ThreadID = 0
  EndWith
EndProcedure


_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.7x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf My Webspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Kleiner UDP Server für Arduino & Co Projekte
BeitragVerfasst: 18.07.2020 13:49 
Offline

Registriert: 21.06.2020 20:15
Hi Michael,

vielen Dank für eine Mühe. Der Code läuft auf dem Mac 1A und zeigt Temperatur und Luftfeuchte an. :allright:

Nun werde ich mir das ausdrucken und in Ruhe durchlesen und hoffen das mein Kopf schlau genug wird das zu verstehen. Vielleicht wird ja irgendwann
mal eine kleinen Wetterstation daraus. :lol:

Gruß Christian


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Kleiner UDP Server für Arduino & Co Projekte
BeitragVerfasst: 18.07.2020 14:13 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Mach dir auch mal Gedanken bei der Übertragung der Daten.
Bei Netzwerk gilt das gleiche wie bei serieller Kommunikation. Es wird der Empfangsbuffer ausgelesen.
Wenn etwas mal länger dauert, kann es passieren das die Daten nicht zusammenhängend bekommst oder schon ein teil der nächsten Daten.
Eventuell mit Steuerzeichen in den Daten arbeiten. #STX$ (StartOfText) und #ETX$ (EndOfText)

Link zum studieren: UdpServer

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.7x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf My Webspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Kleiner UDP Server für Arduino & Co Projekte
BeitragVerfasst: 18.07.2020 14:42 
Offline

Registriert: 21.06.2020 20:15
Ja danke für den Hinweis. Ich weiss das UDP ein verbindungsloses Protokoll ist und man da auf Anwendungsebene ein wenig Arbeit
reinstecken muss.

Aber dank Deiner Hilfe bin ich einen großen Schritt weiter und werde nun erst einmal meinen Wissensstand aufarbeiten. :lol:

Ich glaube ich habe PB seit ca. 20 Jahren registriert und komme ich immer wieder darauf zurück. Es ist eine tolle Sprache
und "eigentlich" nicht so sehr schwer. Aber Job und Familie und 1000 andere Dinge benötigen auch viel Zeit.

LG Christian


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 18 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye