2012-01-22 22 views
16

Tôi đang làm việc trên một dự án sử dụng khả năng của Máy chủ lưu trữ USB trong Android 3.2. Tôi đang bị thiếu hiểu biết và tài năng về giao tiếp USB/Serial nói chung. Tôi cũng không thể tìm thấy bất kỳ mã ví dụ nào tốt cho những gì tôi cần làm.Truyền thông Máy chủ USB Android

Tôi cần đọc từ Thiết bị liên lạc USB.
Ex: Khi tôi kết nối qua Putty (trên máy tính của tôi) Tôi nhập:

>GO 

Và điện thoại bắt đầu phun ra dữ liệu cho tôi. 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 

tôi có thể gửi lệnh 'GO' ban đầu từ thiết bị Android tại thời điểm đó tôi nhận được một tiếng vang của 'GO'.

Sau đó, không có gì khác trên bất kỳ lần đọc tiếp theo nào.

Làm cách nào để có thể: 1) Gửi lệnh 'go'. 2) Đọc trong luồng dữ liệu kết quả.

Thiết bị USB tôi đang làm việc có các giao diện sau (điểm cuối).

Device Class: thiết bị truyền thông (0x2)

Giao diện:

Interface # 0 Class: Communication Device (0x2) Endpoint # 0 Hướng: Inbound (0x80) Loại: Intrrupt (0x3) Poll Interval: 255 Max gói Kích thước: 32 Attributes: 000000011

Interface # 1 class: Truyền De Phó Class (CDC) (0xa) Endpoint # 0 Địa chỉ: 129 Số: 1 Hướng: Inbound (0x80) Loại: Bulk (0x2) Poll Interval (0) Max gói Kích thước: 32 Attributes: 000.000.010

Endpoint # 1 Địa chỉ: 2 Số: 2 Hướng: Outbound (0x0) Loại: Bulk (0x2) Poll Interval (0) Max gói Kích thước: 32 Attributes: 000000010

Tôi có thể xử lý sự cho phép, kết nối với thiết bị, tìm giao diện chính xác và gán các điểm cuối. Tôi chỉ gặp khó khăn trong việc tìm ra kỹ thuật nào để sử dụng để gửi lệnh ban đầu đọc dữ liệu tiếp theo. Tôi đã thử các kết hợp khác nhau của bulkTransfer và controlTransfer mà không có may mắn.

Cảm ơn.

Tôi đang sử dụng giao diện # 1 như bên dưới:

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

cho những người trong chúng ta đấu tranh trên mạng, làm thế nào bạn chọn Interface 1, và cho mục đích gì sẽ giao diện 0, giao diện ngắt, được sử dụng cho? Cảm ơn! – Rachael

Trả lời

12

Tôi ghét phải trả lời câu hỏi của riêng tôi nhưng ... Tôi đã nhận nó tìm ra. Tôi chỉ pha trộn những lần đọc và viết của mình.Ngoài ra, thiết bị không thích '\ n' mà tôi đang sử dụng ở cuối lệnh của mình. Nó xuất hiện để có được cùng với '\ r' tốt hơn nhiều.

Tôi đã sử dụng bulkTransfer của android để đọc và viết. Viết của tôi trông như thế này.

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

Và phương pháp ghi ghi đè tôi cho BufferedWriter tôi:

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

Các lần đọc tương tự:

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

Và:

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

này được tất cả chỉ là khởi đầu trong một thread như vậy:

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

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

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

Rõ ràng đây chỉ là những thứ comm và tôi sẽ cần đến bây giờ làm điều gì đó với nó (đặt nó trong một dịch vụ có thể báo cáo lại cho một hoạt động UI cấp cao nhất sử dụng trình xử lý). Nhưng phần này của nó được tìm ra.

Cảm ơn bạn rất nhiều đến những người đang làm việc trên rosjava (http://code.google.com/p/rosjava/) ... Họ đã tập hợp rất nhiều dự án tuyệt vời và mã của họ rất hữu ích.

Thêm lớp thiết bị của tôi để giúp làm rõ mọi thứ.

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

Thêm mã 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

làm thế nào u có được device.getwriter()? và phương thức flush() sẽ làm gì? – Sathish

+0

Lớp thiết bị của tôi chứa BufferedWriter. getWriter trả về đối tượng đó. Vì vậy, flush() đơn giản là xóa luồng. Để giúp đỡ, tôi sẽ dán mã lớp của mình ở trên. –

+0

BKReader là gì? Có vẻ như một lớp bạn viết. Bạn có thể hiển thị một số mã cho điều đó không? –