serial

package module
v2.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2019 License: BSD-3-Clause Imports: 10 Imported by: 0

README

github.com/darthrookie/go-serial/v2

Build Status

Package updated to v2 version

A cross-platform serial library for Go.

Forked from github.com/bugst/go-serial and now developing independently.

Many ideas were took from github.com/bugst/go-serial and github.com/pyserial/pyserial.

Any PR-s are welcome.

INSTALL

go get -u github.com/darthrookie/go-serial/v2

Documentation and examples

See the godoc here: https://godoc.org/github.com/darthrookie/go-serial

License

The software is release under a BSD 3-clause license

Documentation

Overview

Package go-serial is a cross-platform serial library for the go language.

import github.com/darthrookie/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/darthrookie/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),
)
if err != nil {
	log.Fatal(err)
}

// Send the string "10,20,30\n\r" to 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)

// 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)
		break
	}
	if n == 0 {
		fmt.Println("\nEOF")
		break
	}
	fmt.Printf("%v", string(buff[:n]))
}
Output:

Index

Examples

Constants

View Source
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
)
View Source
const FIONREAD = 0x541B

Variables

This section is empty.

Functions

func GetPortsList

func GetPortsList() ([]string, error)
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 WithBaudrate(o int) Option

func WithDataBits

func WithDataBits(o int) Option

func WithHUPCL

func WithHUPCL(o bool) Option

func WithParity

func WithParity(o Parity) Option

func WithReadTimeout

func WithReadTimeout(o int) Option

func WithStopBits

func WithStopBits(o StopBits) Option

func WithWriteTimeout

func WithWriteTimeout(o int) Option

type Parity

type Parity int

Parity describes a serial port parity setting

type Port

type Port struct {
	// contains filtered or unexported fields
}

Port is the interface for a serial Port

func Open

func Open(name string, opts ...Option) (*Port, error)

func (*Port) Close

func (p *Port) Close() error

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

func (p *Port) Read(b []byte) (int, error)

func (*Port) ReadyToRead

func (p *Port) ReadyToRead() (uint32, error)

func (*Port) Reconfigure

func (p *Port) Reconfigure(opts ...Option) error
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 (p *Port) ResetInputBuffer() error

func (*Port) ResetOutputBuffer

func (p *Port) ResetOutputBuffer() error

func (*Port) SetDTR

func (p *Port) SetDTR(dtr bool) error

func (*Port) SetFirstByteReadTimeout

func (p *Port) SetFirstByteReadTimeout(t uint32) error

func (*Port) SetRTS

func (p *Port) SetRTS(rts bool) error

func (*Port) SetReadTimeout

func (p *Port) SetReadTimeout(t int) error

func (*Port) SetReadTimeoutEx

func (p *Port) SetReadTimeoutEx(t, i uint32) error

func (*Port) SetWriteTimeout

func (p *Port) SetWriteTimeout(t int) error

func (*Port) String

func (p *Port) String() string

func (*Port) Write

func (p *Port) Write(b []byte) (int, error)

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

func (e PortError) EncodedErrorString() string

EncodedErrorString returns a string explaining the error code

func (PortError) Error

func (e PortError) Error() string

Error returns the complete error code with details on the cause of the error

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 StopBits

type StopBits int

StopBits describe a serial port stop bits setting

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL