2012-01-22 20 views
16

Pracuję nad projektem, który wykorzystuje możliwości hosta USB w systemie Android 3.2. Cierpię na opłakany brak wiedzy i talentu w zakresie komunikacji USB/szeregowej w ogóle. Nie mogę też znaleźć żadnego dobrego kodu przykładowego do tego, co muszę zrobić.Android Host Host Communication

Potrzebuję czytać z urządzenia komunikacyjnego USB.
Ex: Po podłączeniu poprzez Putty (na moim komputerze) wejdę:

>GO 

i urządzenie zacznie wypluwać dane dla mnie. 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 

mogę wysłać początkową polecenie 'Go' z urządzenia z systemem Android, w którym razem otrzymać echo 'Go'.

Nic innego w przypadku późniejszych odczytów.

Jak mogę: 1) Wyślij polecenie "idź". 2) Odczytuj w strumieniu danych, które wynikają.

Urządzenie USB, z którym pracuję, ma następujące interfejsy (punkty końcowe).

Device Class: Urządzenie do komunikacji (0x2)

Interfejsy:

Interfejs # 0 Klasa: Communication Device (0x2) Endpoint # 0 Kierunek: Inbound (0x80) Typ: Intrrupt (0x3) Poll Interval: 255 Max Packet Size: 32 Atrybuty: 000000011

Interfejs nr 1 Klasa: Komunikacja De wice Class (CDC) (0xa) Endpoint # 0 Adres: 129 Numer: 1 Kierunek: Inbound (0x80) Rodzaj: Bulk (0x2) Poll Interval (0) Max Packet Size: 32 Atrybuty: 000000010

Endpoint # 1 Adres: 2 Numer: 2 Kierunek: Wychodzące (0x0) Typ: Bulk (0x2) Poll Interval (0) Max Packet Size: 32 Atrybuty: 000000010

Jestem w stanie poradzić sobie z uprawnieniami, połączyć się z urządzeniem, znaleźć właściwy interfejs i przypisać punkty końcowe. Mam problem z ustaleniem, którą technikę użyć, by wysłać początkowe polecenie, odczytać wynikające z tego dane. Próbowałem różnych kombinacji bulkTransfer i controlTransfer bez powodzenia.

Dzięki.

Używam interfejsu nr 1, jak widać poniżej:

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

dla tych z nas zmaga się tam, w jaki sposób wybraliście Interfejs 1, i do jakich celów będzie Interfejs 0, interfejs przerwania być używane? Dzięki! – Rachael

Odpowiedz

12

Nienawidzę odpowiedzieć na moje własne pytanie, ale ... mam to zorientowali się. Po prostu miksowałem moje teksty i piszę.Dodatkowo urządzenie nie podobało się '\ n', którego używałem na końcu moich poleceń. Wydaje się, że lepiej sobie radzi z "\ r".

Skończyło się na wykorzystaniu bulkTransfer Androida do czytania i pisania. Moje teksty wyglądały tak.

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

A moja zastąpiona metoda zapisu dla mojego 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); 
    } 

odczyty były podobne:

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

I:

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

To wszystko było po prostu skopany w wątku tak:

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

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

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

Oczywiście jest to tylko rzeczy Comm i będę musiał teraz zrobić coś z nim (umieścić go w usługę, która może zgłosić powrót do aktywności na najwyższym poziomie UI za pomocą handler'a). Ale ta część jest zorientowana.

Ogromne podziękowania dla osób, które pracują nad rosjava (http://code.google.com/p/rosjava/) ... Stworzyły wiele świetnych projektów, a ich kod był bardzo pomocny.

Dodanie klasy urządzenia do wyjaśnienia.

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

Dodawanie kodu 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

jak zdobyć device.getwriter()? i co zrobi metoda flush()? – Sathish

+0

Moja klasa urządzenia zawierała BufferedWriter. getWriter zwrócił ten obiekt. Tak więc, flush() po prostu przepłukuje strumień. Aby pomóc, wkleję powyższy kod zajęć. –

+0

co to jest BKReader? Wygląda na klasę, którą napisałeś. Czy możesz też pokazać jakiś kod? –