Arduino経由でAndroidとつなげてみることにしました。
使うもの
・Android端末(Nexus6)・Arduino UNO
・アルコールセンサー(MQ-3)
まず参考にしたのは、
Androidで簡単にArduinoと接続できるライブラリ
Physicaloid Library
https://github.com/ksksue/PhysicaloidLibrary
それを使ってアルコールセンサーを動かしているPocketDuinoです。
PocketDuino
http://www.physicaloid.com/wiki/doku.php?id=hardware:pocketduino
PocketDuinoがあれば良かったのだけど、既に販売終了しているようなので、
諦めてArduinoでやってみることにしました。
作業開始メモ
1.PysycaloidをEcripseに取り込んでサンプルソフトを実行する。しかしながら、シリアルのOpenが出来ない。Arduinoを認識していない模様。
デバッグしようにも、Android端末のUsbがArduinoでふさがってる。
なので、Wifiデバッグを試してみる。
Wifiデバッグのやりかた
・PCのとAndroidをUSBで接続し、下記コマンドをうつ
$ adb tcpip 5555
$ adb connect 192.168.1.1:5555 ※IPアドレスはAndroidのやつを指定
・USBを抜いても、普通にログだしたりできます。
$ adb shell logcat
もとに戻すにははadb usbでOK
無事デバッグ可能になりました。超簡単。
↑嘘でした。ちゃんとダイアログでPermissionを許可してやれば大丈夫。xmlのパーミッション許可とか不要。
で、再度Debugで動かして、mSerialのmDeviceをみると、Arduinoがちゃんと接続されていることがわかる。
ただし何故かSerialが開けない。
Physicaloid.javaにて、mSerial openでfalseになる。これが原因ぽい。
ソースを潜ると
UsbCdcConnection.javaのopen()にて、falseを返しているのがおかしい。
どうも、既にOpenになっている場合は、else側に行くのだが、そっちだとFalseを返してしまうようだ。
なので、すでにOpenの場合もTrueを返すようにする。
UsbCdcConnection.javaを下記に修正
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public boolean open(UsbVidPid ids, boolean isCdcAcm, int ch) { | |
if(ids == null) return false; | |
int devNum = 0; | |
int chNum = 0; | |
for(UsbDevice usbdev : mUsbAccess.manager().getDeviceList().values()) { | |
if(usbdev.getVendorId() == ids.getVid()) { | |
if(ids.getPid() == 0 || ids.getPid() == usbdev.getProductId()) { | |
for(int intfNum=0; intfNum < usbdev.getInterfaceCount(); intfNum++) { | |
if( (isCdcAcm && (usbdev.getInterface(intfNum).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA)) | |
|| !isCdcAcm) { | |
if(ch == chNum) { | |
if(!mUsbAccess.deviceIsConnected(devNum)) { | |
if(mUsbAccess.openDevice(devNum,intfNum,ch)) { | |
if(DEBUG_SHOW){ Log.d(TAG, "Find VID:"+Integer.toHexString(usbdev.getVendorId())+", PID:"+Integer.toHexString(usbdev.getProductId())+", DevNum:"+devNum+", IntfNum:"+intfNum); } | |
mUsbConnectionEp.put(ch,new UsbCdcConnectionEp(mUsbAccess.connection(ch), getEndpoint(devNum, intfNum, UsbConstants.USB_DIR_IN), getEndpoint(devNum, intfNum, UsbConstants.USB_DIR_OUT))); | |
mCdcAcmInterfaceNum = intfNum; | |
return true; | |
} | |
}else{ | |
return true; //********here********* | |
} | |
chNum++; |
すると今度はInitのcontrolTransfer()で失敗する。
http://android.ohwada.jp/archives/tag/mbed
ここを参考にさせてもらうと、
ここを参考にさせてもらうと、
Arduino Uno では、CDC ACM は、Interface 0 固定らしい。
元のソースでは変数mInterfaceNumになってて、これが1だったのが間違い。
これも0にしてやる。
2箇所でcontrolTransfer()が使われてるので、どちらも0にする。
UartCdcAcm.java
元のソースでは変数mInterfaceNumになってて、これが1だったのが間違い。
これも0にしてやる。
2箇所でcontrolTransfer()が使われてるので、どちらも0にする。
UartCdcAcm.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Initializes CDC communication | |
* @return true : successful, false : fail | |
*/ | |
private boolean init() { | |
if(mConnection == null) return false; | |
//int ret = mConnection.controlTransfer(0x21, 0x22, 0x00, mInterfaceNum, null, 0, 0); // init CDC | |
int ret = mConnection.controlTransfer(0x21, 0x22, 0x00, 0, null, 0, 0); // init CDC for Arduino Uno | |
Log.d(TAG, "init:" + ret); | |
if(ret < 0) { | |
if(DEBUG_SHOW) { Log.d(TAG, "Fail to Init controlTransfer()"); } | |
return false; | |
} | |
return true; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sets baudrate | |
* @param baudrate baudrate e.g. 9600 | |
* @return true : successful, false : fail | |
*/ | |
public boolean setBaudrate(int baudrate) { | |
byte[] baudByte = new byte[4]; | |
baudByte[0] = (byte) (baudrate & 0x000000FF); | |
baudByte[1] = (byte) ((baudrate & 0x0000FF00) >> 8); | |
baudByte[2] = (byte) ((baudrate & 0x00FF0000) >> 16); | |
baudByte[3] = (byte) ((baudrate & 0xFF000000) >> 24); | |
//int ret = mConnection.controlTransfer(0x21, 0x20, 0, mInterfaceNum, new byte[] { | |
int ret = mConnection.controlTransfer(0x21, 0x20, 0, 0, new byte[] { | |
baudByte[0], baudByte[1], baudByte[2], baudByte[3], 0x00, 0x00, | |
0x08}, 7, 100); | |
if(ret < 0) { | |
if(DEBUG_SHOW) { Log.d(TAG, "Fail to setBaudrate"); } | |
return false; | |
} | |
mUartConfig.baudrate = baudrate; | |
return true; | |
} |
これでようやくSerialがOpenできるようになる。
こうして無事アルコールセンサーの値がとれました。
組み合わせだけでいけると思ってましたが、意外に時間がかかりました。
こうして無事アルコールセンサーの値がとれました。
組み合わせだけでいけると思ってましたが、意外に時間がかかりました。
まとめ:
1.AndroidアプリはPocketDuino用に作られたのを流用させてもらう
https://github.com/ohwada/PocketDuino2.AndroidからArduinoを認識させるためにPhysicaloid Libraryをつかう
https://github.com/ksksue/PhysicaloidLibrary/tree/master/SampleProjectsただしこのままでは動かない。Arduino Uno用に上述した変更が必要。
3.ArduinoのスケッチもPocketDuino用に作られたのを流用。
https://github.com/ohwada/PocketDuinoSparkfunのサンプルでも良い
http://wiring.org.co/learning/basics/airqualitymq135.html
4.アルコールセンサーはこちら
https://www.sparkfun.com/products/8880回路図は下記を参考
http://wiring.org.co/learning/basics/airqualitymq135.html
http://bildr.org/2013/10/mq3-arduino/
無事、簡易アルコールチェッカーができました。
Androidの電源だけで、Arduinoとアルコールセンサが動いています。
Dear author:
返信削除Thanks a lot. I have the same issues to you when I use the library. Your solution is very helpful to me.
Thank you for your comment. I'm glad you're with useful.
削除