0
votes

I am currently facing a serial communication problem that has had me stumped for a few days now.

The application is a type of personal RFID tag inventory system. The end goal is to scan RFID tags and log them into the arduino FRAM, and to relay the tag data to an android smartphone application I am making. I am new to Java and Android development as a whole, and I am having problems reading (RX) serial data that the arduino is writing (TX).

I am using a bluetooth adapter (Bluesmirf, RN42 modem), and pairing and connectivity is all good there.

I am able to transmit from the android phone a "Refresh Inventory" toggle, and the Arduino does indeed receive it, as it jumps to the AndroidRefresh() function, as can be seen in the code. However, when I attempt to write a test RFID tag, the Android doesn't see anything.

I am 80% sure it is a flaw within my Android code. I'm thinking perhaps its a "timing" issue, because as soon as the "refresh Inventory" button is toggled on the Android, it sends the "flag int" to send the arduino into AndroidRefresh(), and immediately in both scripts, the arduino writes, and the Android listens. I'm new to serial communication, and I'm not sure if this data disappears off the buffer for some reason?

Thanks for any help. This is driving me crazy.

Arduino Snippet:

#include <SoftwareSerial.h>
#include <EEPROM.h>
#include < avr/interrupt.h >
#include < avr/io.h >

//setup serial for RFID reader
#define rxPin 3
#define txPin 2
SoftwareSerial rfserial = SoftwareSerial(rxPin, txPin);

//seek command 0x82
byte SeekCard[] = {0xFF,0x00,0x01,0x82,0x83};
byte value;
int k;
char incomingChar;
long convert = 0;

void setup()
    {

     //set the Serial monitor to preferred baud rate
    Serial.begin(9600);
    //RFID reader is defaulted to 19200 baud rate
    rfserial.begin(19200);
   // for (int i =0; i< 7; i++){


                 // convert = convert + test[i];
                  //Serial.println(convert, DEC);
                 // delay(100);

            //    }

    }



void loop()
{

  //find a tag
  if (rfserial.available() > 0){
    SeekTag();
  }

  if (Serial.available() > 0){ 
  androidRefresh(); // Refresh Inventory
  while(Serial.available()>0) Serial.read(); //CLEARS RX BUFFER

  }
}

void SeekTag(){ 
// Do RFID stuff
}

void androidRefresh()
{
  //*************receiving a message from Android and printing on Arduino************************* 
                byte test[] = {0xFF,0x00,0x01,0x82,0x83, 0xFC, 0x64, 0xD0, 0x82,0x83, 0xFF};
                //Serial.println("Refreshing Inventory...");


                for (int i =0; i< 11; i++){                  
                 Serial.write(test[i]);
                 Serial.println(test[i]);
                // Serial.println(test[i], HEX);
               }

                //while(Serial.available()>0) Serial.read(); //CLEARS RX BUFFER



}

And the Android Java Activity:

public class InventoryActivity extends Activity {

    /** Bluetooth Variables **/

    private static BluetoothSocket mbtSocket;
    private static InputStream mbtInputStream;
    private static OutputStream mbtOutputStream;

    private static final String TAG = "SmartFridge"; //Debug
    private static final boolean D = true;          // Debug

    OutputStream tmpOut = null;
    OutputStream mmOutStream = null;    
    InputStream tmpIn = null;
    InputStream mmInStream = null;
    byte[] buffer = new byte[1024];;  // buffer store for the stream
    int bytes; // bytes returned from read()
    int numberofbytes = 0;










  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.inventory);


    final ListView listview = (ListView) findViewById(R.id.listview);
    String[] values = new String[] {    "Item 1 from Arduino",
                                        "Item 2 from Arduino", 
                                        "Item 3 from Arduino",
                                        "Item 4 from Arduino",
                                        "Item 5 from Arduino", 
                                        "and the beat goes on"};

    final ArrayList<String> list = new ArrayList<String>();
    for (int i = 0; i < values.length; ++i) {
      list.add(values[i]);
    }
    final StableArrayAdapter adapter = new StableArrayAdapter(this,
        android.R.layout.simple_list_item_1, list);
    listview.setAdapter(adapter);


  }



  // Menu Stuff

        // Initiating Menu XML file (menu.xml)
        @Override
        public boolean onCreateOptionsMenu(Menu menu)
        {
            MenuInflater menuInflater = getMenuInflater();
            menuInflater.inflate(R.menu.inventory_menu, menu);
            return true;
        }

        /**
         * Event Handling for Individual menu item selected
         * Identify single menu item by it's id
         * */
        @Override
        public boolean onOptionsItemSelected(MenuItem item)
        {

            switch (item.getItemId())
            {

            case R.id.menu_search:
                Toast.makeText(InventoryActivity.this, "Refreshing...", Toast.LENGTH_SHORT).show();

                {    
                    // As suggested by http://developer.android.com/guide/topics/connectivity/bluetooth.html

                    mbtSocket = btWrapper.getSocket();                  


                    try {
                        tmpOut = mbtSocket.getOutputStream();
                        tmpIn = mbtSocket.getInputStream();
                        if(D) Log.e(TAG, "Test 1");
                    } catch (IOException e1) {  }                   
                    mmOutStream = tmpOut;   
                    mmInStream = tmpIn;
                    if(D) Log.e(TAG, "Test 2");
                    try {                       
                                mmOutStream.write(600); // Can be anything, only UI request is to send FRAM contents from Arduino once toggled on phone
                                if(D) Log.e(TAG, "Serial Message Sent to Arduino for Refresh");


                    }
                    catch(Exception e) {}


              }
                /** Read Bluetooth Stuff **/

                // Read from the InputStream
                try {   
                        numberofbytes = mmInStream.available();
                        if(D) Log.e(TAG, numberofbytes + " bytes ready to read");
                        if( mmInStream.available() > 0 )
                        {
                            bytes = mmInStream.read(buffer);
                            if(D) Log.e(TAG, "Received Data from Arduino");
                            if(D) Log.e(TAG, "Received:" + bytes);
                        }



                } catch (IOException e) {
                    if(D) Log.e(TAG, "Did not receive data from Arduino");
                }

                /** End Read Bluetooth Stuff **/



                return true;


            default:
                return super.onOptionsItemSelected(item);
            }
        }   


  //End Menu STuff

  private class StableArrayAdapter extends ArrayAdapter<String> {

    HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();

    public StableArrayAdapter(Context context, int textViewResourceId,
        List<String> objects) {
      super(context, textViewResourceId, objects);
      for (int i = 0; i < objects.size(); ++i) {
        mIdMap.put(objects.get(i), i);
      }
    }

    @Override
    public long getItemId(int position) {
      String item = getItem(position);
      return mIdMap.get(item);
    }

    @Override
    public boolean hasStableIds() {
      return true;
    }

  }

}
1

1 Answers

0
votes

This appears to be a problem with your android code.

The thing you must look into is, at what time does your android code try to listen for the serial data? Looking at the code, it is only when nOptionsItemSelected is called. So by the time the Arduino sends the data back, and the bluetooth modules do their thing, and the Android OS processes it and gives the data to your application, your application may have already finished running your code in nOptionsItemSelected that listens to the data.

A quick fix to test is to just put your reading-serial-data code into a while loop.

while(True){
try {   
                    numberofbytes = mmInStream.available();
                    if(D) Log.e(TAG, numberofbytes + " bytes ready to read");
                    if( mmInStream.available() > 0 )
                    {
                        bytes = mmInStream.read(buffer);
                        if(D) Log.e(TAG, "Received Data from Arduino");
                        if(D) Log.e(TAG, "Received:" + bytes);
                    }



            } catch (IOException e) {
                if(D) Log.e(TAG, "Did not receive data from Arduino");
            }
}