Android Tutorial [B4X] AsyncStreams Tutorial

Status
Not open for further replies.

Roberto P.

Well-Known Member
Licensed User
Longtime User

Hi Flyingbag
I ask the courtesy to provide the class file of your server instance? thank you very much
 

GaNdAlF89

Active Member
Licensed User
Longtime User
How can I do something like a ping to bluetooth printer? I want to check if printer is on before send it the data to be printed..
 

EduardoElias

Well-Known Member
Licensed User
Longtime User
I am using stream to read a Bluetooth to serial converted connected to a device that measure weight.

It works now.

However the way it is used, it is needed to wait for the weight.

I send a request for the device and it immediately returns with the weight.

Is there a way to wait for the bytes come from the stream? Then the user can move to the next steps.
 

joedarock

Member
Licensed User
Longtime User
Data from my remote USB serial device arrives in messages of 14 bytes. These get broken up by Asyncstreams into a number of NewData events, sometimes containing 1 byte, sometimes 4, sometimes 5, etc and different every time. I reassemble them as they arrive into a single 14 byte message array.

My question is "How does AsyncStreams decide when to raise a NewData event and why are the buffer lengths different every time?". Also, It seems that every alternate time I poll the device, the last byte of the last NewData event is missing. Is there any common explanation for this?

Joe
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
These get broken up by Asyncstreams into a number of NewData events
AsyncStreams doesn't break the messages. AsyncStreams (in non-prefix mode) reads the data from the input stream and then raises the event with the data it was able to read.

Also, It seems that every alternate time I poll the device, the last byte of the last NewData event is missing. Is there any common explanation for this?
No. Can you post your code? Preferably in a new thread.
 

joedarock

Member
Licensed User
Longtime User
AsyncStreams doesn't break the messages. AsyncStreams (in non-prefix mode) reads the data from the input stream and then raises the event with the data it was able to read.


No. Can you post your code? Preferably in a new thread.
If it doesn't btreak up the stream, why is there 4, sometimes 5, events in a 14 byte message stream?
 

joedarock

Member
Licensed User
Longtime User
I'm having a devil of a time using USBSerial and AsyncStreams to make my polling application work and I'd appreciate any suggestions to break through this basic communications problem so I can move on with the value-add code.

I'm polling a low speed (2400 baud) microcontroller-based device using the USBSerial library. The USBSerial part seems to work OK, but I'm having difficulty with the AsyncStreams part. My application uses a 12-byte forward message to the device and a 14-byte return message from the device, all in binary (not ASCII encoded). The sequence to poll a device from start-up looks like this:
1) Send a Reset command
2) Wait for the device to reset and be ready to hear messages
3) Send a 'ping' message to verify the device is alive
4) Get all 14 bytes of the ping message before sending the next message
5) and so on...

I'm OK up to somewhere in step 4. If I enter any sort of DO loop to wait for all the data to be available, the NewData event doesn't get raised anymore, so I don't know when to proceed with the next command. A code example is attached.

Any help greatly appreciated.

Joe
 

Attachments

  • Polling debug code.zip
    7.8 KB · Views: 641

Erel

B4X founder
Staff member
Licensed User
Longtime User
If it doesn't btreak up the stream, why is there 4, sometimes 5, events in a 14 byte message stream?
It is not AsyncStreams the breaks the messages. This is how network communication works.

Don't try to do any loop. It will not work.
The solution is to collect the bytes in a List or array until you have a full message and then work with the message.

You can see an example that works with text and looks for an end of line character: http://www.b4x.com/android/forum/threads/27002/#content

Your case is simpler as you know the length of each message.
 

joedarock

Member
Licensed User
Longtime User
OK, I got through the previous problem with a workaround similar to how it's done in AsyncStreamsText (I think that's what it's called). In my NewData event, I count up the received bytes as they arrive , stuffing them into an array, until all the expected bytes in the message are received. It's not a perfect solution for other reasons, but it will work for this application, at least for now.

New problem: If I leave the device app running with B4A in the wireless debug mode and walk away for some period of time (minutes?), then when I return, the NewData event doesn't fire anymore. Everything else in the app (UI button events, AsyncStream writes, etc) work as normal, but no NewData. If I press the "Restart Program" icon (F11) in the B4A gui, the program restarts and works normally.

Suggestions?
Joe
 

joedarock

Member
Licensed User
Longtime User
It's not a 'network" connection, it's a USB serial connection - a 2 foot piece of wire directly to a single device. In all my years developing low speed asynchronous serial data links, even via USB serial adaptors, I've never had this problem or had to resort to the complex and obtuse workarounds required to make this work reliably. Even VB, which runs on top of a lot of OS layers, is much more intuitive, easier and reliable in this respect. Isn't there a simpler method to handle simple USB serial comms or are these difficulties implicit to Android and will always be there?
 

joedarock

Member
Licensed User
Longtime User
How are you interacting with the USB?
With USBSerial library?

OK, I finally broke through and got my thinking process wrapped around this problem. My system is working smoothly and reliably via the USB Serial library and Asyncstreams now. Sorry for any frustration I might have vented here.

For others like me who are accustomed to working with small micro-controllers and small or no operating systems, serial communications on Android requires a different way of thinking. Instead of sending a command and trying to 'waste time' in some sort of loop until the reply comes in, you really have to think in terms of event-driven systems. What I did was basically to build a little 'state-machine' inside the NewData event with Case statements. Each message that I transmit is labeled via global variables with a name and a message type that includes expected number of return bytes and the name of the Case statement that should process it. Each CASE statement concludes with a call to the next message to be transmitted. When the first message in a multi-message transaction is sent, it's response, which comes in multiple NewData events of varying buffer length, is processed and assembled by NewData into a return message array until all the expected bytes arrive. Once a complete and verified return message is received, it triggers the next forward message in the state machine sequence and a new set of returned bytes get built into a new returned message. This process continues until a whole message transaction is complete. There are no 'Waits' or "Do" loops.

Thanks Erel for your patience with me. I think I get it now.

Joe
 

westingenieria

Active Member
Licensed User
Longtime User

Attach the code modified little bit. With bookmarks and questions. Help me please.

thanks
 

Attachments

  • TestClientSocket WEST.zip
    352.1 KB · Views: 1,197
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…