Documentation
¶
Overview ¶
Package go-serial is a cross-platform serial library for the go language.
import github.com/albenik/go-serial/v2
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:
port, err := serial.Open("/dev/ttyUSB0", serial.WithBaudrate(115200)) if err != nil { log.Fatal(err) }
The Open function can accept options 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:
serial.Open("/dev/ttyUSB0", serial.WithBaudrate(57600), serial.WithParity(serial.EvenParity), serial.WithDataBits(7), serial.WithStopBits(serial.OneStopBit), )
The configuration can be changed at any time with the Reconfigure() function:
if err := port.Reconfigure( serial.WithBaudrate(57600), serial.WithParity(serial.EvenParity), ); 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 "github.com/boseji/go-serial/v2/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.
Example (SendAndReceive) ¶
This example prints the list of serial ports and use the first one to send a string "10,20,30" and prints the response on the screen.
// Retrieve the port list ports, err := serial.GetPortsList() if err != nil { log.Fatal(err) } if len(ports) == 0 { log.Fatal("No serial ports found!") } // Print the list of detected ports for _, port := range ports { fmt.Printf("Found port: %v\n", port) } // Open the first serial port detected at 9600bps N81 port, err := serial.Open(ports[0], serial.WithBaudrate(9600), serial.WithDataBits(8), serial.WithParity(serial.NoParity), serial.WithStopBits(serial.OneStopBit), serial.WithReadTimeout(1000), serial.WithWriteTimeout(1000), serial.WithHUPCL(false), ) if err != nil { log.Fatal(err) } // Send the string "ABCDEF" to the serial port n, err := fmt.Fprint(port, "ABCDEF") if err != nil { log.Fatal(err) } fmt.Printf("Sent %v bytes\n", n) // Read and print the response buff := make([]byte, 100) for { // Reads up to 100 bytes n, err := port.Read(buff) if err != nil { log.Fatal(err) } if n == 0 { fmt.Println("\nEOF") break } fmt.Printf("%v", string(buff[:n])) }
Output:
Index ¶
- Constants
- func GetPortsList() ([]string, error)
- type ModemStatusBits
- type Option
- type Parity
- type Port
- func (p *Port) Close() error
- func (p *Port) GetModemStatusBits() (*ModemStatusBits, error)
- func (p *Port) Read(b []byte) (int, error)
- func (p *Port) ReadyToRead() (uint32, error)
- func (p *Port) Reconfigure(opts ...Option) error
- func (p *Port) ResetInputBuffer() error
- func (p *Port) ResetOutputBuffer() error
- func (p *Port) SetDTR(dtr bool) error
- func (p *Port) SetFirstByteReadTimeout(t uint32) error
- func (p *Port) SetRTS(rts bool) error
- func (p *Port) SetReadTimeout(t int) error
- func (p *Port) SetReadTimeoutEx(t, _ uint32) error
- func (p *Port) SetWriteTimeout(t int) error
- func (p *Port) String() string
- func (p *Port) Write(b []byte) (int, error)
- type PortError
- type PortErrorCode
- type RS485Config
- type StopBits
Examples ¶
Constants ¶
const ( // NoParity disable parity control (default) NoParity Parity = iota // OddParity enable odd-parity check OddParity // EvenParity enable even-parity check EvenParity // MarkParity enable mark-parity (always 1) check MarkParity // SpaceParity enable space-parity (always 0) check SpaceParity // OneStopBit sets 1 stop bit (default) OneStopBit StopBits = iota // OnePointFiveStopBits sets 1.5 stop bits OnePointFiveStopBits // TwoStopBits sets 2 stop bits TwoStopBits )
const FIONREAD = 0x541B
Variables ¶
This section is empty.
Functions ¶
func GetPortsList ¶
Example ¶
ports, err := serial.GetPortsList() if err != nil { log.Fatal(err) } if len(ports) == 0 { fmt.Println("No serial ports found!") } else { for _, port := range ports { fmt.Printf("Found port: %v\n", port) } }
Output:
Types ¶
type ModemStatusBits ¶
type ModemStatusBits struct { CTS bool // ClearToSend status DSR bool // DataSetReady status RI bool // RingIndicator status DCD bool // DataCarrierDetect status }
ModemStatusBits contains all the modem status bits for a serial port (CTS, DSR, etc...). It can be retrieved with the Port.GetModemStatusBits() method.
type Option ¶
type Option func(p *Port)
func WithBaudrate ¶
func WithDataBits ¶
func WithParity ¶
func WithRS485 ¶
func WithRS485(o RS485Config) Option
func WithReadTimeout ¶
func WithStopBits ¶
func WithWriteTimeout ¶
type Port ¶
type Port struct { RS485 RS485Config // contains filtered or unexported fields }
Port is the interface for a serial Port
func (*Port) GetModemStatusBits ¶
func (p *Port) GetModemStatusBits() (*ModemStatusBits, error)
Example ¶
// Open the first serial port detected at 9600bps N81 port, err := serial.Open("/dev/ttyACM1", serial.WithBaudrate(9600), serial.WithDataBits(8), serial.WithParity(serial.NoParity), serial.WithStopBits(serial.OneStopBit), serial.WithReadTimeout(1000), serial.WithWriteTimeout(1000), ) if err != nil { log.Fatal(err) } defer port.Close() count := 0 for count < 25 { status, err := port.GetModemStatusBits() if err != nil { log.Fatal(err) } fmt.Printf("Status: %+v\n", status) time.Sleep(time.Second) count++ if count == 5 { err := port.SetDTR(false) if err != nil { log.Fatal(err) } fmt.Println("Set DTR OFF") } if count == 10 { err := port.SetDTR(true) if err != nil { log.Fatal(err) } fmt.Println("Set DTR ON") } if count == 15 { err := port.SetRTS(false) if err != nil { log.Fatal(err) } fmt.Println("Set RTS OFF") } if count == 20 { err := port.SetRTS(true) if err != nil { log.Fatal(err) } fmt.Println("Set RTS ON") } }
Output:
func (*Port) ReadyToRead ¶
func (*Port) Reconfigure ¶
Example ¶
port, err := serial.Open("/dev/ttyACM0") if err != nil { log.Fatal(err) } if err := port.Reconfigure( serial.WithBaudrate(9600), serial.WithDataBits(8), serial.WithParity(serial.NoParity), serial.WithStopBits(serial.OneStopBit), serial.WithReadTimeout(1000), serial.WithWriteTimeout(1000), ); err != nil { log.Fatal(err) } fmt.Println("Port set to 9600 N81")
Output:
func (*Port) ResetInputBuffer ¶
func (*Port) ResetOutputBuffer ¶
func (*Port) SetFirstByteReadTimeout ¶
func (*Port) SetReadTimeout ¶
func (*Port) SetReadTimeoutEx ¶
TODO Second argument was forget here while interface type that forces to implement it was removed.
To support backward compatibility keep it here until version v3
func (*Port) SetWriteTimeout ¶
type PortError ¶
type PortError struct {
// contains filtered or unexported fields
}
PortError is a platform independent error type for serial ports
func (PortError) Code ¶
func (e PortError) Code() PortErrorCode
Code returns an identifier for the kind of error occurred
func (PortError) EncodedErrorString ¶
EncodedErrorString returns a string explaining the error code
type PortErrorCode ¶
type PortErrorCode int
PortErrorCode is a code to easily identify the type of error
const ( // PortBusy the serial port is already in used by another process PortBusy PortErrorCode = iota // PortNotFound the requested port doesn't exist PortNotFound // InvalidSerialPort the requested port is not a serial port InvalidSerialPort // PermissionDenied the user doesn't have enough priviledges PermissionDenied // InvalidSpeed the requested speed is not valid or not supported InvalidSpeed // InvalidDataBits the number of data bits is not valid or not supported InvalidDataBits // InvalidParity the selected parity is not valid or not supported InvalidParity // InvalidStopBits the selected number of stop bits is not valid or not supported InvalidStopBits // Invalid timeout value passed InvalidTimeoutValue // ErrorEnumeratingPorts an error occurred while listing serial port ErrorEnumeratingPorts // PortClosed the port has been closed while the operation is in progress PortClosed // FunctionNotImplemented the requested function is not implemented FunctionNotImplemented // Operating system function error OsError // Port write failed WriteFailed // Port read failed ReadFailed )
type RS485Config ¶
type RS485Config struct { // Enable RS485 support Enabled bool // Delay RTS prior to send DelayRtsBeforeSend time.Duration // Delay RTS after send DelayRtsAfterSend time.Duration // Set RTS high during send RtsHighDuringSend bool // Set RTS high after send RtsHighAfterSend bool // Rx during Tx RxDuringTx bool }
platform independent RS485 config. Thie structure is ignored unless Enable is true.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
Package enumerator is a golang cross-platform library for USB serial port discovery.
|
Package enumerator is a golang cross-platform library for USB serial port discovery. |