// // Copyright 2014-2023 Cristian Maglie. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // /* Package serial is a cross-platform serial library for the go language. The canonical import for this library is go.bug.st/serial so the import line is the following: import "go.bug.st/serial" It is possible to get the list of available serial ports with the GetPortsList function: ports, err := serial.GetPortsList() if err != nil { log.Fatal(err) } if len(ports) == 0 { log.Fatal("No serial ports found!") } for _, port := range ports { fmt.Printf("Found port: %v\n", port) } The serial port can be opened with the Open function: mode := &serial.Mode{ BaudRate: 115200, } port, err := serial.Open("/dev/ttyUSB0", mode) if err != nil { log.Fatal(err) } The Open function needs a "mode" parameter that specifies the configuration options for the serial port. If not specified the default options are 9600_N81, in the example above only the speed is changed so the port is opened using 115200_N81. The following snippets shows how to declare a configuration for 57600_E71: mode := &serial.Mode{ BaudRate: 57600, Parity: serial.EvenParity, DataBits: 7, StopBits: serial.OneStopBit, } The configuration can be changed at any time with the SetMode function: err := port.SetMode(mode) if err != nil { log.Fatal(err) } The port object implements the io.ReadWriteCloser interface, so we can use the usual Read, Write and Close functions to send and receive data from the serial port: n, err := port.Write([]byte("10,20,30\n\r")) if err != nil { log.Fatal(err) } fmt.Printf("Sent %v bytes\n", n) buff := make([]byte, 100) for { n, err := port.Read(buff) if err != nil { log.Fatal(err) break } if n == 0 { fmt.Println("\nEOF") break } fmt.Printf("%v", string(buff[:n])) } If a port is a virtual USB-CDC serial port (for example an USB-to-RS232 cable or a microcontroller development board) is possible to retrieve the USB metadata, like VID/PID or USB Serial Number, with the GetDetailedPortsList function in the enumerator package: import "go.bug.st/serial/enumerator" ports, err := enumerator.GetDetailedPortsList() if err != nil { log.Fatal(err) } if len(ports) == 0 { fmt.Println("No serial ports found!") return } for _, port := range ports { fmt.Printf("Found port: %s\n", port.Name) if port.IsUSB { fmt.Printf(" USB ID %s:%s\n", port.VID, port.PID) fmt.Printf(" USB serial %s\n", port.SerialNumber) } } for details on USB port enumeration see the documentation of the specific package. This library tries to avoid the use of the "C" package (and consequently the need of cgo) to simplify cross compiling. Unfortunately the USB enumeration package for darwin (MacOSX) requires cgo to access the IOKit framework. This means that if you need USB enumeration on darwin you're forced to use cgo. */ package serial