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;
}
}
}