Android USB host Communication

Pracuję nad projektem, który wykorzystuje możliwości hosta USB w Androidzie 3.2. Cierpię na godny ubolewania brak wiedzy i talentu w zakresie komunikacji USB / szeregowej w ogóle. Nie jestem również w stanie znaleźć żadnego dobrego przykładowego kodu do tego, co muszę zrobić.

Muszę czytać z urządzenia komunikacyjnego USB.
Ex: po podłączeniu przez Putty (na moim PC) wpisuję:
>GO
I urządzenie zaczyna 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ątkowe polecenie " GO "z urządzenia z Androidem, w którym czasie otrzymuję echo "GO".

Potem nic więcej na kolejnych czytaniach.

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

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

Klasa urządzenia: Urządzenie komunikacyjne (0x2)

Interfejsy:

Interfejs #0 Klasa: urządzenie komunikacyjne (0x2) Punkt końcowy #0 Kierunek: Inbound (0x80) Typ: Intrupt (0x3) Ankieta: 255 Max Wielkość Opakowania: 32 Atrybuty: 000000011

Interfejs #1 Class: Communication Device Class (CDC) (0xa) Punkt końcowy #0 Adres: 129 Numer: 1 Kierunek: Inbound (0x80) Typ: Bulk (0x2) Ankieta (0) Max Wielkość Opakowania: 32 Atrybuty: 000000010

Punkt końcowy # 1 Adres: 2 Numer: 2 Kierunek: wychodzący (0x0) Typ: Bulk (0x2) Ankieta (0) Maksymalny Rozmiar Pakietu: 32 Atrybuty: 000000010

Jestem w stanie poradzić sobie z uprawnieniami, połączyć się z urządzeniem, znaleźć odpowiedni interfejs i przypisać punkty końcowe. Po prostu mam problem z ustaleniem jakiej techniki użyć, aby wysłać początkowe polecenie odczytaj dane. Próbowałem różnych kombinacji bulkTransfer i controlTransfer bez powodzenia. Dzięki.

Używam interfejsu # 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);
  }
Author: K.R., 2012-01-22

1 answers

Nienawidzę odpowiadać na własne pytanie, ale... Rozgryzłem to. Po prostu mieszałem się w czytaniu i pisaniu. Dodatkowo urządzenie nie podobało się '\n' używałem na końcu moich poleceń. Wydaje się, aby dogadać się z '\R' znacznie lepiej.

Skończyło się na użyciu bulkTransfer Androida do odczytu i zapisu. Moje zapiski wyglądały tak.

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

I moja nadpisana metoda zapisu dla mojego Bufferedwritera:

@ 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 dopiero się zaczęło w takim wątku:

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

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

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

Oczywiście jest to tylko komunikacja rzeczy i będę musiał teraz coś z nim zrobić (umieścić go w Serwisie, który może zgłosić z powrotem do najwyższego poziomu aktywności UI za pomocą Handlera). Ale ta część jest rozpracowana.

Wielkie podziękowania dla ludzi, którzy pracują nad rosjava ( http://code.google.com/p/rosjava / )... stworzyli wiele świetnych projektów i ich kod był bardzo pomocny.

Dodanie mojej klasy urządzeń, aby pomóc wyjaśnić rzeczy.

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

Dodanie 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 {
    }

}
 12
Author: K.R.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-18 13:24:09