Android端末とマイコン(mbed LPC1768)をシリアル通信した。
使用したライブラリとその導入方法
今回使用したライブラリはusb-serial-for-android v2.2.1です。
早速ですが、これの使い方から躓きました。リファレンス(Readme.md)を読むと次のようにあります。
1. Add library to your project:
Add jitpack.io repository to your root build.gradle:
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
Add library to dependencies
dependencies { implementation 'com.github.mik3y:usb-serial-for-android:Tag' }
ここで一度整理しますと、build.gradleは実は2つあるということです。1つ目はファイル直下、もう1つはapp直下です(次の写真の通りです)。
まずはrootの、つまり上の写真で言えば下の方のbuild.gradleのallprojects/repositoriesにリファレンスの最初の部分を書き込み、次にapp直下の、上の写真で言えば上の方のbuild.gradleのdependanciesにリファレンスの2番目のように書き込めばいいわけです。
ここでもう1つ注意点があります。2番目の操作について、implementation 'com.github.mik3y:usb-serial-for-android:Tag'とリファレンス通りに素直に書き込むと動作しません。'Tag'の部分は'master'や'2.1.0'などと置換しなくてはいけません1。おそらくgitのブランチの選択だと思われます(間違っていたらごめんなさい、指摘等お願い致します)。大抵の場合masterにしておけば間違いはなさそうです。
Intent filterとかDevice filterとか
Intent filterに関しては好みですので、とくに強制ではないと思います。1回1回きちんと接続許可を確認したいならば特に必要はありません。他のサイトでもこの部分は重点的に説明されているので、ここではソースのみ掲載しておきます。resにxml/device_filter.xmlを作成し、activity内の既存のIntent filterと並列して以下を書き込むのでした。
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" />
問題はDevice filterの問題です。ライブラリにあるdevice_filter.xmlを確認すると、現時点では以下のようになっています。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 0x0403 FTDI -->
<usb-device vendor-id="1027" product-id="24577" /> <!-- 0x6001: FT232R -->
<usb-device vendor-id="1027" product-id="24592" /> <!-- 0x6010: FT2232H -->
<usb-device vendor-id="1027" product-id="24593" /> <!-- 0x6011: FT4232H -->
<usb-device vendor-id="1027" product-id="24596" /> <!-- 0x6014: FT232H -->
<usb-device vendor-id="1027" product-id="24597" /> <!-- 0x6015: FT231X -->
<!-- 0x10C4 / 0xEAxx: Silabs CP210x -->
<usb-device vendor-id="4292" product-id="60000" /> <!-- 0xea60: CP2102 -->
<usb-device vendor-id="4292" product-id="60016" /> <!-- 0xea70: CP2105 -->
<usb-device vendor-id="4292" product-id="60017" /> <!-- 0xea71: CP2108 -->
<usb-device vendor-id="4292" product-id="60032" /> <!-- 0xea80: CP2110 -->
<!-- 0x067B / 0x2303: Prolific PL2303 -->
<usb-device vendor-id="1659" product-id="8963" />
<!-- 0x1a86 / 0x7523: Qinheng CH340 -->
<usb-device vendor-id="6790" product-id="29987" />
<!-- CDC driver -->
<usb-device vendor-id="9025" /> <!-- 0x2341 / ......: Arduino -->
<usb-device vendor-id="5824" product-id="1155" /> <!-- 0x16C0 / 0x0483: Teensyduino -->
<usb-device vendor-id="1003" product-id="8260" /> <!-- 0x03EB / 0x2044: Atmel Lufa -->
<usb-device vendor-id="7855" product-id="4" /> <!-- 0x1eaf / 0x0004: Leaflabs Maple -->
<usb-device vendor-id="3368" product-id="516" /> <!-- 0x0d28 / 0x0204: ARM mbed -->
</resources>
おそらくラズパイやArduinoといったメジャーなマイコンを使うなら問題は無さそうですが、mbedというマイナーなマイコンには対応していませんでした。(確認したら対応していました。以下は超マイナーなマイコンを使ったことを想定してください。)このまま使うと見事にエラーとなります。
そこで使用するのがUsbSerialProberクラスです。これを使えばvender-idとproduct-idさえわかっていればどんな機器も接続できます。mbedの使用例は下の通りです。
//ProbeTableで追加するデバイスの登録
//mbedは使用対象外なのでここでベンダーIDとプロダクトIDを登録する必要がある
ProbeTable customTable = new ProbeTable();
customTable.addProduct(0x0d28, 0x0204, CdcAcmSerialDriver.class);
UsbSerialProber prober = new UsbSerialProber(customTable);
通信方法
ここまできたらあともう一歩です。リファレンスには以下のようなコードが例として挙げられています。
// Find all available drivers from attached devices.
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
if (availableDrivers.isEmpty()) {
return;
}
// Open a connection to the first available driver.
UsbSerialDriver driver = availableDrivers.get(0);
UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
if (connection == null) {
// add UsbManager.requestPermission(driver.getDevice(), ..) handling here
return;
}
UsbSerialPort port = driver.getPorts().get(0); // Most devices have just one port (port 0)
port.open(connection);
port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
上のコードで通信の窓口となるポートの準備を終えたことになります。
受信・送信のコードは以下の通りです。
port.write(request, WRITE_WAIT_MILLIS);
len = port.read(response, READ_WAIT_MILLIS);
ちなみにrequest,responseはそれぞれbyte型配列です。port.read()の返り値は受信したデータの長さですので、受信成功の有無をこれで確認することもできます。
通信時の注意点(?)
特にデータの読み込みを行う際ですが、別スレッドで行った方が良いことが多いです。スレッドの作成法はこちらを参照してください。
最後に
やっぱりライブラリは便利ですね。
Author And Source
この問題について(Android端末とマイコン(mbed LPC1768)をシリアル通信した。), 我々は、より多くの情報をここで見つけました https://qiita.com/Suzumushi724/items/7e7309efcecf144e54d4著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .