使用 karalabe 包从 Go 中的 USB 设备读取

Reading from a USB Device in Go using karalabe package

我正在使用 karalabe USB 包(因为它不依赖于 Win 10 上的 libusb 安装)并且我可以成功找到 micro:bit,但是没有输出读入缓冲区,即计数始终为 0 :

func show_read(device usb.Device) {
    var buffer []byte
    for {
        count, err := device.Read(buffer)
        if err != nil {
            fmt.Println("Error reading:", err)
        } else if count != 0 {
            fmt.Print(string(buffer))
        }
    }
}

func ShowDevices() {
    hids, err := usb.Enumerate(0x0D28, 0x0204)
    if err != nil {
        panic(err)
    }
    for i, hid := range hids {
        fmt.Printf("HID #%d\n", i)
        fmt.Printf("  OS Path:      %s\n", hid.Path)
        fmt.Printf("  Vendor ID:    %#04x\n", hid.VendorID)
        fmt.Printf("  Product ID:   %#04x\n", hid.ProductID)
        var device, err = hid.Open()
        if err != nil {
            fmt.Println("Error opening", err)
        } else {
            go show_read(device)
        }
    }
}

例如这输出:

HID #0
  OS Path:      \?\hid#vid_0d28&pid_0204&mi_03#8&30686a44&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  Vendor ID:    0x0d28
  Product ID:   0x0204

我在 micro:bit 上有一个现有程序,它确实连接并成功输出到 python 版本(我正在移植到 Go)- 这有效并显示正在发送输出来自 micro:bit.

注意:如果我通过 Mu 编辑器打开 micro:bit REPL,Python 代码无法 open/connect(这在技术上是正确的)但是 Go 程序仍然运行而不会抛出一个错误,这意味着设备实际上并没有被打开。

我不确定其中有多少是必要的,但我通过以下方式解决了这个问题:

  1. 使用 go.bug.st/serial - 另见 https://godoc.org/go.bug.st/serial
  2. 并将 uart.init(115200,8,None,1) 添加到我的 micro:bit python 代码中

现在 uart 已正确初始化,karalabe 也有可能工作...

这是一些有效的串行代码 - 适合我的目的(仅在 windows 上测试过) - 尽管显然有一些整理工作要做 - 当 micro:bit 断开连接时程序退出。

package usb

import (
    "fmt"
    "log"

    "go.bug.st/serial"
    "go.bug.st/serial/enumerator"
)

const VID = "0D28"
const PID = "0204"

func show_read(device serial.Port) {
    buffer := make([]byte, 100)
    for {
        count, err := device.Read(buffer)
        if err != nil {
            fmt.Println("Error reading:", err)
        } else if count != 0 {
            fmt.Print(string(buffer[:count]))
        }
    }
}

func ShowDevices() {
    ports, err := enumerator.GetDetailedPortsList()
    if err != nil {
        log.Fatal(err)
    }
    for _, port := range ports {
        if port.IsUSB && (port.VID == VID) && (port.PID == PID) {
            UBIT_MODE := &serial.Mode{
                BaudRate: 115200,
                DataBits: 8,
                Parity:   serial.NoParity,
                StopBits: serial.OneStopBit,
            }
            fmt.Printf("Found port: %s\n", port.Name)
            fmt.Printf("   USB ID     %s:%s\n", port.VID, port.PID)
            fmt.Printf("   USB serial %s\n", port.SerialNumber)
            device, err := serial.Open(port.Name, UBIT_MODE)
            if err != nil {
                log.Fatal(err)
            }
            go show_read(device)
        }
    }
}