2013-07-15 50 views
0

我目前正面临一个串口通信问题,这让我难倒了几天。一旦从Arduino TX'd读取蓝牙串行数据Android

该应用程序是一种个人RFID标签库存系统。最终目标是扫描RFID标签并将其登录到arduino FRAM中,并将标签数据转发到我正在制作的Android智能手机应用程序。作为一个整体,我对Java和Android开发不熟悉,并且在读取(RX)arduino正在写入(TX)的串行数据时遇到问题。

我使用的是蓝牙适配器(Bluesmirf,RN42调制解调器),配对和连接都很好。

我可以从Android手机上传输一个“刷新清单”切换,并且Arduino确实会收到它,因为它会跳转到AndroidRefresh()函数,如代码中所示。但是,当我尝试写一个测试RFID标签时,Android没有看到任何东西。

我80%确定这是我的Android代码中的一个缺陷。我在想也许它是一个“时间”问题,因为只要在Android上切换“刷新库存”按钮,它会发送“标志int”将arduino发送到AndroidRefresh(),并立即在两个脚本中, arduino写道,而Android收听。我是新来的串行通信,我不确定这个数据是否由于某种原因从缓冲区中消失了?

感谢您的任何帮助。这真让我抓狂。

Arduino的摘录:

#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 



} 

和Android的Java活动:

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

    } 

} 

回答

0

这似乎是与Android的代码有问题。

你必须看看的东西是,你的android代码在什么时候尝试听串行数据?看代码,只有当调用nOptionsItemSelected时。所以到Arduino发回数据,蓝牙模块完成它们的工作,Android OS处理它并将数据提供给您的应用程序时,您的应用程序可能已经完成了在侦听数据的nOptionsItemSelected中运行您的代码。

测试的一个快速解决方案是将您的读串行数据代码放入while循环中。

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"); 
      } 
} 
+0

谢谢你,在阅读你的while循环解决方案时,它非常有意义。我以高得多的波特率接收了正确的数据(与9600相比115200bps),并且与您所描述的一致;没有足够的时间。再次感谢。 – user2585042