I am using the code below to read a paired bluetooth-serial converter.
It works very well in my test application, where I have ONE BUTTON for each command.
When I try to integrate on my application I have a big problem.
I need to send a request to the device, the request is received. And the device responds.
However the New_Data event does not happen until I get out of the SUB where I made the request.
I know I should be going event based, however this case the user is doing an action that needed that and everything depends on this. The program must wait for the answer.
In fact, the answer comes extremely quick, however the event is only fired AFTER I get out of the SUB.
I have used DOEVENTS, making a loop trying to wait for that, but that does not work.
I really dont know how to be in a loop waiting for the request arrive in the New_Data. It is milliseconds.
This is the code that I use to read the bluetooth
	
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
and this is the part where I call it. You see there is a loop to retry the reading, and that I have the same thing reading from USB and working. Now I made the same thing to read from BT.
	
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
The idea is always the same, I send a request and get back a value. I see that working on the log. But the NEW_DATA event only happens after I get out of this SUB. After 5 times the sub get out and then I see the Log message of the NEW_DATA.
The class yBTManager is declared in a Class_Globals.
Please, I ask for help, I have a delivery date that is way too close now...
EDIT:
I see this is a recurring issue on the questions. I read the tutorials and I besides the "it runs on the main thread" nothing else I could found. In fact I see that somehow there is a kind of message loop at the main thread level. I was hoping that DoEvents would force it. The problem is that i created the application around the USB-Serial library that reads blocking and now I have an Async reading that I am trying to make Blocking.
So I need a trick to solve that, since DoEvents doesnt.
			
			It works very well in my test application, where I have ONE BUTTON for each command.
When I try to integrate on my application I have a big problem.
I need to send a request to the device, the request is received. And the device responds.
However the New_Data event does not happen until I get out of the SUB where I made the request.
I know I should be going event based, however this case the user is doing an action that needed that and everything depends on this. The program must wait for the answer.
In fact, the answer comes extremely quick, however the event is only fired AFTER I get out of the SUB.
I have used DOEVENTS, making a loop trying to wait for that, but that does not work.
I really dont know how to be in a loop waiting for the request arrive in the New_Data. It is milliseconds.
This is the code that I use to read the bluetooth
			
				B4X:
			
		
		
		'Class module
Sub Class_Globals
    Dim BTMac                As String  
    Dim Connected            As Boolean
  
    Private OSerial        As Serial
    Private OStream        As AsyncStreams
    Private RXData            As String
End Sub
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    OSerial.Initialize("OnSerial")
    Connected = False
End Sub
' show available BT devices for choose and return the MAC of the selected
Public Sub SelectionDialog As String
    Dim PairedDevices As Map
    PairedDevices = OSerial.GetPairedDevices
    Dim l As List
    l.Initialize
    For i = 0 To PairedDevices.Size - 1
        l.Add(PairedDevices.GetKeyAt(i))
    Next
    Dim res As Int
    res = InputList(l, "Selecione Bluetooth", -1) 'show list with paired devices
    If res <> DialogResponse.CANCEL Then
        BTMac = PairedDevices.Get(l.Get(res))
        Return BTMac
    Else
        Return ""
    End If
End Sub
Public Sub Connect
    If BTMac = "" Then
        ToastMessageShow("Informe Bluetooth as Ser conectado", False)
    Else
        If Not(Connected) Then
            OSerial.Connect(BTMac) 'convert the name to mac address and connect
        End If
    End If
End Sub
Public Sub Disconnect
    OStream.Close
    OnStream_Terminated
End Sub
Private Sub OnSerial_Connected (Success As Boolean)
    OSerial.Listen
    Connected = Success
    If Success Then
        OStream.Initialize(OSerial.InputStream, OSerial.OutputStream, "OnStream")
        ToastMessageShow("Bluetooth Conectado", False)
    End If
End Sub
Private Sub OnStream_Error
    Log("###Bluetooth "&LastException)
    OStream.Close
    OnStream_Terminated
End Sub
Private Sub OnStream_Terminated
    Log("###Bluetooth stream terminada")
    Connected = False
    OSerial.Disconnect
End Sub
Private Sub OnStream_NewData(Buffer() As Byte)
    Dim s As String
    s = OnlyNumbers(BytesToString(Buffer, 0, Buffer.Length, "UTF-8"))
    If s <> "" Then
        RXData = s
    End If
    Log("###Bluetooth recebido dados "&s)
End Sub
Sub RequestPeso
    Log("###Bluetooth request peso ")
    If OStream.IsInitialized Then
        Dim msg = Chr(5)
        OStream.Write(msg.GetBytes("UTF-8"))
'        RXData = ""
    End If
End Sub
Public Sub SendPrice(Price As String)
    Dim s As String
    Dim v As BigDecimal
    v.Initialize(Price)
    v.MovePointRight(2)
    s = Chr(2)&FillZeroes(OnlyNumbers(v.ToPlainString)&Chr(3), 6)
    OStream.Write(s.GetBytes("UTF-8"))
End Sub
Public Sub Read As String
    Dim s As String = RXData
    RXData = ""
    Log("### lido dados: "&s)
    Return(s)
End Sub
'Remove anything that is not in the range 0 -> 9
Private Sub OnlyNumbers(Value As String) As String
    Dim s As String
    s = ""
    For i = 0 To Value.Length - 1
        If (Asc(Value.CharAt(i)) >= Asc("0")) AND (Asc(Value.CharAt(i)) <= Asc("9")) Then
            s = s & Value.CharAt(i)
        End If
    Next
  
    Return s
End Sub
'Fill Zeroes to the Left according the number of digits
Private Sub FillZeroes(Value As String, Digits As Int) As String
    Dim s As String
    s = Value
    If Value.Length < Digits Then
        For i = 0 To Digits - Value.Length - 1
            s = "0" & s
        Next
    End If
    Return s
End Suband this is the part where I call it. You see there is a loop to retry the reading, and that I have the same thing reading from USB and working. Now I made the same thing to read from BT.
			
				B4X:
			
		
		
		            Dim I As Int
            Dim s As String
            Dim erro As Boolean
            I = 5
            Do While I > 0
                If FAppManager.GetConfig.GetBoolean("balancabt") Then
                    FAppManagerAct.BTMan.RequestPeso
                Else
                    FAppManagerAct.UsbMan.RequestPeso
                End If
                DoEvents
                DoEvents
                DoEvents
                DoEvents
                DoEvents
                DoEvents
                DoEvents
                erro = False
                If FAppManager.GetConfig.GetBoolean("balancabt") Then
                    s = FAppManagerAct.BTMan.Read
                Else
                    s = FAppManagerAct.UsbMan.Read
                End If
                If s.Length < 5 Then
                    I = I - 1
                    erro = True
                Else
                    FMultiplicador.Initialize(s) 'coloca o peso como multiplicador
                    div.Initialize3(1000)
                    FMultiplicador.Divide(div)
                    I = 0
                    erro = False
                End If
            Loop
          
            If erro Then
                ToastMessageShow("Problema na leitura balanca", True)
                Return -1
            End IfThe idea is always the same, I send a request and get back a value. I see that working on the log. But the NEW_DATA event only happens after I get out of this SUB. After 5 times the sub get out and then I see the Log message of the NEW_DATA.
The class yBTManager is declared in a Class_Globals.
Please, I ask for help, I have a delivery date that is way too close now...
EDIT:
I see this is a recurring issue on the questions. I read the tutorials and I besides the "it runs on the main thread" nothing else I could found. In fact I see that somehow there is a kind of message loop at the main thread level. I was hoping that DoEvents would force it. The problem is that i created the application around the USB-Serial library that reads blocking and now I have an Async reading that I am trying to make Blocking.
So I need a trick to solve that, since DoEvents doesnt.
			
				Last edited: 
			
		
	
								
								
									
	
								
							
							 
				 
 
		 
 
		 
 
		 
 
		 
 
		