Android USB Host Communication - PullRequest
       36

Android USB Host Communication

16 голосов
/ 22 января 2012

Я работаю над проектом, который использует возможности USB Host в Android 3.2.Я страдаю от прискорбного недостатка знаний и талантов в отношении USB / последовательной связи в целом.Я также не могу найти хороший пример кода для того, что мне нужно сделать.

Мне нужно читать с USB-устройства связи.
Пример: при подключении через Putty (на моем ПК) явведите:

>GO

И устройство начнет извергать данные для меня.Pitch / Roll / Temp / Checksum.

Пример:

$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

Я могу отправить начальную команду 'GO' с устройства Android, когда я получаю эхо 'GO'.

Тогда больше ничего при последующих чтениях.

Как я могу: 1) Отправить команду «go».2) Считать поток данных, которые в результате.

Устройство USB, с которым я работаю, имеет следующие интерфейсы (конечные точки).

Класс устройства: Устройство связи (0x2)

Интерфейсы:

Интерфейс # 0 Класс: коммуникационное устройство (0x2) Конечная точка # 0 Направление: входящее (0x80) Тип: Интервал (0x3) Интервал опроса: 255 Макс. Размер пакета: 32 Атрибуты: 000000011

Интерфейс # 1 Класс: Класс устройства связи (CDC) (0xa) Конечная точка # 0 Адрес: 129 Номер: 1 Направление: Входящий (0x80) Тип: Bulk (0x2) Интервал опроса (0) Макс. Размер пакета: 32 Атрибуты: 000000010

Конечная точка # 1 Адрес: 2 Номер: 2 Направление: Исходящий (0x0) Тип: Bulk (0x2) Интервал опроса (0) Макс. Размер пакета: 32 Атрибуты: 000000010

I 'Я могу работать с разрешениями, подключиться к устройству, найти правильный интерфейс и назначить конечные точки.У меня просто возникают проблемы с выяснением, какую технику использовать для отправки исходной команды для чтения следующих данных.Я пробовал разные комбинации массового переноса и контрольного переноса без удачи.

Спасибо.

Я использую интерфейс # 1, как показано ниже:

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

1 Ответ

12 голосов
/ 23 января 2012

Я не хочу отвечать на свой вопрос, но ... я понял это. Я просто смешивал свои чтения и записи. Кроме того, устройству не нравилось «\ n», которое я использовал в конце моих команд. Похоже, что он намного лучше ладит с \ r.

Я закончил тем, что использовал массовый перенос Android для чтения и записи. Мои записи выглядели так.

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

И мой переопределенный метод записи для моего 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);
  }

Показания были похожи:

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

И

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

Все это было начато в такой ветке, как:

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

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

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

Очевидно, что это просто коммуникация, и теперь мне нужно что-то с ней сделать (поместить ее в службу, которая может отправлять отчеты в активность пользовательского интерфейса верхнего уровня с помощью обработчика). Но эта часть выяснена.

Огромное спасибо ребятам, которые работают над rosjava (http://code.google.com/p/rosjava/)... Они собрали много отличных проектов, и их код был очень полезным.

Добавление класса моего устройства для уточнения вещей.

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

Добавление кода 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 {
    }

}
...