Android Question IOIO Stream has been closed

rosippc64a

Active Member
Licensed User
Longtime User
Hi Guys,
I read a lof of articles about this problem, but there wasn't answer what would be good for me.
I use a diy ioio with a serially connected rfid reader. I use a home made b4a (b4x.com) program. Te rfid reader reads 13bytes in each 5 seconds, repeatedly.
When I use this with android 4.2, and ADB (usb debugger on), IOIO 1.4 and IOIOib, it works fine. When I use it with android 4.4 or 5.01 (both tested), IOIO 2.05 lib, open accessory, usb debugger off, then after 10-20 readings the same program hangs with 'Stream has benn closed'. I verified, the rfid reader reads further and sends its signal, but the stream is closed... I don't close this stream anywhere, and I can't figure out what is the reason of this error. The ioio firmware is the latest of course.
I don't thought somebody will say which row of source program is faulty, just a question if someone met such a problem: it is a hardware or software issue ?
best regards
Steve
 

rosippc64a

Active Member
Licensed User
Longtime User
The process is going. If there is only reading, there is no problem. But I have to write too after all reading, and after some writing the 'Stream has been closed.' happens, and neither reading nor writing can be done further.

As I mentioned before, this problem is when I use android 4.4 or above.
 
Last edited:
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
When I close the yoyo ( close uart, close streams, unregisterreceiver, disconnect) after I use an uart pin rx3, tx4, I can't reconnect to yoyo. I vainly close the uart, at connect I got the message, pin 4 already claimed.
 
Upvote 0

kolbe

Active Member
Licensed User
Longtime User
Hi Guys,
I read a lof of articles about this problem, but there wasn't answer what would be good for me.
I use a diy ioio with a serially connected rfid reader. I use a home made b4a (b4x.com) program. Te rfid reader reads 13bytes in each 5 seconds, repeatedly.
When I use this with android 4.2, and ADB (usb debugger on), IOIO 1.4 and IOIOib, it works fine. When I use it with android 4.4 or 5.01 (both tested), IOIO 2.05 lib, open accessory, usb debugger off, then after 10-20 readings the same program hangs with 'Stream has benn closed'. I verified, the rfid reader reads further and sends its signal, but the stream is closed... I don't close this stream anywhere, and I can't figure out what is the reason of this error. The ioio firmware is the latest of course.
I don't thought somebody will say which row of source program is faulty, just a question if someone met such a problem: it is a hardware or software issue ?
best regards
Steve

The first thing that caught my eye was the "every five seconds". The other is that it works in ioiolib 1.4 and not ioiolib 2.05. The big change between those versions is that 1.4 ran on the GUI thread and on 2.05 every IOIO method runs on a separate thread. Newer versions of Android do not allow doing all the IOIO i/o on the GUI thread, that is why it had to change. So I suspect that there is a timing and resource issue here. Try to vary the time between your uart reads. Also keep any screen activity to a minimum and any other device activity to a minimum. You should also check the unfiltered logs to see why the stream is being closed. Android itself should give you a reason but you don't see these logs unless you deselect filter in the logs window. The fact that it runs for awhile but then stops is that something happens over repeated iterations, buffer problem, too many threads or instances.. some kind of resource problem. I have a routine that accesses a uart camera to take and download a picture of up to 64k. It works but it took some time to get it right. I recall a similar problem and if I recall correctly it was a buffer problem.
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
The first thing that caught my eye was the "every five seconds". The other is that it works in ioiolib 1.4 and not ioiolib 2.05. The big change between those versions is that 1.4 ran on the GUI thread and on 2.05 every IOIO method runs on a separate thread. Newer versions of Android do not allow doing all the IOIO i/o on the GUI thread, that is why it had to change. So I suspect that there is a timing and resource issue here. Try to vary the time between your uart reads. Also keep any screen activity to a minimum and any other device activity to a minimum. You should also check the unfiltered logs to see why the stream is being closed. Android itself should give you a reason but you don't see these logs unless you deselect filter in the logs window. The fact that it runs for awhile but then stops is that something happens over repeated iterations, buffer problem, too many threads or instances.. some kind of resource problem. I have a routine that accesses a uart camera to take and download a picture of up to 64k. It works but it took some time to get it right. I recall a similar problem and if I recall correctly it was a buffer problem.
Thank you the reply Kolbe! I went further in this issue and of course I tried with latest library too, but there was other problem, as I wrote to you in conversation section. The 5 seconds is because my rfid reader prevent from speedy readings and I wanted to mark, that there is no big amount of data. By the way I did some test programs too for testing minimal resource reserving with the latest lib, and there was good read but at the first writing the mentioned stream has been closed error, which wasn't in the java language example (which did the same reading/writing).
 
Upvote 0

kolbe

Active Member
Licensed User
Longtime User
Can't really help more then unless I know more about your code or see the complete error logs. I didn't mention above that I use a service module to run the IOIO code. Did you look at the workbench app to use a model for your uart code?
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
In my big application the ioio managing is also works in a service module, but with latest ioio lib there was the problem, so I made a small test program using ioio examples (no service module, ioio version 2.05, ioiolib 3.20):
B4X:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: Megafuture Box test
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

'Activity module
'PROG NAME: B4A_IOIO_UART_Test1.b4a, date: 2011.08.29 by ERIC WANG
'This is a sample program for testing IOIO UART function in B4A,
'Since I only play with B4A for several weeks, errors should be found somewhere.
'I wrote these codeto  share my work in reading passive/active RFID, bluetooth, nRF24e1,
'AVR data from a mandown device that my comapny SWEETEK created recently.
'I am trying to read SPI and I2C device in the future. if someone has codes to share that will be very much appreciated.
'NOTE: The default default RXpin=5,pintype=Floating TXpin=4,pintype=Normal, baud=9600 on IOIO Board.
' I tried serial input and  AStreams method to read data from PC, and found no luck.
' I don't why, but you need to assign the exact buffer size as found in BytesAvailable or RX won't work.
' please let me know if you tried ASterams and worked, you can email your code to [email protected],
' this sample project is far from finished, so use it with caution.
' if you have any question please contact me via email: [email protected] or [email protected]
' good luck! and have fun.

Sub Process_Globals

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim period As Int
    Dim TimerLoop As Timer
    Dim TimerRX As Timer

    Dim btnSend As Button
    Dim btnSetUp As Button
    Dim Label1 As Label
    Dim Label10 As Label
    Dim Label3 As Label
    Dim Label4 As Label
    Dim Label5 As Label
    Dim Label6 As Label
    Dim Label7 As Label
    Dim Label8 As Label
    Dim Label9 As Label
    Dim rbtn_loop As RadioButton
    Dim rbtn_Single As RadioButton
    Dim spn_Baudrate As Spinner
    Dim spn_RxPin As Spinner
    Dim spn_Rxpintype As Spinner
    Dim spn_TxPin As Spinner
    Dim spn_Txpintype As Spinner
    Dim spn_Period As Spinner
    Dim txtRX As EditText
    Dim txtSend As EditText

    Dim PeriodMap As Map
    Dim p_uart As Panel
    Dim panel1 As Panel
    Dim lbStatus As Label
  
    Dim YOYO As IOIO
    Dim led As DigitalOutput
    Dim uart1 As Uart
    Dim in1 As InputStream
    Dim out1 As OutputStream
    Dim go As Boolean
    Dim RXPIN As Int
    Dim RXPINTYPE
    Dim TXPIN As Int
    Dim TXPINTYPE
    Dim BAUDRATE As Int
    Dim TPeriod As Int
    Dim looped As Boolean
    Dim LedFlag As Boolean
End Sub

Sub Activity_Create(FirstTime As Boolean)
Dim panels(5) As Panel
Activity.LoadLayout("1")
Activity.Title="IOIO UART TEST"
If FirstTime Then

    p_uart.Initialize("p_Uart")
    SetSpinner
    'default RXpin=5,pintype=Floating TXpin=4,pintype=Normal, baud=9600)
    spn_RxPin.SelectedIndex=1
    spn_TxPin.SelectedIndex=0
    spn_Baudrate.SelectedIndex=4
    spn_Txpintype.SelectedIndex=0
    spn_Rxpintype.SelectedIndex=0
    spn_Period.SelectedIndex=4
  
    go=False
    looped=False
    rbtn_Single.Checked=True  
  
    YOYO.Initialize
    YOYO.WaitForConnect()
      
    TimerLoop.Initialize("TimerLoop",10)
    TimerRX.Initialize("TimerRX",100)

    led = YOYO.OpenDigitalOutput( 0,led.OP_NORMAL ,True) ' Enable LED_PIN for output
    getSetUPValue

    uart1= YOYO.OpenUart(RXPIN,RXPINTYPE,TXPIN,TXPINTYPE,BAUDRATE,uart1.PARITY_NONE,uart1.STOPBIT_ONE)
    in1=uart1.InputStream
    out1=uart1.OutputStream

End If
  
End Sub
Sub SetSpinner()
    spn_Period.TextSize=14
    spn_Period.AddAll(Array As String("0.05 sec","0.1 sec","0.2 sec","0.5 sec","1 sec","2 sec","5 sec","10 sec","20 sec"))
    PeriodMap.Initialize
    PeriodMap.Put("0.05 sec",50)
    PeriodMap.Put("0.1 sec",100)
    PeriodMap.Put("0.2 sec",200)
    PeriodMap.Put("0.5 sec",500)
    PeriodMap.Put("1 sec",1000)
    PeriodMap.Put("2 sec",2000)
    PeriodMap.Put("5 sec",5000)
    PeriodMap.Put("10 sec",10000)
    PeriodMap.Put("20 sec",20000)
    spn_TxPin.TextSize=14
    spn_TxPin.AddAll(Array As String("3","4","5","6","7","9","10","11","12","13","14"))
    spn_RxPin.TextSize=14
    spn_RxPin.AddAll(Array As String("3","4","5","6","7","9","10","11","12","13","14"))
    spn_Txpintype.TextSize=14
    spn_Txpintype.AddAll(Array As String("OP_NORMAL","OP_OPEN_DRAIN"))
    spn_Rxpintype.TextSize=14
    spn_Rxpintype.AddAll(Array As String("IP_FLOATING","IP_PULL_DOWN","IP_PULL_UP"))
    spn_Baudrate.TextSize=14
    spn_Baudrate.AddAll(Array As String("1200","2400","4800","9600","19200","38400","57600","115200"))
End Sub
Sub getSetUPValue
Dim tmp As String
'get RXPIN#
tmp=spn_RxPin.SelectedItem
Select Case tmp
    Case "3","4","5","6","7","9","10","11","12","13","14"
        RXPIN = tmp
End Select
'get TXPIN#
tmp=spn_TxPin.SelectedItem
Select Case tmp
    Case "3","4","5","6","7","9","10","11","12","13","14"
        TXPIN = tmp
End Select
'get RXPINTYPE
tmp=spn_Rxpintype.SelectedItem
Select Case tmp
    Case "IP_FLOATING"  
        RXPINTYPE = uart1.IP_FLOATING
    Case "IP_PULL_DOWN"  
        RXPINTYPE = uart1.IP_PULL_DOWN
    Case "IP_PULL_UP"  
        RXPINTYPE = uart1.IP_PULL_UP
End Select
'get TXPINTYPE
tmp=spn_Txpintype.SelectedItem
Select Case tmp
    Case "OP_NORMAL"  
        TXPINTYPE = uart1.OP_NORMAL
    Case "OP_OPEN_DRAIN"  
        TXPINTYPE = uart1.OP_OPEN_DRAIN
End Select
'get baud rate
tmp=spn_Baudrate.SelectedItem
BAUDRATE=tmp
'Get Period
Dim si As Int
si=spn_Period.SelectedIndex
TPeriod=PeriodMap.GetValueAt(si)
End Sub


Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed Then
        led.Close
        YOYO.disconnect()
    End If
End Sub

Sub rbtn_Single_CheckedChange(Checked As Boolean)
If Checked Then
    looped=    False
End If
End Sub
Sub rbtn_loop_CheckedChange(Checked As Boolean)
If Checked Then
    looped=True
End If
End Sub
Sub btnSetUp_Click()
If go=True Then
    go=False
    btnSetUp.Text="SET/GO"
    'btnSetUp.Background=black
    TimerLoop.Enabled=False
    TimerRX.Enabled=False
Else
    go=True
    btnSetUp.Text="STOP"
    getSetUPValue
    uart1.Close
    in1.Close
    out1.Close
    uart1= YOYO.OpenUart(RXPIN,RXPINTYPE,TXPIN,TXPINTYPE,BAUDRATE,uart1.PARITY_NONE,uart1.STOPBIT_ONE)  
    in1=uart1.InputStream
    out1=uart1.OutputStream
    If rbtn_Single.Checked=False Then
        TimerLoop.Initialize("TimerLoop",TPeriod)
        TimerLoop.Enabled=True
    End If
    TimerRX.Enabled=True
    Msgbox("READ TO GO","")
End If
End Sub
Sub btnSend_Click
'If rbtn_Single.Checked=True Then
led.Write(Not(LedFlag)) ' Turn on/off stat LED, active LOW
LedFlag = Not ( LedFlag )
If uart1.IsInitialized Then
    'getSetUPValue
    'uart1.Close
    'IN1.Close
    'OUT1.Close
    'uart1= YOYO.OpenUart(RXPIN,RXPINTYPE,TXPIN,TXPINTYPE,BAUDRATE,uart1.PARITY_NONE,uart1.STOPBIT_ONE)
    'in1=uart1.InputStream
    'out1=uart1.OutputStream
     If txtSend.Text.Length > 0 Then
        Dim buffer() As Byte
        Dim ST As String
        ST=txtSend.Text & Chr(13) & Chr(10) 'CRLF
        buffer =ST.GetBytes("UTF8")
        out1.WriteBytes(buffer,0,buffer.Length)
        out1.Flush
        txtSend.SelectAll
    End If
End If
End Sub
Sub TimerLoop_Tick
    If LedFlag= True Then
         LedFlag=False
    Else
        LedFlag=True
    End If
    led.Write(LedFlag)
    If  rbtn_Single.Checked=False Then
        If txtSend.Text.Length > 0 Then
            Dim buffer() As Byte
            Dim ST As String
            ST=txtSend.Text & CRLF
            buffer =ST.GetBytes("UTF8")
            out1.WriteBytes(buffer,0,buffer.Length)
            out1.Flush
            txtSend.SelectAll
        End If
    End If
End Sub
Sub TimerRX_Tick()
    If in1.IsInitialized Then
        'If in1.BytesAvailable>0 Then
            TimerRX.Enabled=False
            '*** need to assign the exact buffer size as in BytesAvailable or it won't work
            Dim buffer(in1.BytesAvailable) As Byte
            Dim count As Int
            count = in1.ReadBytes(buffer, 0,buffer.Length)
            lbStatus.Text="Read " & count & " bytes. @ " & DateTime.Time(DateTime.Now)
            If count > 0 Then
                txtRX.Text=txtRX.Text  & BytesToString(buffer, 0, count, "UTF8")
                txtRX.SelectionStart = txtRX.Text.Length
            End If
        'End If
    End If
    TimerRX.Enabled=True
End Sub
Sub Label3_Click
    txtRX.Text = ""
End Sub
In this case I can read almost errorless datas from my rfid reader via ioio, but if I send an only one character command, immediately I get the stream has been closed message. If I don't send anything, the reading works.
Because I experienced this issue, I made a small java program (using an example program also):
B4X:
package ioio.examples.hello;

import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.IOIO.VersionType;
import ioio.lib.api.Uart;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.AbstractIOIOActivity;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOActivity;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.widget.ToggleButton;


import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.IOException;

/**
* This is the main activity of the HelloIOIO example application.
* <p/>
* It displays a toggle button on the screen, which enables control of the
* on-board LED. This example shows a very simple usage of the IOIO, by using
* the {@link IOIOActivity} class. For a more advanced use case, see the
* HelloIOIOPower example.
*/
public class MainActivity extends IOIOActivity {
    private ToggleButton button_;
    Button btnSend;
    Button button2_;
    Button button3_;
    Button button4_;
    EditText txtTX, txtRX;

    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    private GoogleApiClient client;

    /**
     * Called when the activity is first created. Here we normally initialize
     * our GUI.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
        button_ = (ToggleButton) findViewById(R.id.button);
        btnSend = (Button) findViewById(R.id.Sendbutton);
        txtTX = (EditText) findViewById(R.id.editText);
        txtRX = (EditText) findViewById(R.id.editText2);
        button2_ = (Button) findViewById(R.id.button2);
        button3_ = (Button) findViewById(R.id.button3);
        button4_ = (Button) findViewById(R.id.button4);
        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
    }

    @Override
    public void onStart() {
        super.onStart();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client.connect();
        Action viewAction = Action.newAction(
                Action.TYPE_VIEW, // TODO: choose an action type.
                "Main Page", // TODO: Define a title for the content shown.
                // TODO: If you have web page content that matches this app activity's content,
                // make sure this auto-generated web page URL is correct.
                // Otherwise, set the URL to null.
                Uri.parse("http://host/path"),
                // TODO: Make sure this auto-generated app URL is correct.
                Uri.parse("android-app://ioio.examples.hello/http/host/path")
        );
        AppIndex.AppIndexApi.start(client, viewAction);
        txtRX.setEnabled(false);
    }

    @Override
    public void onStop() {
        super.onStop();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        Action viewAction = Action.newAction(
                Action.TYPE_VIEW, // TODO: choose an action type.
                "Main Page", // TODO: Define a title for the content shown.
                // TODO: If you have web page content that matches this app activity's content,
                // make sure this auto-generated web page URL is correct.
                // Otherwise, set the URL to null.
                Uri.parse("http://host/path"),
                // TODO: Make sure this auto-generated app URL is correct.
                Uri.parse("android-app://ioio.examples.hello/http/host/path")
        );
        AppIndex.AppIndexApi.end(client, viewAction);
        client.disconnect();
    }

    /**
     * This is the thread on which all the IOIO activity happens. It will be run
     * every time the application is resumed and aborted when it is paused. The
     * method setup() will be called right after a connection with the IOIO has
     * been established (which might happen several times!). Then, loop() will
     * be called repetitively until the IOIO gets disconnected.
     */
    class Looper extends BaseIOIOLooper {
        /**
         * The on-board LED.
         */
        private DigitalOutput led_;
        Uart uart;
        private OutputStream out;
        private InputStream in;
        private BufferedReader reader;
        private int szamlalo = 0;
        /**
         * Called every time a connection with IOIO has been established.
         * Typically used to open pins.
         *
         * @throws ConnectionLostException When IOIO connection is lost.
         * @see IOIOLooper#setup()
         */
        @Override
        protected void setup() throws ConnectionLostException {
            showVersions(ioio_, "IOIO connected!");
            led_ = ioio_.openDigitalOutput(IOIO.LED_PIN, true);
            enableUi(true);

            uart = ioio_.openUart(4, 3, 19200, Uart.Parity.NONE, Uart.StopBits.ONE);
            in = uart.getInputStream();
            out = uart.getOutputStream();
            toast(new String("OpenUart"));

            btnSend.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {
                        String codetext = txtTX.getText().toString();

                        codetext += "\r\n";
                        //byte[] wrBuff = txtTX.getText().toString().getBytes();

                        byte[] wrBuff = codetext.toString().getBytes();
                        out.write(wrBuff);
                        Thread.sleep(100);

                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();

                    }
                }
            });
            button3_.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {
                        String codetext = "*INFO\r\n";
                        byte[] wrBuff = codetext.toString().getBytes();
                        out.write(wrBuff);
                        Thread.sleep(100);

                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();

                    }

                }
            });

            button2_.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {
                        String codetext = "*GTIM\r\n";
                        byte[] wrBuff = codetext.toString().getBytes();
                        out.write(wrBuff);
                    } catch (IOException e) {
                        e.printStackTrace();


                    }

                }
            });
            button4_.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    /*try {

                        Thread.sleep(100);
                        byte[] rdBuff = new byte[in.available()];
                        in.read(rdBuff);
                        txtRX.setText(new String(rdBuff));


                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();

                    }*/

                }
            });

        }

        /**
         * Called repetitively while the IOIO is connected.
         *
         * @throws ConnectionLostException When IOIO connection is lost.
         * @throws InterruptedException    When the IOIO thread has been interrupted.
         * @see IOIOLooper#loop()
         */
        @Override
        public void loop() throws ConnectionLostException, InterruptedException {
            /*led_.write(!button_.isChecked());*/
            BufferedReader reader=new BufferedReader(new InputStreamReader(in));
            try {
                InputStream reading = uart.getInputStream();

                if (in.available() > 0) {
                    BufferedReader rd = new BufferedReader(new InputStreamReader(reading));

                    String line = rd.readLine();
                    //rd.close();
                    setText((szamlalo++) + ": " + line);
                    if (line.length() > 5) {
                        led_.write(false);
                        //Thread.sleep(500);
                        String codetext = "V\r\n";
                        byte[] wrBuff = codetext.toString().getBytes();
                        out.write(wrBuff);
                        setText((szamlalo++) + ": V");
                        Thread.sleep(100);
                        led_.write(true);
                        //Thread.sleep(500);
                    }
                }
                //writeAlert(line);

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        @Override
        public void disconnected() {
            enableUi(false);
            toast("IOIO disconnected");
        }

        /**
         * Called when the IOIO is connected, but has an incompatible firmware version.
         *
         * @see IOIOLooper#incompatible(IOIO)
         */
        @Override
        public void incompatible() {
            showVersions(ioio_, "Incompatible firmware version!");
        }
    }

    /**
     * A method to create our IOIO thread.
     *
     * @see AbstractIOIOActivity#createIOIOThread()
     */
    @Override
    protected IOIOLooper createIOIOLooper() {
        return new Looper();
    }
    private void setText(final String str) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                String s = str + "\r\n" + txtRX.getText();
                if (s.length()>100) {
                    s = str + "\r\n";
                }
                //String s = txtRX.getText() + "";
                txtRX.setText( s );
            }
        });
    }

    private void showVersions(IOIO ioio, String title) {
        toast(String.format("%s\n" +
                        "IOIOLib: %s\n" +
                        "Application firmware: %s\n" +
                        "Bootloader firmware: %s\n" +
                        "Hardware: %s",
                title,
                ioio.getImplVersion(VersionType.IOIOLIB_VER),
                ioio.getImplVersion(VersionType.APP_FIRMWARE_VER),
                ioio.getImplVersion(VersionType.BOOTLOADER_VER),
                ioio.getImplVersion(VersionType.HARDWARE_VER)));
    }

    private void toast(final String message) {
        final Context context = this;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(context, message, Toast.LENGTH_LONG).show();
            }
        });
    }

    private int numConnected_ = 0;

    private void enableUi(final boolean enable) {
        // This is slightly trickier than expected to support a multi-IOIO use-case.
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (enable) {
                    if (numConnected_++ == 0) {
                        button_.setEnabled(true);
                    }
                } else {
                    if (--numConnected_ == 0) {
                        button_.setEnabled(false);
                    }
                }
            }
        });
    }
}
this will write to ioio immediately the one character command after read and this program can't make error, I tested it about 100000 cycles lasting for hours.
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
I made another test with error call-stack.
Here is the B4A program:
B4X:
#Region  Project Attributes
    #ApplicationLabel: Megabox Android 4.4
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
 
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
Dim yoyo As IOIO
Dim uart1 As Uart
Dim in1 As InputStream
Dim out1 As OutputStream
Dim szam As Int

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
Dim txtSend As EditText
Dim txtRX As EditText
Dim TimerRX As Timer
Dim lbStatus As Label
    Private btnSend As Button
    Private ListView1 As ListView
    Private chbox1 As CheckBox
    Private chbox2 As CheckBox
    Private Label2 As Label
    Private Label1 As Label
    Private RadioButton2 As RadioButton
    Private RadioButton1 As RadioButton
    Private ImageView1 As ImageView
 
'    Private AutoCompleteEditText1 As AutoCompleteEditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("lay1")
    yoyo.Initialize
    yoyo.ReceiverRegister
    yoyo.Connect("yoyo",yoyo.CONN_OPEN_ACC,0,10)
    ListView1.Clear
    Activity.Title="Pigeonbox IOIO"
 
End Sub

Sub yoyo_connected(noerror As Boolean)
    'connected event, if noerror than connection made
    If noerror Then
        'sikeres csatlakozás, megnyitom a további portokat is
        Log("YOYO connected")
        Try
            Log("IOIO Hardware: " & yoyo.GetIOIOVersion(yoyo.VER_HARDWARE))
            Log("IOIO Bootloader: " & yoyo.GetIOIOVersion(yoyo.VER_BOOTLOADER))
            Log("IOIO Firmware: " & yoyo.GetIOIOVersion(yoyo.VER_FIRMWARE))
            Log("IOIO Library: " & yoyo.GetIOIOVersion(yoyo.VER_IOIOLIB))
            Log("B4A Library: v"& yoyo.Version&CRLF&CRLF)
         
            Log("Android Release: "& yoyo.DEVICE_RELEASE)
            Log("Android API: "& yoyo.DEVICE_SDK)     
            'ProgressDialogHide
            'led = YOYO.OpenDigitalOutput( 0,led.OP_NORMAL ,True) ' Enable LED_PIN for output
            yoyo.OpenUart("uart",4,uart1.IP_FLOATING,3,uart1.OP_NORMAL,19200,uart1.PARITY_NONE,uart1.STOPBIT_ONE)
        Catch
            Log(LastException.Message)
        End Try 
    Else
        Dim trouble As Exception
        trouble=LastException
        ToastMessageShow(trouble.Message,False)
        Log("yoyo.connect:"&trouble.Message)
    End If
End Sub

Sub uart_open(noerror As Boolean, result As Object, input As Object, output As Object)
    'get input and output stream as here well
    If noerror Then
        uart1=result
        in1=input
        out1=output 
        TimerRX.Initialize("TimerRX",1000)
        TimerRX.enabled = True
        Log("Write mode")
        btnSend.Enabled = True
        chbox1.Enabled =True
     
    Else
        Dim trouble As Exception
        trouble=LastException
        Log("yoyo.openuart:"&trouble.Message)
    End If
End Sub
Sub btnSend_Click
'If rbtn_Single.Checked=True Then
'led.Write(Not(LedFlag)) ' Turn on/off stat LED, active LOW
'LedFlag = Not ( LedFlag )
If uart1.IsInitialized Then
    'getSetUPValue
    'uart1.Close
    'IN1.Close
    'OUT1.Close
    'uart1= YOYO.OpenUart(RXPIN,RXPINTYPE,TXPIN,TXPINTYPE,BAUDRATE,uart1.PARITY_NONE,uart1.STOPBIT_ONE)
    'in1=uart1.InputStream
    'out1=uart1.OutputStream
     If txtSend.Text.Length > 0 Then
        Dim buffer() As Byte
        Dim ST As String
        ST=txtSend.Text & Chr(13) & Chr(10) 'CRLF
        buffer =ST.GetBytes("UTF8")
        out1.WriteBytes(buffer,0,buffer.Length)
        out1.Flush
        txtSend.SelectAll   

    End If
End If
End Sub


Sub TimerRX_Tick()
    If uart1.IsInitialized Then
        'If in1.BytesAvailable>0 Then
            TimerRX.Enabled=False
            '*** need to assign the exact buffer size as in BytesAvailable or it won't work
            Dim buffer(in1.BytesAvailable) As Byte
            Dim count As Int
            count = in1.ReadBytes(buffer, 0,buffer.Length)
            'lbStatus.Text="Read " & count & " bytes. @ " & DateTime.Time(DateTime.Now)
            If count > 0 Then
                szam = szam + 1
                'txtRX.Text= BytesToString(buffer, 0, count, "UTF8")
                'txtRX.SelectionStart = txtRX.Text.Length
            ListView1.AddSingleLine(szam & Chr(9) & BytesToString(buffer, 0, count, "UTF8") &Chr(13) &Chr(10))
            If chbox1.Checked = True Then
                    If txtSend.Text.Length > 0 Then
                           Dim buffer() As Byte
                        Dim ST As String
                        ST=txtSend.Text & Chr(13) & Chr(10) 'CRLF
                        buffer =ST.GetBytes("UTF8")
                        out1.WriteBytes(buffer,0,buffer.Length)
                        out1.Flush
                        txtSend.SelectAll
                    End If
    '***automatikus text küldés
                    End If
         
     
        End If
    End If
    TimerRX.Enabled=True
End Sub

Sub Activity_Resume
    yoyo.Connect("yoyo",yoyo.CONN_OPEN_ACC,0,10)
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed Then
        yoyo.ReceiverUnregister
    End If

End Sub

Sub RadioButton2_CheckedChange(Checked As Boolean)
    If Checked=True Then
    txtSend.Text="*GTIM"
    Else
    txtSend.Text=""
    End If
End Sub
Sub RadioButton1_CheckedChange(Checked As Boolean)
    If Checked=True Then
    txtSend.Text="*INFO"
    Else
    txtSend.Text=""
    End If
End Sub
Here is the error call-stak from B4A. It happens when I want to send anything to ioio.
B4X:
YOYO connected
IOIO Hardware: SPRK0020
IOIO Bootloader: IOIO0401
IOIO Firmware: IOIO0506
IOIO Library: IOIO0504
B4A Library: v2.05
Android Release: 4.2.1
Android API: 17
Write mode
yoyo.connect:java.lang.NullPointerException
Error occurred on line: 123 (Main)
java.io.IOException: Stream has been closed
    at ioio.lib.impl.FlowControlledOutputStream.write(FlowControlledOutputStream.java:83)
    at java.io.OutputStream.write(OutputStream.java:106)
    at anywheresoftware.b4a.objects.streams.File$OutputStreamWrapper.WriteBytes(File.java:455)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:680)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:308)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:238)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:78)
    at android.view.View.performClick(View.java:4211)
    at android.view.View$PerformClick.run(View.java:17446)
    at android.os.Handler.handleCallback(Handler.java:725)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:153)
    at android.app.ActivityThread.main(ActivityThread.java:5297)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    at dalvik.system.NativeStart.main(Native Method)
** Activity (main) Pause, UserClosed = true **
** Activity (main) Resume **
 
Last edited:
Upvote 0

kolbe

Active Member
Licensed User
Longtime User
@rosippc64a

I'm not going to spend time on the first program b/c it uses the old library that is deprecated. I don't see a reason to spend time on that.

As for the post above. A few possibilities.

In the Activity_Resume you ioio.connect again without ever disconnecting. This might cause problems as you are reconnecting without properly disconnecting the ioio. All you need is a ReceiverUnregister and Disconnect when UserClosed is true.

Also try removing the out1.flush or putting it before the out1.writebytes.

Also try using the byteconverter library instead of string.getbytes. I'm not sure what this would do but that is what I do.

I'll try running the program myself when I get a chance. The log you posted is a start but it's not enough. I need the full logs to see what is happening and not just the B4A log.

Have you tried this with Firmware 504? I've never tested it on 506.
 
Upvote 0

kolbe

Active Member
Licensed User
Longtime User
@rosippc64a

I'm not going to spend time on the first program b/c it uses the old library that is deprecated. I don't see a reason to spend time on that.

As for the post above. A few possibilities.

In the Activity_Resume you ioio.connect again without ever disconnecting. This might cause problems as you are reconnecting without properly disconnecting the ioio. All you need is a ReceiverUnregister and Disconnect when UserClosed is true.

Also try removing the out1.flush or putting it before the out1.writebytes.

Also try using the byteconverter library instead of string.getbytes. I'm not sure what this would do but that is what I do.

I'll try running the program myself when I get a chance. The log you posted is a start but it's not enough. I need the full logs to see what is happening and not just the B4A log.

Have you tried this with Firmware 504? I've never tested it on 506.

I just saw this in the log.

yoyo.connect:java.lang.NullPointerException

Seems to me that my first suggestion is the problem. While trying to connect, it reconnects, the timer is still running, and the streams are not there.
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
I didn't try with firmware 0504.
Here is a new source code:
B4X:
 #Region  Project Attributes
    #ApplicationLabel: Megabox Android 4.4
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
   
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
Dim yoyo As IOIO
Dim uart1 As Uart
Dim in1 As InputStream
Dim out1 As OutputStream
Dim szam As Int

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
Dim txtSend As EditText
Dim txtRX As EditText
Dim TimerRX As Timer
Dim lbStatus As Label
    Private btnSend As Button
    Private ListView1 As ListView
    Private chbox1 As CheckBox
    Private chbox2 As CheckBox
    Private Label2 As Label
    Private Label1 As Label
    Private RadioButton2 As RadioButton
    Private RadioButton1 As RadioButton
    Private ImageView1 As ImageView
   
'    Private AutoCompleteEditText1 As AutoCompleteEditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("lay1")
    yoyo.Initialize
    yoyo.ReceiverRegister
    yoyo.Connect("yoyo",yoyo.CONN_OPEN_ACC,0,10)
    ListView1.Clear
    Activity.Title="Pigeonbox IOIO"
   
End Sub

Sub yoyo_connected(noerror As Boolean)
    'connected event, if noerror than connection made
    If noerror Then
        'sikeres csatlakozás, megnyitom a további portokat is
        Log("YOYO connected")
        Try
            Log("IOIO Hardware: " & yoyo.GetIOIOVersion(yoyo.VER_HARDWARE))
            Log("IOIO Bootloader: " & yoyo.GetIOIOVersion(yoyo.VER_BOOTLOADER))
            Log("IOIO Firmware: " & yoyo.GetIOIOVersion(yoyo.VER_FIRMWARE))
            Log("IOIO Library: " & yoyo.GetIOIOVersion(yoyo.VER_IOIOLIB))
            Log("B4A Library: v"& yoyo.Version&CRLF&CRLF)
           
            Log("Android Release: "& yoyo.DEVICE_RELEASE)
            Log("Android API: "& yoyo.DEVICE_SDK)       
            'ProgressDialogHide
            'led = YOYO.OpenDigitalOutput( 0,led.OP_NORMAL ,True) ' Enable LED_PIN for output
            yoyo.OpenUart("uart",4,uart1.IP_FLOATING,3,uart1.OP_NORMAL,19200,uart1.PARITY_NONE,uart1.STOPBIT_ONE)
        Catch
            Log(LastException.Message)
        End Try   
    Else
        Dim trouble As Exception
        trouble=LastException
        ToastMessageShow(trouble.Message,False)
        Log("yoyo.connect:"&trouble.Message)
    End If
End Sub

Sub uart_open(noerror As Boolean, result As Object, input As Object, output As Object)
    'get input and output stream as here well
    If noerror Then
        uart1=result
        in1=input
        out1=output   
        TimerRX.Initialize("TimerRX",1000)
        TimerRX.enabled = True
        Log("Write mode")
        btnSend.Enabled = True
        chbox1.Enabled =True
       
    Else
        Dim trouble As Exception
        trouble=LastException
        Log("yoyo.openuart:"&trouble.Message)
    End If
End Sub


Sub btnSend_Click
'If rbtn_Single.Checked=True Then
'led.Write(Not(LedFlag)) ' Turn on/off stat LED, active LOW
'LedFlag = Not ( LedFlag )
If uart1.IsInitialized Then
    'getSetUPValue
    'uart1.Close
    'IN1.Close
    'OUT1.Close
    'uart1= YOYO.OpenUart(RXPIN,RXPINTYPE,TXPIN,TXPINTYPE,BAUDRATE,uart1.PARITY_NONE,uart1.STOPBIT_ONE)
    'in1=uart1.InputStream
    'out1=uart1.OutputStream
     If txtSend.Text.Length > 0 Then
        Dim buffer() As Byte
        Dim ST As String
        ST=txtSend.Text & Chr(13) & Chr(10) 'CRLF
        buffer =ST.GetBytes("UTF8")
        out1.WriteBytes(buffer,0,buffer.Length)
        out1.Flush
        txtSend.SelectAll
       
   
    End If
   
End If
End Sub


Sub TimerRX_Tick()
    If uart1.IsInitialized Then
        'If in1.BytesAvailable>0 Then
            TimerRX.Enabled=False
            '*** need to assign the exact buffer size as in BytesAvailable or it won't work
            Dim buffer(in1.BytesAvailable) As Byte
            Dim count As Int
            count = in1.ReadBytes(buffer, 0,buffer.Length)
            'lbStatus.Text="Read " & count & " bytes. @ " & DateTime.Time(DateTime.Now)
            If count > 0 Then
                szam = szam + 1
                'txtRX.Text= BytesToString(buffer, 0, count, "UTF8")
                'txtRX.SelectionStart = txtRX.Text.Length
            ListView1.AddSingleLine(szam & Chr(9) & BytesToString(buffer, 0, count, "UTF8") &Chr(13) &Chr(10))
            If chbox1.Checked = True Then
                    If txtSend.Text.Length > 0 Then
                           Dim buffer() As Byte
                        Dim bt As ByteConverter
                        buffer =bt.StringToBytes(txtSend.Text,"UTF-8")
                        out1.WriteBytes(buffer,0,buffer.Length)
                        'out1.Flush
                        txtSend.SelectAll
                    End If
    '***automatikus text küldés
                    End If    
        End If
    End If
    TimerRX.Enabled=True
End Sub

Sub Activity_Resume
    'yoyo.Connect("yoyo",yoyo.CONN_OPEN_ACC,0,10)
End Sub
Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed Then
        yoyo.ReceiverUnregister
        yoyo.Disconnect
    End If
End Sub
Sub RadioButton2_CheckedChange(Checked As Boolean)
    If Checked=True Then
    txtSend.Text="*GTIM"
    Else
    txtSend.Text=""
    End If
End Sub
Sub RadioButton1_CheckedChange(Checked As Boolean)
    If Checked=True Then
    txtSend.Text="*INFO"
    Else
    txtSend.Text=""
    End If
End Sub
Sub btnDicConnect_Click
    If yoyo.State = "CONNECTED" Then
        Log("yoyo will disconnect")
        yoyo.ReceiverUnregister
        yoyo.Disconnect   
    Else   
        Log(yoyo.State)
    End If
End Sub
Sub btnConnect_Click
    If yoyo.State <> "CONNECTED" Then
        Log("yoyo will connect")
        Try
            yoyo.Connect("yoyo",yoyo.CONN_OPEN_ACC,0,10)
        Catch
            Log(LastException.Message)
        End Try
    End If   
End Sub
and here is a call-stack:
B4X:
** Activity (main) Pause, UserClosed = false **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
YOYO connected
IOIO Hardware: SPRK0020
IOIO Bootloader: IOIO0401
IOIO Firmware: IOIO0506
IOIO Library: IOIO0504
B4A Library: v2.05
Android Release: 4.2.1
Android API: 17
Write mode
Error occurred on line: 141 (Main)
java.io.IOException: Stream has been closed
    at ioio.lib.impl.QueueInputStream.read(QueueInputStream.java:75)
    at anywheresoftware.b4a.objects.streams.File$InputStreamWrapper.ReadBytes(File.java:406)
    at b4a.example.main._timerrx_tick(main.java:509)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:636)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:302)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:238)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
    at anywheresoftware.b4a.objects.Timer$TickTack.run(Timer.java:105)
    at android.os.Handler.handleCallback(Handler.java:725)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:153)
    at android.app.ActivityThread.main(ActivityThread.java:5297)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    at dalvik.system.NativeStart.main(Native Method)
** Activity (main) Pause, UserClosed = true **
** Activity (main) Resume **
After this I eliminated fully the st.getbytes
B4X:
 #Region  Project Attributes
    #ApplicationLabel: Megabox Android 4.4
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
   
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
Dim yoyo As IOIO
Dim uart1 As Uart
Dim in1 As InputStream
Dim out1 As OutputStream
Dim szam As Int

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
Dim txtSend As EditText
Dim txtRX As EditText
Dim TimerRX As Timer
Dim lbStatus As Label
    Private btnSend As Button
    Private ListView1 As ListView
    Private chbox1 As CheckBox
    Private chbox2 As CheckBox
    Private Label2 As Label
    Private Label1 As Label
    Private RadioButton2 As RadioButton
    Private RadioButton1 As RadioButton
    Private ImageView1 As ImageView
'    Private AutoCompleteEditText1 As AutoCompleteEditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("lay1")
    yoyo.Initialize
    yoyo.ReceiverRegister
    yoyo.Connect("yoyo",yoyo.CONN_OPEN_ACC,0,10)
    ListView1.Clear
    Activity.Title="Pigeonbox IOIO"
End Sub

Sub yoyo_connected(noerror As Boolean)
    'connected event, if noerror than connection made
    If noerror Then
        'sikeres csatlakozás, megnyitom a további portokat is
        Log("YOYO connected")
        Try
            Log("IOIO Hardware: " & yoyo.GetIOIOVersion(yoyo.VER_HARDWARE))
            Log("IOIO Bootloader: " & yoyo.GetIOIOVersion(yoyo.VER_BOOTLOADER))
            Log("IOIO Firmware: " & yoyo.GetIOIOVersion(yoyo.VER_FIRMWARE))
            Log("IOIO Library: " & yoyo.GetIOIOVersion(yoyo.VER_IOIOLIB))
            Log("B4A Library: v"& yoyo.Version&CRLF&CRLF)
           
            Log("Android Release: "& yoyo.DEVICE_RELEASE)
            Log("Android API: "& yoyo.DEVICE_SDK)       
            'ProgressDialogHide
            'led = YOYO.OpenDigitalOutput( 0,led.OP_NORMAL ,True) ' Enable LED_PIN for output
            yoyo.OpenUart("uart",4,uart1.IP_FLOATING,3,uart1.OP_NORMAL,19200,uart1.PARITY_NONE,uart1.STOPBIT_ONE)
        Catch
            Log(LastException.Message)
        End Try   
    Else
        Dim trouble As Exception
        trouble=LastException
        ToastMessageShow(trouble.Message,False)
        Log("yoyo.connect:"&trouble.Message)
    End If
End Sub

Sub uart_open(noerror As Boolean, result As Object, input As Object, output As Object)
    'get input and output stream as here well
    If noerror Then
        uart1=result
        in1=input
        out1=output   
        TimerRX.Initialize("TimerRX",1000)
        TimerRX.enabled = True
        Log("Write mode")
        btnSend.Enabled = True
        chbox1.Enabled =True
    Else
        Dim trouble As Exception
        trouble=LastException
        Log("yoyo.openuart:"&trouble.Message)
    End If
End Sub
Sub btnSend_Click
If uart1.IsInitialized Then
     If txtSend.Text.Length > 0 Then
        sendtx
    End If    
End If
End Sub
Sub sendtx
    Dim buffer() As Byte
    Dim bt As ByteConverter
    buffer =bt.StringToBytes(txtSend.Text,"UTF-8")
    out1.WriteBytes(buffer,0,buffer.Length)
    'out1.Flush
    txtSend.SelectAll
End Sub

Sub TimerRX_Tick()
    If uart1.IsInitialized Then
        'If in1.BytesAvailable>0 Then
            TimerRX.Enabled=False
            '*** need to assign the exact buffer size as in BytesAvailable or it won't work
            Dim buffer(in1.BytesAvailable) As Byte
            Dim count As Int
            count = in1.ReadBytes(buffer, 0,buffer.Length)
            If count > 0 Then
                szam = szam + 1
            ListView1.AddSingleLine(szam & Chr(9) & BytesToString(buffer, 0, count, "UTF8") &Chr(13) &Chr(10))
            If chbox1.Checked = True Then
                If txtSend.Text.Length > 0 Then
                    sendtx
                End If
               End If    
        End If
    End If
    TimerRX.Enabled=True
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed Then
        btnDicConnect_Click
    End If
End Sub
Sub RadioButton2_CheckedChange(Checked As Boolean)
    If Checked=True Then
    txtSend.Text="*GTIM"
    Else
    txtSend.Text=""
    End If
End Sub
Sub RadioButton1_CheckedChange(Checked As Boolean)
    If Checked=True Then
        txtSend.Text="*INFO"
    Else
    txtSend.Text=""
    End If
End Sub
Sub btnDicConnect_Click
    If yoyo.State = "CONNECTED" Then
        Log("yoyo will disconnect")
        yoyo.ReceiverUnregister
        yoyo.Disconnect   
    Else   
        Log(yoyo.State)
    End If
End Sub
Sub btnConnect_Click
    If yoyo.State <> "CONNECTED" Then
        Log("yoyo will connect")
        Try
            yoyo.Connect("yoyo",yoyo.CONN_OPEN_ACC,0,10)
        Catch
            Log(LastException.Message)
        End Try
    End If   
End Sub
and there was a total surprising: the phone went power off at the first send (in debug mode), and when I power on newly, the b4a can't connect to the phone ADB until restarting the phone. The phone will not power off while it in power unit, this was because of the sending. I repeated the whole process some times, and I stop since the result was the same.
If I install the above program without debug mode, restart the phone while the yoyo is connected, the error happen immediately. If restart the phone without yoyo is connected, and I first start the program and connect the yoyo, the program works until the first sending, then stream... error happen. Then I exit the program and restart, ot disconnect and connect - yoyo can't connect only if I remove yoyo from phone. The all thing start from the beginning. I lost what happen and why.
So from now on I can't get error call stack.
 
Upvote 0

kolbe

Active Member
Licensed User
Longtime User
@rosippc64a

Try the app attached. This works for me no problems. I used the device mode but it shouldn't make a difference just change to CONN_OPEN_ACC.

If the attached app still gives you problems I would think it isn't a software issue. Sounds like a hardware issue. Check all your cables, voltages, grounding. Then again you say it works fine with your java app.

Try just connecting the pins 4 and 3 together, don't attach the reader. Whatever you send you receive back. This is what I did, actually I just put my finger across the pins.

Maybe try the 500 firmware? I could also try the open accessory and see if there is a difference.

Here's the log.

** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **
sending message to waiting queue (disconnect_done)
** Activity (main) Create, isFirst = false **
running waiting messages (1)
** Activity (main) Resume **
yoyo will connect
YOYO connected
IOIO Hardware: SPRK0020
IOIO Bootloader: IOIO0400
IOIO Firmware: IOIO0500
IOIO Library: IOIO0504
B4A Library: v2.05
Android Release: 6.0.1
Android API: 23
Write mode
btnSend :doboz
timer :doboz
btnSend :doboz
timer :doboz
btnSend :doboz
timer :doboz
btnSend :doboz
timer :doboz
btnSend :doboz
timer :doboz
btnSend :doboz
timer :doboz
btnSend :doboz
timer :doboz
btnSend :doboz
timer :doboz
btnSend :doboz
timer :doboz
yoyo will disconnect
** Activity (main) Pause, UserClosed = true **
sending message to waiting queue (disconnect_done)
 

Attachments

  • uart problem.zip
    11 KB · Views: 254
Last edited:
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
Kolbe, thank you very much for your effort. I tried the attached app, the result is the same, even then, when I remove reader and shorted the rx-tx pins. And yes, I tried the java app, what works fine. I can't figure out what would be the difference!
By the way this issue is since I wanted to move to ioio lib 2.05. The old lib (1.4) worked (and works) fine with this hw, but I have to eliminate the trouble of .waitforconnect() and others.
Tomorrow I try with another tablet, newer as my old 4.2
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
I tried the attached program on a tablet having android 4.4 and the result is the same, except the error appear later, not at the first writing.
 
Upvote 0

kolbe

Active Member
Licensed User
Longtime User
I just uploaded version 2.07 of the IOIO library. It includes the latest commits from Ytai plus a few bug fixes and doc corrections.

For this version your IOIO should be running version 5.06 of the application firmware.

Let me know if this version helps any with your problem.

Since I can't reproduce your problem the only thing that can help me are the complete logs. The log you posted above is just the b4a log. Uncheck filter on the logs tab in the IDE.

The best I can guess at the moment is that you are loosing your connection to the IOIO and that is why the stream in closed. So the question is why is the connection dropping?
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
Hi Kolbe,
I tried the new library, but the result is the same. But I vainly uncheck the filter on the b4a ide (Kolbe, how can I get a more detailed log from b4a ide?), the result is very short-spoken.
This error happen only when I write to the uart, and in return the uart send me the result. If I don't write, there is no error.
--------------------------------------------------------
Installing file.
PackageAdded: package:b4a.example
Copying updated assets files (7)
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
yoyo.connect:java.lang.NullPointerException
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
yoyo will connect
YOYO connected
IOIO Hardware: SPRK0020
IOIO Bootloader: IOIO0401
IOIO Firmware: IOIO0506
IOIO Library: IOIO0507
B4A Library: v2.07
Android Release: 4.2.1
Android API: 17
Write mode
Error occurred on line: 124 (Main)
java.io.IOException: Stream has been closed
at ioio.lib.impl.QueueInputStream.read(QueueInputStream.java:75)
at anywheresoftware.b4a.objects.streams.File$InputStreamWrapper.ReadBytes(File.java:406)
at b4a.example.main._timerrx_tick(main.java:586)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:702)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:336)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:246)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at anywheresoftware.b4a.objects.Timer$TickTack.run(Timer.java:105)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5297)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
** Activity (main) Pause, UserClosed = true **
B4X:
Sub TimerRX_Tick()
    If uart1.IsInitialized Then
        'If in1.BytesAvailable>0 Then
            TimerRX.Enabled=False
            '*** need to assign the exact buffer size as in BytesAvailable or it won't work
            Dim buffer(in1.BytesAvailable) As Byte
            Dim count As Int
            count = in1.ReadBytes(buffer, 0,buffer.Length) '<- line 124 where error occured.
            If count > 0 Then
                szam = szam + 1
            ListView1.AddSingleLine(szam & Chr(9) & BytesToString(buffer, 0, count, "UTF8") &Chr(13) &Chr(10))
            If chbox1.Checked = True Then
                If txtSend.Text.Length > 0 Then
                    sendtx
                End If
               End If  
        End If
    End If
    TimerRX.Enabled=True
End Sub
-----------------------------
I am desperated. I think I take the small java program what works well (what I showed to you before), and try to make from it a very small library. At first only the uart read-write part. I start it in the meantime while I write this, and it made a cycle of reading-writing 1342.

The small library writing is not an easy task in this level. What a pity.
 
Last edited:
Upvote 0

kolbe

Active Member
Licensed User
Longtime User
The log is showing that the IOIO has disconnected when you try to readbytes. So I suggest you look carefully how you manage the connection. To debug maybe check connection before every readbyte, once per timer loop.

I noticed this at the beginning of the log.

B4X:
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
yoyo.connect:java.lang.NullPointerException
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
yoyo will connect
YOYO connected

When your activity resumes ioio is null, why is that? It then goes on to connect. You need to make sure the IOIO stays connected in all your activity states.

API 17 is Android 4.2, have you tried this on different devices?

The java app that you say works, you run that on the same android device and it works?

I just released the library for B4J, maybe that will work for you.
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
Hi Kolbe,
thank you for your reply.
I think this null value is for a previous frozen state. Now I am playing with new lib and while it was in debug mode there was multiple occasion when after a frozen state the next running 'remember' the previous erroneous state.
I tried other tab too, this worked only until I wanted to send any string to uart. And when I start the java program in the same tab, this runs and works and do everything. So I decided to transform this working java program into a lib, but this isn't an easy task. I am just there that how to connect the ioio to the hw.
This b4j lib I can use with a b4a program?
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
Thread is closed with success. I made a my own library (thanks Kolbe) where these streams is situated in this, not in b4a program. From this there is no such an error.
 
Upvote 0
Top