Very slow loop and don't know why :(

Just starting out? Need help? Post your questions and find answers here.
Walko
User
User
Posts: 11
Joined: Thu Mar 26, 2020 6:08 pm

Very slow loop and don't know why :(

Post by Walko »

Hello,

So first of all I am an extreme beginner in Purebasic and programming in general.

I found on this forum very nice example for handling serial port that works very well.
Now, I need to add some stuff to do inside the infinite loop but It seems that the loop is very very slow.

I just add to this found example a global variable and the ElapsedMilliseconds() function to see how fast the loop executes.
It seems that the execution speed is fast when I click a button ( or an event ), it seems to unlock something.

Do you know why and how to fix this ?

Thank you very much :)

Code: Select all

XIncludeFile "serial3.pbf"

EnableExplicit

#COMMaxPorts = 30

Enumeration #PB_Event_FirstCustomValue
  #ComThread_Started
  #ComThread_ByteReceived
  #ComThread_LineReceived
  #ComThread_Finished
EndEnumeration

Enumeration
  #SendString
  #SendButton
  #ReceiveText
  #ReceiveEdit
EndEnumeration

Global val

Structure ThreadParameterStructure
  Thread.i
  Semaphore.i
  Com$
  Com.i
  Receive$
  Exit.i
EndStructure


Global NewList COMUsablePorts.s()


Procedure COMGetAvailablePorts()

  Protected NewList COMPortNameList.s()
  Protected i.i, Directory.i, Com.i
 
 
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    For i = 1 To #COMMaxPorts
      AddElement(COMPortNameList())
      COMPortNameList() = "COM" + Str(i)
    Next i
  CompilerEndIf
 
  ForEach COMPortNameList()
    Com = OpenSerialPort(#PB_Any, COMPortNameList(), 115200, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1, 1)
    If Com
      AddElement(COMUsablePorts())
      COMUsablePorts() = COMPortNameList()
      CloseSerialPort(Com)
    EndIf
  Next
 
  FreeList(COMPortNameList())
 
EndProcedure


Procedure ComThread(*Parameter.ThreadParameterStructure)
 
  Protected Byte.a, ReceivedBytes.i
 
 
  PostEvent(#ComThread_Started)
 
  *Parameter\Com = OpenSerialPort(#PB_Any, *Parameter\Com$, 115200, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
  If *Parameter\Com
   
    WriteSerialPortString(*Parameter\Com, "hello")
   
    Repeat
      If AvailableSerialPortInput(*Parameter\Com)
        If ReadSerialPortData(*Parameter\Com, @Byte, 1) = 1
          ReceivedBytes + 1
          PostEvent(#ComThread_ByteReceived, 0, 0, 0, ReceivedBytes)
          If Byte = #CR
            PostEvent(#ComThread_LineReceived)
            WaitSemaphore(*Parameter\Semaphore)
          Else
            *Parameter\Receive$ + Chr(Byte)
          EndIf
        EndIf
      Else
        Delay(10)
      EndIf
    Until *Parameter\Exit
   
    CloseSerialPort(*Parameter\Com)
   
  EndIf
 
  PostEvent(#ComThread_Finished)
 
EndProcedure


Define.i Event, Exit
Define ThreadParameter.ThreadParameterStructure

COMGetAvailablePorts()

OpenMain_menu()

ForEach COMUsablePorts()
  AddGadgetItem(#ComCombo, -1, COMUsablePorts())
Next
SetGadgetState(#ComCombo, 0)

ThreadParameter\Semaphore = CreateSemaphore()

Repeat
 
  Event = WaitWindowEvent()
 
  Select Event
    Case #ComThread_Started
      SetGadgetText(#StartButton, "Disconnect")
      DisableGadget(#ComCombo, #True)
     
    Case #ComThread_ByteReceived
      StatusBarText(0, 1, Str(EventData()), #PB_StatusBar_Center)
     
    Case #ComThread_LineReceived
      AddGadgetItem(#ReceiveText, -1, ThreadParameter\Receive$)
      ThreadParameter\Receive$ = ""
      SignalSemaphore(ThreadParameter\Semaphore)
     
    Case #ComThread_Finished
      SetGadgetText(#StartButton, "Start")
      DisableGadget(#ComCombo, #False)
     
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #StartButton
          If GetGadgetText(#StartButton) = "Start"

            ThreadParameter\Com$ = GetGadgetText(#ComCombo)
            ThreadParameter\Exit = #False
            ThreadParameter\Thread = CreateThread(@ComThread(), @ThreadParameter)
          Else
            ThreadParameter\Exit = #True
          EndIf
         
        Case #SendButton
          WriteSerialPortString(ThreadParameter\Com, GetGadgetText(#SendString))
         
      EndSelect
     
    Case #PB_Event_CloseWindow
      Exit = #True
     
  EndSelect
  
val = ElapsedMilliseconds()
Debug val 
 
Until Exit



If IsThread(ThreadParameter\Thread)
  ThreadParameter\Exit = #True
  If WaitThread(ThreadParameter\Thread, 3000) = 0
    KillThread(ThreadParameter\Thread)
  EndIf
EndIf

FreeSemaphore(ThreadParameter\Semaphore)
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Very slow loop and don't know why :(

Post by TI-994A »

Walko wrote:...I need to add some stuff to do inside the infinite loop but It seems that the loop is very very slow...
The event loop is technically not an infinite loop. It stops and waits for the command, WaitWindowEvent(), to receive events before executing the loop.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
HeX0R
Addict
Addict
Posts: 979
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: Very slow loop and don't know why :(

Post by HeX0R »

Better use this to find available COM ports.
It will also show virtual COM ports, which usually are not named "COMx"
Walko
User
User
Posts: 11
Joined: Thu Mar 26, 2020 6:08 pm

Re: Very slow loop and don't know why :(

Post by Walko »

Hello,

Thank you for your help.
I will look at your code :)

BTW, I solve my problem by using AddWindowTimer() :D
Post Reply