On-The-Go (OTG) アダプターで接続された Arduino ボードとの間でシリアル データを送受信できる Android アプリケーションを作成しようとしています。usb-serial-for-androidライブラリを使用しています。文字列「T」を受信すると、文字列「T」を送り返すようにArduinoを設定しています。Android は同じように設定されていますが、文字列変数 dataToSend が空でない場合は、その値を "T" と共に送信します。私は基本的にこれら2つがデータをやり取りしたいと思っています。このプロジェクトの 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 マネージャーで 2 つの別個のドライバーを使用しようとしていることに注意してください。それが悪影響を与えるかどうかはわかりません。Arduino にデータを送信でき、Arduino の TX LED が点灯するので、何かが送信されていることがわかります。SerialInputOutputManager リスナーが着信データを検出したときにトリガーされる onNewData メソッドは実行されません。だから私は、マネージャーのリスナーのドライバーが正しく初期化されていないか何かだと思います。
双方向 USB シリアル経由で Android と Arduino の間で通信するより良い方法を誰かが持っている場合は、それが何であるかを教えてください。これを機能させるのに多くの苦労がありました。