A Go package to allow you to read and write from the serial port as a stream of bytes.

GoDoc Build Status

Serial

A Go package to allow you to read and write from the serial port as a stream of bytes.

Details

It aims to have the same API on all platforms, including windows. As an added bonus, the windows package does not use cgo, so you can cross compile for windows from another platform.

You can cross compile with GOOS=windows GOARCH=386 go install github.com/tarm/serial

Currently there is very little in the way of configurability. You can set the baud rate. Then you can Read(), Write(), or Close() the connection. By default Read() will block until at least one byte is returned. Write is the same.

Currently all ports are opened with 8 data bits, 1 stop bit, no parity, no hardware flow control, and no software flow control. This works fine for many real devices and many faux serial devices including usb-to-serial converters and bluetooth serial ports.

You may Read() and Write() simulantiously on the same connection (from different goroutines).

Usage

package main

import (
        "log"

        "github.com/tarm/serial"
)

func main() {
        c := &serial.Config{Name: "COM45", Baud: 115200}
        s, err := serial.OpenPort(c)
        if err != nil {
                log.Fatal(err)
        }
        
        n, err := s.Write([]byte("test"))
        if err != nil {
                log.Fatal(err)
        }
        
        buf := make([]byte, 128)
        n, err = s.Read(buf)
        if err != nil {
                log.Fatal(err)
        }
        log.Printf("%q", buf[:n])
}

NonBlocking Mode

By default the returned Port reads in blocking mode. Which means Read() will block until at least one byte is returned. If that's not what you want, specify a positive ReadTimeout and the Read() will timeout returning 0 bytes if no bytes are read. Please note that this is the total timeout the read operation will wait and not the interval timeout between two bytes.

	c := &serial.Config{Name: "COM45", Baud: 115200, ReadTimeout: time.Second * 5}
	
	// In this mode, you will want to suppress error for read
	// as 0 bytes return EOF error on Linux / POSIX
	n, _ = s.Read(buf)

Possible Future Work

  • better tests (loopback etc)
Comments
  • Added support for bytesize, stopbits, parity

    Added support for bytesize, stopbits, parity

    I try to add support for bytesize 5,6,7,8, parity, stopbits. I tested on windows and it seems to work. I don't know how to deal with the 1.5 stop bits, so I turn it on-the-fly to 2 I cannot compile the "posix" version so I can't guaranteed about that. Each new parameter is optional, so the library is retro-compatible and defaulted to 8N1, as requested by the author.

  • Data, parity, stop bit settings and config parsing and formatting

    Data, parity, stop bit settings and config parsing and formatting

    The first commit is the PR #34 from @paocalvi squashed and cleaned up to use the go naming convention. It return errors for unsupported configuration instead of using defaults.

    The second commit replaces naked returns to use arguments in some function(s). Naked returns should be used only in short functions.

    The third commit just adds a build tag so that I could test format.go on windows.

    The fourth commit adds code to format and parse serial configurations, useful for command line argument handling.

  • When receiving data, one segment of data is divided into two segments

    When receiving data, one segment of data is divided into two segments

    Main Environment OS: win10 x64 GO env: GOARCH=amd64 ` package main

    import ( "fmt" "github.com/tarm/serial" "log" )

    func main() {

    fmt.Printf("lanuch server \n")
    
    c := &serial.Config{
    	Name: "COM3",
    	Baud: 115200,
    	//ReadTimeout:time.Second *5,
    }
    
    s, err := serial.OpenPort(c)
    if err != nil {
    	log.Fatal(err)
    }
    buf := make([]byte, 128)
    for{
    		n, err := s.Read(buf)
    		if err != nil {
    		log.Fatal(err)
    
    }
    	fmt.Printf("%q", buf[:n])
    

    } } ` image

    When I send "123456 ", data is divided into two segments part A: "1" partB : "23456"

  • mipsle compile

    mipsle compile

    Hi,

    Your library looks solid and can use on linux np. However, I did most recently purchase some new IoT Omega2 processors from onion.io and they could be quite popular.

    I have been writing programs in GO and running on it w/no problem. Runs great, small and tight. I was hoping to get some serial port development going on it, and of course, seem to be quite a few platform specific items breaking.

    Your serial lib seems the closest. I try to compile the simple default sample you provide with the library, and get the following error using this compile syntax.

    GOOS=linux GOARCH=mipsle go build -compiler gc serial.go

    # github.com/tarm/serial
    src/github.com/tarm/serial/serial_linux.go:105: unknown field 'Ispeed' in struct literal of type syscall.Termios
    src/github.com/tarm/serial/serial_linux.go:106: unknown field 'Ospeed' in struct literal of type syscall.Termios
    

    Anything I can do to help you support this platform ?

  • Adds NonBlocking Mode

    Adds NonBlocking Mode

    • Setting ReadTimeout to positive value sets non blocking mode
    • ReadTimeout is specified in milliseconds irrespective of platform
    • Caps ReadTimeout on Linux / POSIX systems
    • Updated README
  • Provide API for reading/writing to serial port via channels

    Provide API for reading/writing to serial port via channels

    I suggest adding a new method

    func OpenPortChan(c *Config) (chan<- []byte, <-chan []byte, error)
    

    that returns a pair of channels that can be used to read and write to the serial port directly, by spawning a couple of goroutines redirecting input/output from/to the port. I have a pull request almost ready, will send it for discussion soon.

  • Adding some serial configuration options

    Adding some serial configuration options

    The other change in here, which I can understand if you'd rather that I reverted, is changing the package name from "serial" to "goserial" to meet normal Go package naming conventions (i.e package named after last directory component).

  • Use

    Use "golang.org/x/sys/unix" instead of "syscall" (fix #59)

    According to the discussion on golang/go#18866, Termios from golang.org/x/sys/unix has better portability than syscall.Termios. So we should use it.

    This PR works fine on mipsle.

  • cannot read a whole message

    cannot read a whole message

    buf := make([]byte, 128)
    for {
    	n, err = s.Read(buf)
    	if err != nil {
    	    log.Fatal(err)
    	}
    	log.Printf("%q", buf[:n])
    }
    

    result of code above: when receive "abcdef" it will print "a" and "bcdef" always a single byte followed by reminded bytes. what is the problem?

    btw, I use windows 10 build1703, Go 1.8, VSPD 6.9(virtual serial port).

  • change parity on the fly?

    change parity on the fly?

    I'm trying to implement fimrware upload to STM32 microcontrollers for Windows, MacOS, and Linux using this package, which requires setting the serial port in even parity 8 bits mode. This can be done on open, but not on-the-fly, given the current API.

    Would it be an option to add this capability? I can have a go at it - it'd be nice to know if a pull request has any chance of being considered.

    I tried closing and re-opening the serial port as a workaround, but can't seem to close the port when there is a read pending in another goroutine.

    UPDATE: a read timeout would let me close the port, but unfortunately it looks like a timeout is indistinguishable from an EOF due to a port disconnect, so this too seems to be a no-go.

  • windows FlowControl

    windows FlowControl

    https://github.com/tarm/serial/blob/master/serial.go#L111-L115

    Can you add more information about

    // RTSFlowControl bool // DTRFlowControl bool // XONFlowControl bool // CRLFTranslate bool

    Thanks

  • lost data via bufio.Read

    lost data via bufio.Read

    I am using ubuntu, when I use bufio to read from serial, it seems lost some data. But it's ok to use the raw Read. It's very strange.Bellow is my code.

    func main() {
        c := &serial.Config{Name: "/dev/ttyUSB0", Baud: 2000000}
        s, err := serial.OpenPort(c)
        if err != nil {
            log.Fatal(err)
        }
        for {
            if false {
                // this branch will lost data
                var n int
                buf := make([]byte, 128)
                br := bufio.NewReader(s)                                                                                                                                                                                                                           
                n, err = br.Read(buf)                                                                                                                                                                                                                              
                fmt.Print(string(buf[:n]))                                                                                                                                                                                                                         
            } else {  
               // this branch is ok                                                                                                                                                                                                                                             
                var n int                                                                                                                                                                                                                                          
                buf := make([]byte, 128)                                                                                                                                                                                                                           
                n, err = s.Read(buf)                                                                                                                                                                                                                               
                if err != nil {                                                                                                                                                                                                                                    
                    log.Fatal(err)                                                                                                                                                                                                                                 
                }                                                                                                                                                                                                                                                  
                fmt.Printf(string(buf[:n]))                                                                                                                                                                                                                        
            }                                                                                                                                                                                                                                                      
        }                                                                                                                                                                                                                                                          
    } 
    
  • How catch Lost Serial port(for example USB virtual rs-232 unplug)

    How catch Lost Serial port(for example USB virtual rs-232 unplug)

    Hi Thanks for library. I have a question. My environment: Linux Centos 7x 64 . Usb Virtual rs-232 . Its mapped as /dev/USB0(1,2,3..) or /dev/ACM0(1,2,3...) library work but when USB device unplug, my application have crashed and exit. How I can catch this event(unplug) and reconnect(or wait connection),?

  • Gen2 License plate recognition is not working

    Gen2 License plate recognition is not working

    Hello,

    I have been trying the license plate recognition sample and it is not working as shown in the video. I used the chinese_traffic.mp4 as input and I only get the rgb and attributes window. The license plates are not being recognized. Is anything missing to enable the plate recognition?

    Thanks, Marcelo

  • Connecting to existing port crashes PC

    Connecting to existing port crashes PC

    Hey I tried to open bluetooth module HC-05(com7), that has been already connected to PC. from the code, I cannot open an already opened port. If I try to explicitly specify this COM7 (for me, at the time of development) and write to bluetooth, the bluetooth crashes. I did not dig deep in, but also the PC crashed. I am using Windows 10.

      func main() {
          c := &serial.Config{Name: "COM7", Baud: 9600, ReadTimeout: time.Millisecond * 500}
          s, err := serial.OpenPort(c)
          if err != nil {
    	      log.Fatal(err)
          }
          fmt.Println("writing")
      
          n, err := s.Write([]byte("F"))
          if err != nil {
    	      log.Fatal(err)
          }
          fmt.Println(n)
      }
    
Related tags
A simple tool to send binary data over a serial port. Designed for use with my retro computer systems.

Colin's Transfer Tool This is a really basic tool to transfer firmware files to my retro computer systems over a serial port. This removes the need fo

Dec 21, 2021
Store - Read and write data structures

Store - Read and write data structures Store provides the ability to write the data structures to a file and read from a file in the Go programming la

Jan 3, 2022
A ocilloscope writen in GO. Supported serial input, portaudio input.

A ocilloscope writen in GO. Supported serial input, portaudio input.

Oct 23, 2021
Arduino pluggable discovery for serial ports

Arduino pluggable discovery for serial ports The quarto-discovery tool is a command line program that interacts via stdio. It accepts commands as plai

Oct 29, 2021
Go library for generate serial numbers according to rules.

go-sn - Serial Number Generator Go library for generate serial numbers according to rules. This library is also useful for generating serial numbers i

Sep 8, 2022
Serial to Keyboard converter for Polar's card readers

polar-serial-to-keyboard Serial to Keyboard converter for Polar's card readers Configuration This program is intended to be run as a background proces

Dec 17, 2021
Buffer Compactor is a tool to allow for buffering for a duration and compacting data on keys.

Buffer Compactor is a tool to allow for buffering for a duration and compacting data on keys. It uses a badgerDB and sortedset in order to coridinate a time-delayed queue that also aggregates updates sharing the same key in a extremely peformant manner.

Feb 8, 2022
PKSUID is a small extension for KSUID (K-Sortable Globally Unique IDs) which allows prefixing it with arbitrary up to 16 bytes strings

PKSUID is a small extension for KSUID (K-Sortable Globally Unique IDs) which allows prefixing it with arbitrary up to 16 bytes strings

Dec 1, 2022
Squizit is a simple tool, that aim to help you get the grade you want, not the one you have learnt for.
Squizit is a simple tool, that aim to help you get the grade you want, not the one you have learnt for.

Squizit is a simple tool, that aim to help you get the grade you want, not the one you have learnt for. Screenshots First, input PIN Then enjoy! Hoste

Mar 11, 2022
The package manager for macOS you didn’t know you missed. Simple, functional, and fast.
The package manager for macOS you didn’t know you missed. Simple, functional, and fast.

Stew The package manager for macOS you didn’t know you missed. Built with simplicity, functionality, and most importantly, speed in mind. Installation

Mar 30, 2022
💥 Fusion is a tiny stream processing library written in Go.

?? Fusion Fusion is a tiny stream processing library written in Go. See reactor for a stream processing tool built using fusion. Features Simple & lig

Jun 30, 2021
Processing Nomad Events Stream
Processing Nomad Events Stream

Nomad Events Sink Nomad Events Sink is an events collection agent which uses Nomad Events SDK to fetch events. Events can help debug the cluster state

Dec 19, 2022
Measurements stream joiner.

sensors Measurements stream joiner

Dec 13, 2021
Decrypts and dumps K3s bootstrap data read from stdin.

k3s-dump-bootstrap Decrypts and dumps K3s bootstrap data read from stdin. Note: <token> parameter should be just the bare passphrase, not a full K10-f

Jan 12, 2022
Parse a shell script and output all export declarations in an easy to read format

Find Exports Parse a shell script and output all export declarations in an easy to read format. Usage Example $ findexports ~/.bashrc PATH=$PATH:/usr/

Jan 13, 2022
Write API for employees and teams

Problem Manager Employees - Teams Connect to Database and save information Write API for employees and teams Getting Started Install MySQL Create file

Feb 18, 2022
Day-1 is apart of my 6 days of Christmas challenge where i write in two new languages everyday, and make something weird out of it.

Day-1 is apart of my 6 days of Christmas challenge where i write in two new languages everyday, and make something weird out of it. today was a HTTP server written with PostGreSQL using Golang, R, and shell script read more

Dec 21, 2021
Read RFID card data so Protospace directors can assign them to users!

RFID Reader Dependencies This application was developed with: go1.17.5 linux/amd64 xclip version 0.13 (if you're on Linux) Find go for your OS and arc

Dec 15, 2021
Vocabular checker JetBrains Academy home work Read file with bad words

Vocabulary Checker JetBrains Academy home work Read file with bad words and replace them on * in the next entered text until exitVocabulary Checker JetBrains Academy home work Read file with bad words and replace them on * in the next entered text until exit

Jan 14, 2022