Android Question Wait for packet predefined time

Andrej Meszaros

Member
Licensed User
Longtime User
Hy Erel,

In my project I try to communicate on android mobile with a PIC micro over bluetooth serial. I use asyncstream in prefix mode. The mobile is the main, so every time the android send packet and wait for a answer. My question is, how to handle when for some reason the PIC dosnt send back answer.
Something like WAIT for packed received FOR 1000mS. When no packet received do something ...
I try to find on forum the solution but I dont find how to manage it.

Please help

Thank You

Edit (Erel): Answer is here: https://www.b4x.com/android/forum/threads/wait-for-packet-predefined-time.80666/#post-511130
 
Last edited by a moderator:

tigrot

Well-Known Member
Licensed User
Longtime User
I don't wait for incoming data. I use AStreams_NewData event to handle incoming data. You can activate a timer with a count down.
First initialize a variable with a number of seconds.
The set timer.enabled=true ; timer.interval=1000 ' one second
Subtract 1 from variable in timer event
If you get some data recharge variable with number of seconds
If counter go to 0 then you get TIMEOUT!

Mauro
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
Unfortunately, he only asked Erel, you did not have to answer :p:p:p
 
Upvote 0

Andrej Meszaros

Member
Licensed User
Longtime User
Thank You for the tip. Handling received packet is working. But how to detect time out ?
I prefer to write a SUB with parameters :

SUB SendRecPacket ( sending packet, timeout ) received packet

This sub send the packet and wait for the answer predefined time. If packet received, returns the packet, if no, return empty packet.

Someone has this already done ?

Thank You

Andrej
 
Upvote 0

SteveTerrell

Active Member
Licensed User
Longtime User
Thank You for the tip. Handling received packet is working. But how to detect time out ?
I prefer to write a SUB with parameters :

SUB SendRecPacket ( sending packet, timeout ) received packet

This sub send the packet and wait for the answer predefined time. If packet received, returns the packet, if no, return empty packet.

Someone has this already done ?

Thank You

Andrej

If i understand how the new "wait for" works (which i might not!) you could perhaps use it with a callback from either a timer or from the packet received code

Pseudo code...

Send the packet
Start the timer
Wait For CommonCallBack(reason, packet)
Use reason to work out what happened


Sub TimerCallback
Disable the timer
CommonCallBack(1,Null) ' timed out
End Sub

Sub PacketReceived(packet)
Disable the timer
CommonCallBack(2,packet) ' good
End Sub
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
And if possible, do not ask the question to a person in the Forum, but give it to everyone. :D:D:D
If you have to ask a person question person write it in private or maybe home phones :p:p:p
 
Upvote 0

Andrej Meszaros

Member
Licensed User
Longtime User
Hy tigrot, Thank You for Your tip. I start to solve my problem with tip You write, but with no luck. Also try to search the forum for the solution.
SteveTerrell write exactly what I looking for, but I still do not have enought information about Wait For.
Im good in PIC programming and solve this issue in PIC with the method like SteveTerrell write. But can not
implement in B4A and B4J.
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
Wait for encapsulate other "home made" solutions like mine. Since I don't know anything about your APP structure so I told you MINE solution, which is working for me.
You can write whatever you need without using wait for.
How do you read bytes from PIC?
 
Upvote 0

Andrej Meszaros

Member
Licensed User
Longtime User
Asynstream in prefix mode reading packet from PIC.
My PIC project collects temperature data from 16 nodes over RF every 30 minute.
When I connect from my mobile to PIC over bluetooth serial, I need to get data from PIC.
So I try to use a FOR NEXT loop.
FOR node=1 to 16
send packet ' asking PIC to send temp data for node
PIC send data
NEXT
If there is no problem with communication and PIC is working, everything is ok.
But when the PIC has problem, and dont send packet back, how to solve it.

I my first version which is working, I use 2 SUBS.
The first SUB send the first asking packet PIC.
The SUB ends.

The second SUB is asynstream_newdata.
So when the PIC send back packet this sub is raised.
The data is processed.
Becouse I get packet, send asking packet for the second node.

When I get back packet from PIC a second sub is raised.

But when I dont get back packet, i have no data, and how to check it ?

Sorry for my english.
 
Upvote 0

Andrej Meszaros

Member
Licensed User
Longtime User
Erel implemented the asynstream with prefix mode, where the newdata event raised when the complete packet is received. He used also a time value, in which the complete packet should be received.
Something similar should be the solution.
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
B4X:
dim timercnt as integer=10 ' ten seconds timeout
dim timer1 as timer
timer1.initialize("timer1",1000)
timer1.enabled=true

Sub AStreams1_NewData (bufferx() As Byte)
  Dim msg As String
  timercnt=10
  msg = BytesToString(bufferx, 0, bufferx.Length, "ISO-8859-1")
  'process msg 
end sub
sub timer1_tick
  if timercnt>0 then 
      timercnt=timercnt-1
      if timercnt=0 then       callsub "whateveryouwant" ' process timeout
  end if
end sub
 
Upvote 0

Andrej Meszaros

Member
Licensed User
Longtime User
I try this and looks that it is working. I use buttons to simulate the packet sending and receiving,
When I push the Sending button and in less then 1 second push the Receiving, i get log that data is received.
When I dont push, get log, no data received. Later I try it with real communication.

[ code ]
Sub btnSendPacket_Action
Log ("Send packet and start timer.")
Timer1.Initialize("Timer1",1000)
Timer1.Enabled = True
wait for MySub_Complete
End Sub

Sub btnRecPacket_Action
Log ("Data received in time.")
Timer1.Enabled = False
CallSubDelayed(Me,"MySub_Complete")
End Sub

Sub Timer1_tick
Log ("No data received in time.")
Timer1.Enabled = False
CallSubDelayed(Me,"MySub_Complete")
End Sub

[ /code ]
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Like this:
B4X:
Sub SomeSub
Dim IsTimeoutRelevant() As Boolean = Array As Boolean(True)
AbortAfter (1000, IsTimeoutRelevant)
AStream.Write(...)
Wait For AStream_NewData (Data() As Byte)
IsTimeoutRelevant(0) = False

'continue here
End Sub

Sub AbortAfter (TimeoutMs As Int, IsRelevant() As Boolean)
Sleep(TimeoutMs)
If IsRelevant(0) = True Then
  Log("Timeout")
  AStream.Close
End If
End Sub

You can safely call it multiple times.

The trick here is to pass an array with a single boolean to the resumable sub. This allows us to control its behavior without using a global variable. Similar to passing a variable by reference.
 
Upvote 0
Top