2012-01-22 1 views
16

Je travaille sur un projet qui utilise les capacités de l'hôte USB dans Android 3.2. Je souffre d'un manque déplorable de connaissance et de talent concernant la communication USB/série en général. Je suis également incapable de trouver un bon exemple de code pour ce que je dois faire.Communication USB hôte USB

Je dois lire à partir d'un périphérique de communication USB.
Ex: Lorsque je me connecte via Putty (sur mon PC) J'entrez:

>GO 

Et l'appareil commence crachant des données pour moi. 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 

je peux envoyer la première « GO » commande de l'appareil Android à laquelle je reçois un écho de « GO ».

Puis rien d'autre sur les lectures ultérieures.

Comment puis-je: 1) Envoyer la commande 'go'. 2) Lire dans le flux de données qui en résulte.

Le périphérique USB sur lequel je travaille comporte les interfaces suivantes (points de terminaison).

classe périphérique: Dispositif de communication (0x2)

Interfaces:

Interface # 0 Classe: dispositif de communication (0x2) Endpoint # 0 Direction: entrante (0x80) Type: Intrrupt (0x3) Intervalle d'interrogation: 255 Max Packet Taille: 32 Attributs: 000000011

Interface # 1 classe: Communication De vice-classe (CDC) (0xa) Endpoint # 0 Adresse: 129 Numéro: 1 Direction: trafic entrant (0x80) Type: En vrac (0x2) Intervalle d'interrogation (0) Taille maximale paquet: 32 Attributs: 000000010

Endpoint # 1 Adresse: 2 : 2 Direction: sortante (0x0) type: en vrac (0x2) Intervalle d'interrogation (0) Max Taille paquet: 32 Attributs: 000000010

Je suis capable de traiter les autorisations, de me connecter à l'appareil, de trouver la bonne interface et d'attribuer les points de terminaison. J'ai juste du mal à trouver la technique à utiliser pour envoyer la commande initiale lire les données qui suivent. J'ai essayé différentes combinaisons de bulkTransfer et controlTransfer sans chance.

Merci.

J'utilise l'interface # 1 comme on le voit ci-dessous:

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); 
    } 
+0

pour ceux d'entre nous qui luttent là-bas, comment avez-vous choisi Interface 1, et dans quel but serait Interface 0, l'interface d'interruption, être utilisé? Merci! – Rachael

Répondre

12

Je déteste répondre à ma propre question, mais ... Je l'ai compris. Je ne faisais que mélanger mes lectures et écritures.De plus, l'appareil n'a pas aimé le \ n que j'utilisais à la fin de mes commandes. Il semble bien s'entendre avec '\ r'. J'ai fini par utiliser le bulkTransfer d'android pour les lectures et les écritures. Mes écrits ressemblaient à ceci.

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

Et ma méthode d'écriture surchargée pour mon BufferedWriter:

@Override

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); 
    } 

Le lit étaient similaires:

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); 
    } 

Et:

@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; 
    } 

Ce fut tout simplement lancé dans un fil comme ceci:

new Thread() { 
    @Override 
public void run() { 

    String command = "go"; 
    write(command); 

    while (true) { 
     String coords = read(); 
     } 
} 
}.start(); 

Évidemment, cela est juste le truc de comm et je devrai faire maintenant quelque chose avec elle (le mettre dans un service qui peut rendre compte à une activité d'interface utilisateur de niveau supérieur à l'aide d'un gestionnaire). Mais cette partie est comprise.

Un grand merci aux gens qui travaillent sur rosjava (http://code.google.com/p/rosjava/) ... Ils ont mis en place beaucoup de grands projets et leur code a été très utile. Ajout de la classe de périphérique pour clarifier les choses.

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; 
} 
} 

Ajout code 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 { 
    } 

} 
+0

comment avez-vous obtenu device.getwriter()? et qu'a fait la méthode flush()? – Sathish

+0

Ma classe d'unité contenait un BufferedWriter. getWriter a retourné cet objet. Ainsi, flush() vide simplement le flux. Pour aider, je vais coller mon code de classe ci-dessus. –

+0

qu'est ce que BKReader? On dirait une classe que tu as écrite. Pouvez-vous montrer du code pour ça aussi? –

Questions connexes