Android Question Wait For Astream.write?

techknight

Well-Known Member
Licensed User
Longtime User
I have a couple of Astream.Write commands in sequence, one of them sending something different than the other. But both have to be sent back to back.

So I am doing This:

B4X:
WriteCommand
Do some things
Astream.Write(XXXXXX)


Sub WriteCommand
Do some things
Astream.Write(Result of some things)
Sleep(100)
End Sub

But it doesnt work. Soon as it encounters the Sleep(100), it returns and starts completeing everything that in the routine that called WriteCommand.

As you can imagine, this clobbers the serial data going on since its not really "waiting"

any ideas?
 

techknight

Well-Known Member
Licensed User
Longtime User
Grasping at straws here.

Now I am trying this:

B4X:
        Dim WaitTimer As Timer
        WaitTimer.Initialize("WaitTimer", 5000)
        SendCommandCTNC(0,0,1) 'Boot the TNCs
        WaitTimer.Enabled = True
        Wait For WaitTimer_Tick
        WaitTimer.Enabled = False

This doesn't work either. execution resumes immediately after this. So the Wait For isnt doing anything. I need something that halts this particular subroutine and further execution of it until something completes or after a specific time period and then picks up execution.

Seems everything I do wants to continue execution in the same exact sub even after I try sleep or wait for.... Ugh

any ideas?
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Seems the only thing I got to work properly was this:

Its only an educated guess as I have no idea how long the transmission takes.

B4X:
        SendCommandCTNC(0,0,1) 'Boot the TNCs
        WaitTimedOut = False
        WaitTimer.Interval = 100
        WaitTimer.Enabled = True
        Do Until WaitTimedOut = True
            Sleep(1)
        Loop

This only works as long as I keep it like that

if I do a subroutine called Delay, and put that code in a Delay subroutine, it still has the same problem. it resumes code execution after the call to the subroutine BEFORE the subroutine is complete.
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Watch the resumeable subs Video.
You need to understand how it works.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Also, is it possible to add a SendComplete event or something to the Astreams.write handler?

I dont know how reading/writing is handled internally. Just curious.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
It took forever but I finally "got it".

Any resumable sub feature such as sleep keeps returning back to the parent callback, UNLESS.... its expected to return a value. ;-)

Wow I am slow.
 
Upvote 0

Roger Daley

Well-Known Member
Licensed User
Longtime User
It took forever but I finally "got it".

Any resumable sub feature such as sleep keeps returning back to the parent callback, UNLESS.... its expected to return a value. ;-)

Wow I am slow.
Would have been good if you had shown your working example. I've read everything and still don't get it. I'm slower than you.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Would have been good if you had shown your working example. I've read everything and still don't get it. I'm slower than you.

Because my solution wasn't a solution for Astream.write.

I ended up giving up on it. However if a sequence of nested subroutines/wait fors have to complete in a specific order at a specific time? I just simply return a value even if its not used. like return a true or false or something, then discard it. This may get optimized out? I dont know but it has worked so far.

but astreams.write happens asyncronously in the background which causes problems if i need to send packets back to back in a specific timing window. Even if I use a astream.write, sleep(x) and astream.write. It still doesn't work and sometimes packets will get rammed together back-to-back or skipped entirely. Its very weird.

Sadly, I had to use a push timer for this. Throw packets in a FIFO and bytesbuilder, and a 100mSec timer takes care of it. It just checks the queue, sends it, and returns.

This works for blasts, but the problem is if you need 2-way communciation and you have to wait on a response before sending another packet.

It is very painful and not good for scenarios like this. I do not know of an alternative library either. Also if you are dealing with another protocol over bluetooth/serial thats not compatible with Prefix, it gets even more messy because not all of the packet arrives at the same time for an Event fire, or sometimes a packet and a half can arrive during the trigger.

Then it gets difficult to handle because now you need to treat the buffer like a FIFO where you check for the entire packet, do something with it and "pop that off" while the event is filling it in the background simultaneously. Popping off a packet requires you to know the header/footer boundaries and handle that manually... and ive still not mastered that art yet.
 
Last edited:
Upvote 0

agraham

Expert
Licensed User
Longtime User
but astreams.write happens asyncronously in the background which causes problems if i need to send packets back to back in a specific timing window
I've looked at the code for AsyncStreams and write should queue the data packets and send them in the same order as they are entered in the queue so they should alwaysa arrive in order at the other end, although the timing or receiplt will be indeterminate.
it gets even more messy because not all of the packet arrives at the same time for an Event fire, or sometimes a packet and a half can arrive during the trigger.
This always occurs with serial comms and is one of the reasons it is harder to implement a robust system than most people think as handling all possible errors including , missing, additional and corrupted characters and dealing with batching and identifying packets can get complicated.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
I've looked at the code for AsyncStreams and write should queue the data packets and send them in the same order as they are entered in the queue so they should alwaysa arrive in order at the other end, although the timing or receiplt will be indeterminate.

This always occurs with serial comms and is one of the reasons it is harder to implement a robust system than most people think as handling all possible errors including , missing, additional and corrupted characters and dealing with batching and identifying packets can get complicated.

Order was never an issue luckily. Trouble was block/guard time between packet sends being very inconsistent. i could do write, sleep, write. and each packet would never be gapped apart by sleep most of the time.

Anyways...

What would have been cool at the time, is if astreams.write had a flag i could pend the task on to know when it actually finished sending. Defeats the purpose of "async" but in the case of serial, 99.9% of the time that needs to be synchronous anyways especially for 2-way comms.
 
Last edited:
Upvote 0
Top