diff --git a/README.md b/README.md index 8e6930f..d216d50 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,14 @@ Cordovarduino is a Cordova/Phonegap plugin that enable you to use serial communication from an Android device to a serial over USB capable one. -It's a **work in progress** : Android to Arduino works, Arduino to Android is not yet supported +It's a **work in progress** : Android to Arduino works, Arduino to Android now works. + + +## Change log + +2014.03: Ed. Lafargue + Implemented read(). The success callback returns a Javascript ArrayBuffer which is the best way to handle binary data + in Javascript. It is straightforward to convert this to a string if required - a utility function could be implemented in this plugin. ### Context This work was made during an art residency hosted at the [Stereolux, Laboratoire Arts et Technologies](http://www.stereolux.org/laboratoire-arts-et-technologies) with [Coup de foudre](https://www.facebook.com/coup.defoudre.716) and [Xavier Seignard](http://drangies.fr). @@ -37,9 +44,10 @@ serial.open(opts, function success(), function error()); You're now able to read and write: ```js serial.write(data, function success(), function error()); -serial.read(function success(), function error()); +serial.read(function success(buffer), function error()); ``` `data` is the string representation to be written to the serial port. +`buffer` is a JavaScript ArrayBuffer containing the data that was just read. And finally close the port: ```js diff --git a/lib/usbseriallibrary.jar b/lib/usbseriallibrary.jar index a39c669..3f9e2df 100644 Binary files a/lib/usbseriallibrary.jar and b/lib/usbseriallibrary.jar differ diff --git a/src/android/org/stereolux/cordova/serial/Serial.java b/src/android/org/stereolux/cordova/serial/Serial.java index 0f2c361..6898136 100644 --- a/src/android/org/stereolux/cordova/serial/Serial.java +++ b/src/android/org/stereolux/cordova/serial/Serial.java @@ -1,9 +1,11 @@ package org.stereolux.cordova.serial; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.List; import org.apache.cordova.CallbackContext; +import org.apache.cordova.PluginResult; import org.apache.cordova.CordovaPlugin; import org.json.JSONArray; import org.json.JSONException; @@ -21,6 +23,7 @@ import com.hoho.android.usbserial.driver.UsbSerialDriver; import com.hoho.android.usbserial.driver.UsbSerialPort; import com.hoho.android.usbserial.driver.UsbSerialProber; +import com.hoho.android.usbserial.util.SerialInputOutputManager.Listener; /** * Cordova plugin to communicate with the android serial port @@ -42,6 +45,12 @@ public class Serial extends CordovaPlugin { // The serial port that will be used in this plugin private UsbSerialPort port; + private static final int READ_WAIT_MILLIS = 200; + private static final int BUFSIZ = 4096; + + private final ByteBuffer mReadBuffer = ByteBuffer.allocate(BUFSIZ); + private final ByteBuffer mWriteBuffer = ByteBuffer.allocate(BUFSIZ); + /** * Overridden execute method * @param action the string representation of the action to execute @@ -170,8 +179,11 @@ public void run() { private void writeSerial(final String data, final CallbackContext callbackContext) { cordova.getThreadPool().execute(new Runnable() { public void run() { - Log.d(TAG, data); + if (port == null) { + callbackContext.error("writing a closed port"); + } else try { + Log.d(TAG, data); byte[] buffer = data.getBytes(); port.write(buffer, 1000); callbackContext.success(); @@ -191,10 +203,24 @@ public void run() { private void readSerial(final CallbackContext callbackContext) { cordova.getThreadPool().execute(new Runnable() { public void run() { + if (port == null) { + callbackContext.error("reading a closed port"); + } else try { - byte buffer[] = new byte[16]; - int numBytesRead = port.read(buffer, 1000); - callbackContext.success(numBytesRead); + int len = port.read(mReadBuffer.array(), READ_WAIT_MILLIS); + // Whatever happens, we send an "OK" result, up to the + // receiver to check that len > 0 + PluginResult.Status status = PluginResult.Status.OK; + if (len > 0) { + Log.d(TAG, "Read data len=" + len); + final byte[] data = new byte[len]; + mReadBuffer.get(data, 0, len); + mReadBuffer.clear(); + callbackContext.sendPluginResult(new PluginResult(status,data)); + } else { + final byte[] data = new byte[0]; + callbackContext.sendPluginResult(new PluginResult(status, data)); + } } catch (IOException e) { // deal with error @@ -213,7 +239,10 @@ private void closeSerial(final CallbackContext callbackContext) { cordova.getThreadPool().execute(new Runnable() { public void run() { try { - port.close(); + // Make sure we don't die if we try to close an non-existing port! + if (port != null) + port.close(); + port = null; callbackContext.success(); } catch (IOException e) { // deal with error