android io usb serial-communication

Comunicación de host USB Android



io serial-communication (1)

Odio responder a mi propia pregunta, pero ... ya lo entendí. Estaba mezclando mis lecturas y escrituras. Además, al dispositivo no le gustó el ''/ n'' que estaba usando al final de mis comandos. Parece que se lleva bien con ''/ r'' mucho mejor.

Terminé usando bulkTransfer de Android para lecturas y escrituras. Mis escritos se veían así.

try { device.getWriter().write(command + "/r"); device.getWriter().flush(); } catch (IOException e) { throw new RuntimeException(e); }

Y mi método de escritura anulado para mi BufferedWriter:

@Anular

public void write(char[] buf, int offset, int count) throws IOException { byte[] buffer = new String(buf, offset, count).getBytes(Charset.forName("US-ASCII")); int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); }

Las lecturas fueron similares:

char[] buffer = new char[BUF_SIZE]; try { BufferedReader reader = device.getReader(); int readBytes = reader.read(buffer); Log.d(TAG, "BYTES READ: " + readBytes); } catch (IOException e) { throw new RuntimeException(e); } String strBuf = new String(buffer).trim(); if (DEBUG) { Log.d(TAG, "Read: " + strBuf); }

Y:

@Override public int read(char[] buf, int offset, int count) throws IOException { byte[] buffer = new byte[count]; int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); if (byteCount < 0) { throw new IOException(); } char[] charBuffer = new String(buffer, Charset.forName("US-ASCII")).toCharArray(); System.arraycopy(charBuffer, 0, buf, offset, byteCount); return byteCount; }

Todo esto se inició en un hilo como el siguiente:

new Thread() { @Override public void run() { String command = "go"; write(command); while (true) { String coords = read(); } } }.start();

Obviamente, esto es solo un asunto de comunicación y ahora tendré que hacer algo con él (ponlo en un Servicio que pueda informar a una actividad de IU de nivel superior usando un controlador). Pero esta parte de ella está resuelta.

Muchísimas gracias a las personas que están trabajando en rosjava ( http://code.google.com/p/rosjava/ ) ... Han organizado muchos grandes proyectos y su código fue muy útil.

Agregando mi clase de dispositivo para ayudar a aclarar las cosas.

import com.google.common.base.Preconditions; import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbInterface; import android.util.Log; import java.io.BufferedReader; import java.io.BufferedWriter; /* This class represents a USB device that supports the adb protocol. */ public class BKDevice { // private static final int TIMEOUT = 3000; private final UsbDeviceConnection usbDeviceConnection; private final BufferedReader reader; private final BufferedWriter writer; public static final String TAG = "AcmDevice"; public BKDevice(UsbDeviceConnection usbDeviceConnection, UsbInterface usbInterface) { Preconditions.checkState(usbDeviceConnection.claimInterface( usbInterface, true)); this.usbDeviceConnection = usbDeviceConnection; UsbEndpoint epOut = null; UsbEndpoint epIn = null; // look for our bulk endpoints for (int i = 0; i < usbInterface.getEndpointCount(); i++) { UsbEndpoint ep = usbInterface.getEndpoint(i); Log.d(TAG, "EP " + i + ": " + ep.getType()); if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { epOut = ep; } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) { epIn = ep; } } } if (epOut == null || epIn == null) { throw new IllegalArgumentException("Not all endpoints found."); } BKReader acmReader = new BKReader(usbDeviceConnection, epIn); BKWriter acmWriter = new BKWriter(usbDeviceConnection, epOut); reader = new BufferedReader(acmReader); writer = new BufferedWriter(acmWriter); } public BufferedReader getReader() { return reader; } public BufferedWriter getWriter() { return writer; } }

Añadiendo código BKReader:

import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.util.Log; import java.io.IOException; import java.io.Reader; import java.nio.charset.Charset; public class BKReader extends Reader { private static final int TIMEOUT = 1000; private final UsbDeviceConnection connection; private final UsbEndpoint endpoint; public BKReader(UsbDeviceConnection connection, UsbEndpoint endpoint) { this.connection = connection; this.endpoint = endpoint; } @Override public int read(char[] buf, int offset, int count) throws IOException { byte[] buffer = new byte[count]; int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); if (byteCount < 0) { throw new IOException(); } char[] charBuffer = new String(buffer, Charset.forName("US-ASCII")).toCharArray(); System.arraycopy(charBuffer, 0, buf, offset, byteCount); return byteCount; } @Override public void close() throws IOException { } }

Estoy trabajando en un proyecto que utiliza las capacidades del host USB en Android 3.2. Estoy sufriendo de una deplorable falta de conocimiento y talento con respecto a la comunicación USB / serie en general. Tampoco puedo encontrar ningún buen código de ejemplo para lo que necesito hacer.

Necesito leer desde un dispositivo de comunicación USB.
Ej: Cuando me conecto a través de Putty (en mi PC), ingreso:

>GO

Y el dispositivo empieza a arrojarme datos por mí. Pitch / Roll / Temp / Checksum.

Ex:

$R1.217P-0.986T26.3*60 $R1.217P-0.986T26.3*60 $R1.217P-0.987T26.3*61 $R1.217P-0.986T26.3*60 $R1.217P-0.985T26.3*63

Puedo enviar el comando inicial ''GO'' desde el dispositivo Android, momento en el que recibo un eco de ''GO''.

Entonces nada más en las lecturas posteriores.

¿Cómo puedo: 1) Enviar el comando ''ir''. 2) Leer en el flujo de datos que resulta.

El dispositivo USB con el que estoy trabajando tiene las siguientes interfaces (puntos finales).

Clase de dispositivo: Dispositivo de comunicación (0x2)

Interfaces:

Interfaz # 0 Clase: Dispositivo de comunicación (0x2) Punto final # 0 Dirección: Entrante (0x80) Tipo: Interrupción (0x3) Intervalo de sondeo: 255 Tamaño máximo del paquete: 32 Atributos: 000000011

Clase de interfaz # 1: Clase de dispositivo de comunicación (CDC) (0xa) Punto final # 0 Dirección: 129 Número: 1 Dirección: Entrante (0x80) Tipo: Granel (0x2) Intervalo de sondeo (0) Tamaño máximo del paquete: 32 Atributos: 000000010

Dirección del punto final n. ° 1: 2 Número: 2 Dirección: Saliente (0x0) Tipo: Granel (0x2) Intervalo de sondeo (0) Tamaño máximo del paquete: 32 Atributos: 000000010

Soy capaz de lidiar con el permiso, conectarme al dispositivo, encontrar la interfaz correcta y asignar los puntos finales. Solo estoy teniendo problemas para determinar qué técnica usar para enviar el comando inicial, leer los datos posteriores. He probado diferentes combinaciones de bulkTransfer y controlTransfer sin suerte.

Gracias.

Estoy usando la interfaz # 1 como se ve a continuación:

public AcmDevice(UsbDeviceConnection usbDeviceConnection, UsbInterface usbInterface) { Preconditions.checkState(usbDeviceConnection.claimInterface(usbInterface, true)); this.usbDeviceConnection = usbDeviceConnection; UsbEndpoint epOut = null; UsbEndpoint epIn = null; // look for our bulk endpoints for (int i = 0; i < usbInterface.getEndpointCount(); i++) { UsbEndpoint ep = usbInterface.getEndpoint(i); Log.d(TAG, "EP " + i + ": " + ep.getType()); if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { epOut = ep; } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) { epIn = ep; } } } if (epOut == null || epIn == null) { throw new IllegalArgumentException("Not all endpoints found."); } AcmReader acmReader = new AcmReader(usbDeviceConnection, epIn); AcmWriter acmWriter = new AcmWriter(usbDeviceConnection, epOut); reader = new BufferedReader(acmReader); writer = new BufferedWriter(acmWriter); }