使用karalabe包在Go中读取USB设备

huangapple go评论78阅读模式
英文:

Reading from a USB Device in Go using karalabe package

问题

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

func show_read(device usb.Device) {
	var buffer []byte
	for {
		count, err := device.Read(buffer)
		if err != nil {
			fmt.Println("读取错误:", 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路径:%s\n", hid.Path)
		fmt.Printf("  厂商ID:%#04x\n", hid.VendorID)
		fmt.Printf("  产品ID:%#04x\n", hid.ProductID)
		var device, err = hid.Open()
		if err != nil {
			fmt.Println("打开错误", err)
		} else {
			go show_read(device)
		}
	}
}

例如,这将输出:

HID #0
  OS路径:\\?\hid#vid_0d28&pid_0204&mi_03#8&30686a44&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
  厂商ID0x0d28
  产品ID0x0204

我在micro:bit上有一个现有的程序,它可以成功连接并输出到Python版本(我正在将其移植到Go),这个程序可以工作,并显示micro:bit正在发送输出。

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

英文:

I am using karalabe USB package (since it does not depend on libusb installation on Win 10) and I can successfully find a micro:bit, but no output is read into the buffer, i.e. count is always 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)
		}
	}
}

e.g. this outputs:

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

I have an existing program on the micro:bit that does connect and output successfully to a python version (which I am porting to Go) - and this works and shows that output is being sent from the micro:bit.

Note: If I open the micro:bit REPL through the Mu Editor, the Python code fails to open/connect (which is technically correct) but the Go program still runs without throwing an error, which implies that the device isn't actually being opened.

答案1

得分: 0

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

  1. 使用了go.bug.st/serial库 - 参见https://godoc.org/go.bug.st/serial
  2. 在我的micro:bit Python代码中添加了uart.init(115200,8,None,1)

现在,由于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)
		}
	}
}

希望对你有帮助!

英文:

I'm not sure how much of this was necessary, but I solved this by:

  1. Using go.bug.st/serial - see also https://godoc.org/go.bug.st/serial
  2. and adding uart.init(115200,8,None,1) to my micro:bit python code

It's possible that karalabe would also work now that the uart is initialized correctly...

Here is some working serial code - which fine for my purposes (only tested on windows) - though there is obviously some tidying to do - the program exits when the micro:bit is disconnected.

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

huangapple
  • 本文由 发表于 2022年3月2日 18:56:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/71321478.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定