Android Question AsyncStreams - Reinitialize after first initialization

mmanso

Active Member
Licensed User
Longtime User
Hi there,

Let's say I initialize an AsyncStream like this:

B4X:
astreams1.Initialize(UsbSerial1.GetInputStream, UsbSerial1.GetOutputStream, "astreams1")

It's possible after doing this to reinitialize it for "Write only" like this:

B4X:
astreams1 = Null
astreams1.Initialize(Null, UsbSerial1.GetOutputStream, "astreams1")

I've tried this but after the second initilization I can't write to the astreams1.

Thanks for thelp.
 

OliverA

Expert
Licensed User
Longtime User
I'm amazed your program does not crash after doing
B4X:
astreams1 = Null
and then
B4X:
astreams1.Initialize(Null, UsbSerial1.GetOutputStream, "astreams1")
since you are calling an Initialize method on a Null object

Another way this may be accomplished:
1) Use a global boolean variable to keep track of the read only mode
B4X:
Private readOnly as Boolean

2) Add this to your _NewData event
B4X:
Sub astream1_NewData (Buffer() As Byte)
   If Not(readOnly) Then
   'Place original event code here
   End If
End Sub

3) Toggle read only mode by setting readOnly to True or False as needed
 
Upvote 0

mmanso

Active Member
Licensed User
Longtime User
Hi there,

I can't do that because I'm using UsbSerial to connect to a usb printer that sends 10.000 NewData events every 2 seconds. Since I can't control that I was trying to find a way to enable or disable the NewData event so could activate it to read if the print has errors or something.

I've tryed everything and even other printers. WIth others, UsbSerial works great. But receiving 10.000 NewData events every 2 seconds make android so slow that the app can't be used.

I'm trying to find a solution for this problem.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
You don't need the shenanigans in the first post, your second Initialize on the same instance is closing the output stream. Try opening one AsycnStreams instance for output only just like your second Initialize, Initialize will accept Null for the input stream. You should then be able to write whenever you want. Then create another different instance for input only when you want status, Initialize it when you want status and Close it afterwards. You should be able to repeat this on the same instance when you require status.

By the way I'm assuming that what you are receiving repeatedly is valid status data. If so then I am astonished that there appears to be no way to control the frequency as it seems totally unusable in a real world situation.
 
Upvote 0

mmanso

Active Member
Licensed User
Longtime User
Hi there,

Thanks for the suggestion. To try this, I've created two buttons and these are the events:

B4X:
Private Sub btnReadStart_Click
    astreamsIn.Initialize(UsbSerial1.GetInputStream, Null, "astreamsIn")
End Sub

Private Sub btnReadStop_Click
    astreamsIn.Close
End Sub

when I press "start" button, it starts reading. When I press stop, it stops (takes 2 secs to stop because the NewData event, like I said is massive called).

In the end, when I press start again, it doesn't start. I press start and stop and it seems it's not doing anything...

Any suggestion?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Any suggestion?
Looking at the source of AsyncStreams (here), calling Close closes the Input/Output streams of the object that AsysncStreams services (in your case UsbSerial1). Given that, you may need to re-initialize UsbSerial1 to re-establish the input/output streams of the serial port.
 
Upvote 0

mmanso

Active Member
Licensed User
Longtime User
I was writing just that... when I close the read stream I stop being able to write (now I know why).

Couldn't we have a .CloseOut() and .CloseIn() methods also to close only a specific stream?
 
Upvote 0

mmanso

Active Member
Licensed User
Longtime User
Hmmm... the only change needed to the .Close method would be:

Java:
    public synchronized void Close() throws IOException {
        if (tin != null && ain != null) {
            ain.close();
            if (Thread.currentThread() != tin)
                tin.interrupt();
            ain = null;
        }
        if (tout != null && aout != null) {
            aout.close();
            if (Thread.currentThread() != tout)
                tout.interrupt();
            aout = null;
        }
    }

No?
 
Upvote 0

mmanso

Active Member
Licensed User
Longtime User
This is an industrial kiosk printer:


I've tried with a SAM4S also USB and it works like a charm... this one e giving me an headache...
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Upvote 0

mmanso

Active Member
Licensed User
Longtime User
I've read that manual 100 times now... I can't find anything to control that so I was trying to deal with it in the software side.

After several tries, the only way I see working is the one you suggested. Opening and closing the "read" stream from x in x time to allow to check if the printer is in error. I just can't implement that solution because of the behaviour of the .Close method...
 
Upvote 0

mmanso

Active Member
Licensed User
Longtime User
Every time I've open the stream just for write, everything works ok...

B4X:
astreamsOut.Initialize(Null, UsbSerial1.GetOutputStream, "astreamsOut")

I don't notice cpu problems when doing this. Just when I open the Input stream the problem appears... and it happens because of the HIGH number of times the NewData event is called.

I've tried with two different printers of the same exact model... same problem.

I'm out of solutions to go around this...
 
Upvote 0
Top