我正在尝试编写一个 Android 应用程序,该应用程序可以向和从通过 On-The-Go (OTG) 适配器连接的 Arduino 板发送和接收串行数据。我正在使用usb-serial-for-android库。我正在设置 Arduino,这样如果它接收到字符串“T”,那么它将发送回字符串“T”。Android 已设置为执行相同的操作,但如果字符串变量 dataToSend 不为空,那么它将连同“T”一起发送该值。我基本上希望这两个来回发送数据。这个项目的 Arduino 方面运行良好,每当它接收到数据时,它都会将所有内容记录到 SD 卡中,如果它检测到“T”,它会发送一个“T”回告诉 Android 它可以再次发送。
这是我的代码,对于长度很抱歉,但我觉得可能有多个地方可能是问题所在:
public class MainActivity extends Activity {
private boolean canSend;
private boolean notInit;
private String dataToSend;
private UsbManager manager;
private SerialInputOutputManager serialIoManager;
private static UsbSerialDriver sendDriver;
private static UsbSerialDriver recDriver;
private TextView outputText;
private ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private SerialInputOutputManager.Listener mListener = new SerialInputOutputManager.Listener() {
@Override
public void onRunError(Exception e) { }
@Override
public void onNewData(final byte[] data) {
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
MainActivity.this.updateReceivedData(data);
} catch (IOException e) { e.printStackTrace(); }
}
});
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dataToSend = "";
notInit = true;
canSend = true;
outputText = (TextView) findViewById(R.id.textView1);
}
@Override
protected void onPause() {
super.onPause();
stopIoManager();
if (recDriver != null) {
try {
recDriver.close();
} catch (IOException e) {
// Ignore.
}
recDriver = null;
}
finish();
}
@Override
protected void onResume() {
super.onResume();
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
recDriver = UsbSerialProber.acquire(manager);
if (recDriver == null) {
} else {
try {
recDriver.open();
recDriver.setBaudRate(9600);
} catch (IOException e) {
try {
recDriver.close();
} catch (IOException e2) {
// Ignore.
}
recDriver = null;
return;
}
recDriver.getClass().getSimpleName());
}
onDeviceStateChange();
}
private void stopIoManager() {
// Get UsbManager from Android.
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
// Find the first available driver.
recDriver = UsbSerialProber.acquire(manager);
if (serialIoManager != null) {
Log.i("Device", "Stopping io manager ..");
serialIoManager.stop();
serialIoManager = null;
} else {
Log.d("Device", "recDriver NULL");
}
}
private void startIoManager() {
// Get UsbManager from Android.
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
// Find the first available driver.
recDriver = UsbSerialProber.acquire(manager);
if (recDriver != null) {
Log.i("Device", "Starting io manager ..");
serialIoManager = new SerialInputOutputManager(recDriver, mListener);
mExecutor.submit(serialIoManager);
} else {
Log.d("Device", "recDriver NULL");
}
}
private void onDeviceStateChange() {
stopIoManager();
startIoManager();
}
protected void updateReceivedData(byte[] data) throws IOException {
//use the data
Log.d("Device", "is updating");
final String dataIn = HexDump.dumpHexString(data);
outputText.setText(dataIn);
canSend = checkForSend(dataIn);
if (canSend) {
sendData();
}
}
private boolean checkForSend (String in) {
String cur;
int len = in.length();
for (int i = 0; i < len; i++) {
cur = in.substring(i, i + 1);
if (cur.equals("T")) {
return true;
}
}
return false;
}
static void show(Context context, UsbSerialDriver driver) {
recDriver = driver;
final Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
context.startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void requestSend(View v) {
dataToSend = "9375644603\n";
if (notInit) {
try {
sendData();
} catch (IOException e) {
e.printStackTrace();
}
}
notInit = false;
}
private void sendData() throws IOException {
// Get UsbManager from Android.
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
// Find the first available driver.
sendDriver = UsbSerialProber.acquire(manager);
if (sendDriver != null) {
sendDriver.open();
try {
sendDriver.setBaudRate(9600);
dataToSend = "2345\n";
if (!dataToSend.equals("")) {
byte [] byteToSend = dataToSend.getBytes();
sendDriver.write(byteToSend, 1000);
}
dataToSend = "";
byte[] terminator = "T\n".getBytes();
sendDriver.write(terminator, 1000);
} catch (IOException e) {
// Deal with error.
} finally {
sendDriver.close();
}
}
// Get UsbManager from Android.
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
// Find the first available driver.
sendDriver = UsbSerialProber.acquire(manager);
}
}
请注意,我正在尝试将两个单独的驱动程序与同一个 I/O 管理器一起使用。我不确定这是否会对它产生负面影响。我能够将数据发送到 Arduino,并且 Arduino 的 TX led 亮起,所以我知道正在发送一些东西。当 SerialInputOutputManager 侦听器检测到传入数据时触发的 onNewData 方法永远不会运行。所以我认为经理监听器的驱动程序没有正确初始化或其他什么。
如果有人有更好的方法通过双向 USB 串行在 Android 和 Arduino 之间进行通信,请告诉我它是什么。我在试图让它发挥作用时遇到了很多麻烦。