Question

I am currently porting some code I have form C# to Java to run in on an Android system.

In my code, I have to read some data from a board that has a FTDI chip. I am trying to use the java drivers from the FTDI website.

I can connect to the device and send commands to it correctly (LEDs blink as they should). The board appears to be sending me data correctly.

bytesAvailable = ftDevice.getQueueStatus(); returns the expected number

int bytesRead = ftDevice.read(rxData, bytesAvailable); returns the same number

However on calling the read() as above I see the following in my logcat: Cannot read data from Source!! from tag: readBulkInData::

I cannot see what this might be. I tried fiddling with the settings of the device in my code, but to no avail.

Was it helpful?

Solution

I solved this.

By placing the whole sequence of instructions for reading (the getQueueStatus() and the read()) in another Thread. Specifically, I used an AsyncTask, and put the reading instructions in its doInBackground() method.

OTHER TIPS

i have modified the part of the FTDI example for write and wait until receive an answer. this works for me in a simple HMI app for Parker Compax3 servodrives. This sequence is triggered every 100ms.

        // part of FTDI example
        synchronized (ftDev) {
        if(ftDev.isOpen() == false) {
            return;
        }
        ftDev.setLatencyTimer((byte)16);
        String writeString = tvWrite.getText().toString()+"\r";
        byte[] writeByte = writeString.getBytes();
        // write
        ftDev.write(writeByte, writeString.length());

        // new - wait until the buffer have data - no fixed length of incoming data - 4 - 8 bytes     
        readRequest = true;
        startTimeRead = SystemClock.uptimeMillis();
        while (true){
            timeOutInMilliseconds = SystemClock.uptimeMillis() - startTimeRead;

            if (timeOutInMilliseconds > timeOutTime) // checking after 70ms
            {
                readSize = ftDev.getQueueStatus();
                if(readSize>0) {
                        mReadSize = readSize;
                if(mReadSize > READBUF_SIZE) {
                    mReadSize = READBUF_SIZE;
                }

                readCompleted = false;

                // call asynctask
                ReadAsyncTask task = new ReadAsyncTask();
                task.execute();

                // wait until asynctask has completed
                while (readCompleted = false){ // endless loop until asynctask have read
                    if (readCompleted = true){ // <- i know this is not necessary :-)
                        break;  
                    }
                }

                // if read completed, write values to string/textview
                if (readCompleted = true){
                    textView13.setText("Ok" + " " + mReadSize );
                    tvRead.setText(readString); //now it updates the textboxes, strings
                }
            }

            //do anything if there are no data after 70ms
            else{
                readString="**";
                textView13.setText("Timeout, no data");  
                }
            // go out, wait 30ms and do it again
            break;  
            }
        }
    }

here is the asynctask

class ReadAsyncTask extends AsyncTask<Void, Void, Void>{  
      @Override  
      protected Void doInBackground(Void... params) {  

          int j = 0;
          ftDev.read(rbuf,mReadSize);
          for(j=0; j<mReadSize; j++) {
              rchar[j] = (char)rbuf[j];
          }

          // clear buffer
          ftDev.purge((byte) 1);

          // copy to string
          readString =String.copyValueOf(rchar,0,mReadSize);
          readCompleted = true;
          return null;
      }  
      @Override  
      protected void onPreExecute() {  
           super.onPreExecute();  
      }  
      @Override  
      protected void onPostExecute(Void result) {  
           super.onPostExecute(result); 
      }  
 } 

update call after / tricky but it works for me

public void requestCompax() {
    sendseq += 1;
    if (sendseq > 6){
        sendseq = 1;
    }

    switch (sendseq){
    case 1: //request planejado
        tvWrite.setText("O1903.1");         // *send "planejado"
        senddata();                         // call write and read serial
        tvIntrodutor.setText(readString);   // *normally received the answer must be here
        break;

    case 2: //request produzido
        tvWrite.setText("O1903.2");         // send produzido
        senddata();                         // call write and read serial
        tvPlanejado.setText(readString);    // *but received answer "planejado" - it comes here, next call later ?!?!
        break;

   case 3:  //request value caixas
        tvWrite.setText("O1903.3");         // * send caixas
        senddata();
        tvProduzido.setText(readString);    // same with produzido
        break;

    case 4: //request pulas
        tvWrite.setText("O1903.4");         
        senddata();
        tvCaixas.setText(readString);       // same with "caixas"
        break;

    case 5: //request caixas/hora
        tvWrite.setText("O1903.5");         
        senddata();
        tvPulas.setText(readString);         // same with pulas
        break;

    case 6: //request adiantar/atrasar
        tvWrite.setText("O1902.2");         //adiantar/atrasar
        senddata();
        tvCaixasHora.setText(readString);   //same with caixas/hora   
        break;

    default:

        break;
    }
}

its funny, update strings and textboxes at the next task.execute() call. this works for me, maybe a little bit tricky, but i need to read and write only 5 parameters.

anybody in here know how to solve this? this was tested online and with simulator (10ms delay), same results.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top