serial

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2019 License: BSD-3-Clause Imports: 11 Imported by: 7

README

go-serial

Build Status

A cross-platform serial library for go-lang based on github.com/bugst/go-serial with own import path and some modifications (possible incompatible with original library).

Most ideas taken from github.com/bugst/go-serial and github.com/pyserial/pyserial.

Sometime I do backports from github.com/bugst/go-serial.

Any PR-s are welcome.

Documentation and examples

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

License

The software is release under a BSD 3-clause license

Documentation

Overview

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

import github.com/albenik/go-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 "github.com/albenik/go-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.

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
mode := &serial.Mode{
	BaudRate: 9600,
	Parity:   serial.NoParity,
	DataBits: 8,
	StopBits: serial.OneStopBit,
}
port, err := serial.Open(ports[0], mode)
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 FIONREAD = 0x541B

Variables

This section is empty.

Functions

func GetPortsList

func GetPortsList() ([]string, error)

GetPortsList retrieve the list of available serial ports

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 Mode

type Mode struct {
	BaudRate int      // The serial port bitrate (aka Baudrate)
	DataBits int      // Size of the character (must be 5, 6, 7 or 8)
	Parity   Parity   // Parity (see Parity type for more info)
	StopBits StopBits // Stop bits (see StopBits type for more info)
}

Mode describes a serial port configuration.

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 Parity

type Parity int

Parity describes a serial port parity setting

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
)

type Port

type Port interface {
	fmt.Stringer

	// SetMode sets all parameters of the serial port
	SetMode(mode *Mode) error

	// SetReadTimeout sets the whole packet read timeout.
	// Values:
	//   t < 0: Blocking mode
	// 			`Read` function wait until requested number of bytes are received (possible forever).
	//   t = 0: Non-blocking mode
	// 			`Read` function returns immediately in any case, returning up to the requested number of bytes.
	//   t > 0: set timeout to `t` milliseconds.
	// 			`Read` function returns immediately when the requested number of bytes are available,
	//          otherwise wait until the timeout expires and return all bytes that were received until them.
	SetReadTimeout(t int) error

	// SetReadTimeoutEx — Sets whole package read timeout similar to general purpose function SetReadTimeout(),
	// and also sets interbyte timeout.
	//
	// Generally interbyte timeout is not needed, but in some special cases this function cat help you.
	SetReadTimeoutEx(t, i uint32) error

	// SetLegacyReadTimeout — Very special function.
	//
	// Based on https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa363190(v=vs.85).aspx:
	// If there are any bytes in the input buffer, ReadFile returns immediately with the bytes in the buffer.
	// If there are no bytes in the input buffer, ReadFile waits until a byte arrives and then returns immediately.
	// If no bytes arrive within the time specified by ReadTotalTimeoutConstant, ReadFile times out.
	//
	// Use it to configure read timeout in legacy manner. (Legacy for this library).
	SetFirstByteReadTimeout(t uint32) error

	// SetWriteTimeout set whole packet write timeout
	// Values:
	// Values:
	//   t < 0: Blocking mode
	// 			`Write` function will block until complete or error.
	// 			Depending of OS layer it can call multiple subsequent os-level write calls until done.
	//   t = 0: Non-blocking mode
	// 			`Write` function will write some data and returns even not all data has been written.
	//          Depending of OS layer it makes only signle subsequent os-level write call.
	//   t > 0: set timeout to `t` milliseconds.
	// 			`Write` function will write untile complete, error or timeout.
	// 			Depending of OS layer it can call multiple subsequent os-levek write calls until done.
	SetWriteTimeout(t int) error

	// Get the number of bytes that are immediately available for reading
	ReadyToRead() (uint32, error)

	// Stores data received from the serial port into the provided byte array
	// buffer. The function returns the number of bytes read.
	//
	// The Read function blocks until (at least) one byte is received from
	// the serial port or a timeout reached or an error occurs.
	Read(p []byte) (n int, err error)

	// Send the content of the data byte array to the serial port.
	// Returns the number of bytes written.
	Write(p []byte) (n int, err error)

	// ResetInputBuffer Purges port read buffer
	ResetInputBuffer() error

	// ResetOutputBuffer Purges port write buffer
	ResetOutputBuffer() error

	// SetDTR sets the modem status bit DataTerminalReady
	SetDTR(dtr bool) error

	// SetRTS sets the modem status bit RequestToSend
	SetRTS(rts bool) error

	// GetModemStatusBits returns a ModemStatusBits structure containing the
	// modem status bits for the serial port (CTS, DSR, etc...)
	GetModemStatusBits() (*ModemStatusBits, error)

	// Close the serial port
	Close() error
}

Port is the interface for a serial Port

func Open

func Open(portName string, mode *Mode) (Port, error)

Open opens the serial port using the specified modes

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

const (
	// OneStopBit sets 1 stop bit (default)
	OneStopBit StopBits = iota
	// OnePointFiveStopBits sets 1.5 stop bits
	OnePointFiveStopBits
	// TwoStopBits sets 2 stop bits
	TwoStopBits
)

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