我正在尝试编写一个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指示灯会亮相,所以我知道正在发送一些内容。从未运行SerialInputOutputManager侦听器检测到传入数据时触发的onNewData方法。所以我认为经理的听众的驱动程序没有正确初始化或其他东西。
如果有人通过双向usb串口在Android和Arduino之间进行更好的通话方式,请告诉我它是什么。我试图让它发挥作用我遇到了很多麻烦。
答案 0 :(得分:1)
我发现下载应用程序Arduino Uno Communicator for Android,并使用开发人员的Arduino Uno Communicator-Client代码是最好的选择。我可以使用intent过滤器轻松地广播意图并接收数据,并且通信显然是在一个单独的线程上完成的,所以我不必担心崩溃。如果要在代码中本地实现此方法,可以查看应用程序here的源代码。