GithubHelp home page GithubHelp logo

serial's Introduction

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)

serial's People

Contributors

adamslevy avatar akavel avatar astaxie avatar bsiegert avatar dallinski avatar eiannone avatar franxois avatar giacomoberlin avatar half2me avatar hnw avatar ipsusila avatar j-vizcaino avatar jdizzle avatar madhurjain avatar mdempsky avatar saschpe avatar tajtiattila avatar tarm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serial's Issues

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.

Conversion of CR to NewLine is not turned off properly

Inside serial.OpenPort, turning off ICRNL does not take effect unless port is closed and reopened again.

// Turn off break interrupts, CR->NL, Parity checks, strip, and IXON
    st.c_iflag &= ^C.tcflag_t(C.BRKINT | C.ICRNL | C.INPCK | C.ISTRIP | C.IXOFF | C.IXON | C.PARMRK)

Problems cross-compiling for linux-arm

I did a golang crosscompilation toolchain build for linux-arm (on a Mac OS X 10.8) following the instructions on http://dave.cheney.net/2012/09/08/an-introduction-to-cross-compilation-with-go (with go version 1.1). And I've confirmed the crosscompilation builds works (simple hello world, webserver etc.)

However, when I try to install goserial I run into problems:

Greger:Automation gc$ go-linux-arm get github.com/tarm/goserial
# github.com/tarm/goserial
../../../gopath/src/github.com/tarm/goserial/serial.go:92: undefined: openPort
../../../gopath/src/github.com/tarm/goserial/serial.go:92: not enough arguments to return

Any pointers to what might be wrong? (for in-platform, "go get github..." works nicely).

Serial Port Configurability

I'm curious, from a code point of view what it would take to add configuration for data bits, parity and stop bits. Is there some hurdle to this being implemented? Asking before I start digging in for possible solutions. Sounds like you are open to contributions?

Tag a version

Because of the recent changes with Go Modules, it would be cool if you could tag one of the commits with a version.

Non blocking mode undesiderable behavior

Tested in WINDOWS 7 64 bit.
The non-blocking mode behaves in a weird way. If you set the ReadTimeout to 5 seconds, it waits IN ANY CASE, input arriving or not 5 seconds before giving the data out. This is due to
timeouts.ReadIntervalTimeout = 0
timeouts.ReadTotalTimeoutMultiplier = 0
timeouts.ReadTotalTimeoutConstant = uint32(timeoutMs)
While these may be the desired behavior, probably what people wants when setting a timeout is having the data immediately unless the timeout passes without ANY data. This can be achieved with:
timeouts.ReadIntervalTimeout = MAXDWORD
timeouts.ReadTotalTimeoutMultiplier = MAXDWORD
timeouts.ReadTotalTimeoutConstant = uint32(timeoutMs)
I suggest to modify the code or to add a flag to decide which is the wanted behavior.
Thanks for the great job.

Paolo

Timeouts

The API documentation notes "There is currently no exposed way to set the timeouts, though patches are welcome.". On the other hand response on issues and pull requests is minimal to say the least. So @tarm, are you still maintaining this project?

Proposal

How about the following 3 methods from net.Conn?

    // SetDeadline sets the read and write deadlines associated
    // with the connection. It is equivalent to calling both
    // SetReadDeadline and SetWriteDeadline.
    //
    // A deadline is an absolute time after which I/O operations
    // fail with a timeout (see type Error) instead of
    // blocking. The deadline applies to all future and pending
    // I/O, not just the immediately following call to Read or
    // Write. After a deadline has been exceeded, the connection
    // can be refreshed by setting a deadline in the future.
    //
    // An idle timeout can be implemented by repeatedly extending
    // the deadline after successful Read or Write calls.
    //
    // A zero value for t means I/O operations will not time out.
    SetDeadline(t time.Time) error

    // SetReadDeadline sets the deadline for future Read calls
    // and any currently-blocked Read call.
    // A zero value for t means Read will not time out.
    SetReadDeadline(t time.Time) error

    // SetWriteDeadline sets the deadline for future Write calls
    // and any currently-blocked Write call.
    // Even if write times out, it may return n > 0, indicating that
    // some of the data was successfully written.
    // A zero value for t means Write will not time out.
    SetWriteDeadline(t time.Time) error

Error cross compiling from linux/amd64 to arm

Hi,

I setup my dev env to cross compile, my host is linux amd64 and trying to cross compile to arm givesme:

GOOS=linux GOARCH=arm go build
# github.com/huin/goserial
./serial.go:151: undefined: openPort
./serial.go:151: not enough arguments to return

but GOOS=windows go build
builds fine and I end up with a exe binary of my project

if I compile from an arm (raspbery pi), it compiles fine. Any idea of what I may be missing?

Thanks

Windows compatibility

Hi!

I have a strange problem, which gives me serious headaches. I am working with an device, which is connected through an FTDI chip. It has some quirks itself (for example only answering aber 20 seconds after accessing the serial port), but i managed to build a go library for it and it works pretty well, on linux.

As soon as i want to use the library on windows, i won't get any answer from the probe. I've tested the serial port itself with python, c and putty and it works flawlessly. It requires no special configuration, just 19200 baud, 8 data bits, 1 stop bit, no parity, no hardware flow control. I've even implemented a solution with cgo, which also works flawlessly.

I also tried every other golang serial library i've found, and all of them have the same problem. It's also interesting, that the serial library in general is working with other devices on windows.

Can you maybe give me a hint in the right direction? I'm sorry i can't give any more detail information on this, but i'm not quit sure what could be useful.

thanks in advance

pls add the ParityMark support for linux

Add ParityMark support for linux
//tarm/serial/serial_linux.go
line:95 add these code
case ParityMark:
cflagToUseg |=syscall.PARENB
cflagToUse |= unix.CMSPAR
cflagToUse |=syscall.PARODD

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.

Problems Cross Compiling [Mac + BSD]

So I am using a build tool called gox which makes a very effortless build toolchain for all platforms. I was just wondering if serial would have support for the following platforms? They seems like they should be supported based on the code but aren't compiling. Is this something that can be fixed in the code, or does this need configuration gox side? The main build that caught me off guard was Darwin but the others would be cool too. This is the log....

tsteinholz@Ghost ~> gox github.com/tsteinholz/EFM32_bootloader 

Number of parallel builds: 1

-->      netbsd/arm: github.com/tsteinholz/EFM32_bootloader
-->   freebsd/amd64: github.com/tsteinholz/EFM32_bootloader
-->      darwin/386: github.com/tsteinholz/EFM32_bootloader
-->    darwin/amd64: github.com/tsteinholz/EFM32_bootloader
-->       linux/386: github.com/tsteinholz/EFM32_bootloader
-->     linux/amd64: github.com/tsteinholz/EFM32_bootloader
-->       linux/arm: github.com/tsteinholz/EFM32_bootloader
-->     freebsd/386: github.com/tsteinholz/EFM32_bootloader
-->   windows/amd64: github.com/tsteinholz/EFM32_bootloader
-->     openbsd/386: github.com/tsteinholz/EFM32_bootloader
-->   openbsd/amd64: github.com/tsteinholz/EFM32_bootloader
-->     windows/386: github.com/tsteinholz/EFM32_bootloader
-->      netbsd/386: github.com/tsteinholz/EFM32_bootloader
-->     freebsd/arm: github.com/tsteinholz/EFM32_bootloader
-->    netbsd/amd64: github.com/tsteinholz/EFM32_bootloader

10 errors occurred:
--> netbsd/arm error: exit status 2
Stderr: # github.com/tarm/serial
Development/Go/src/github.com/tarm/serial/serial.go:94: undefined: Port
Development/Go/src/github.com/tarm/serial/serial.go:95: undefined: openPort

--> freebsd/amd64 error: exit status 2
Stderr: # github.com/tarm/serial
Development/Go/src/github.com/tarm/serial/serial.go:94: undefined: Port
Development/Go/src/github.com/tarm/serial/serial.go:95: undefined: openPort

--> darwin/386 error: exit status 2
Stderr: # github.com/tarm/serial
Development/Go/src/github.com/tarm/serial/serial.go:94: undefined: Port
Development/Go/src/github.com/tarm/serial/serial.go:95: undefined: openPort

--> darwin/amd64 error: exit status 2
Stderr: # github.com/tarm/serial
Development/Go/src/github.com/tarm/serial/serial.go:94: undefined: Port
Development/Go/src/github.com/tarm/serial/serial.go:95: undefined: openPort

--> freebsd/386 error: exit status 2
Stderr: # github.com/tarm/serial
Development/Go/src/github.com/tarm/serial/serial.go:94: undefined: Port
Development/Go/src/github.com/tarm/serial/serial.go:95: undefined: openPort

--> openbsd/386 error: exit status 2
Stderr: # github.com/tarm/serial
Development/Go/src/github.com/tarm/serial/serial.go:94: undefined: Port
Development/Go/src/github.com/tarm/serial/serial.go:95: undefined: openPort

--> openbsd/amd64 error: exit status 2
Stderr: # github.com/tarm/serial
Development/Go/src/github.com/tarm/serial/serial.go:94: undefined: Port
Development/Go/src/github.com/tarm/serial/serial.go:95: undefined: openPort

--> netbsd/386 error: exit status 2
Stderr: # github.com/tarm/serial
Development/Go/src/github.com/tarm/serial/serial.go:94: undefined: Port
Development/Go/src/github.com/tarm/serial/serial.go:95: undefined: openPort

--> freebsd/arm error: exit status 2
Stderr: # github.com/tarm/serial
Development/Go/src/github.com/tarm/serial/serial.go:94: undefined: Port
Development/Go/src/github.com/tarm/serial/serial.go:95: undefined: openPort

--> netbsd/amd64 error: exit status 2
Stderr: # github.com/tarm/serial
Development/Go/src/github.com/tarm/serial/serial.go:94: undefined: Port
Development/Go/src/github.com/tarm/serial/serial.go:95: undefined: openPort

All the others binaries work great all compiled on linux :) (windows and linux 32+64+ARM)

Having 0x10 set causes arduino to reset when serial message is sent

func setCommState(h syscall.Handle, baud int, databits byte, parity Parity, stopbits StopBits) error {
	var params structDCB
	params.DCBlength = uint32(unsafe.Sizeof(params))

	params.flags[0] = 0x01  // fBinary
	params.flags[0] |= 0x10 // Assert DSR

Having 0x10 set causes arduino to reset when serial message is sent when connecting via windows. I modified my copy of the library to remove this line.

func setCommState(h syscall.Handle, baud int, databits byte, parity Parity, stopbits StopBits) error {
	var params structDCB
	params.DCBlength = uint32(unsafe.Sizeof(params))

	params.flags[0] = 0x01  // fBinary
	//params.flags[0] |= 0x10 // Assert DSR

Currently using it in this project: https://github.com/ASoggyToaster/Max7219

when read 0 bytes not return EOF on windows

c := &serial.Config{Name: "COM4", Baud: 115200, ReadTimeout: time.Second * 5}
conn,_:=serial.OpenPort(c)
buf:= bytes.NewBufferString("")

n, err := buf.ReadFrom(conn) //always block!!
fmt.Printf("% x,%d,%v\n",buf.Bytes(),n,err)
buf.Reset()

Always returns [65]

on windows 7.
Using Termite:
Port: COM1
Baud rate: 115200
Data bits: 8
Stop bits: 1
Parity: none
Flow control: none

  • Append LF
TEMPS?
AC/DC Temperature 1 = 56 C
AC/DC Temperature 2 = 51 C
Control Brd Temp = 39 C
DC/AC Temperature = 39 C
DC2 Temperature = 55.18 C
DC2 Temperature 2 = 51.18 C
Battery Temperature = 29.8 C

Code below gives [65] though:

λ telem_serial.exe
2017/10/24 23:47:58 %q[65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
buf len:  1
package main

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

func main() {
	c := &serial.Config{Name: "COM1", Baud: 115200}
	s, err := serial.OpenPort(c)
	if err != nil {
		log.Fatal(err)
	}

	err = s.Flush()
	if err != nil {
		log.Fatal(err)
	}

	cmd := []byte("TEMPS?\r\n")
	n, err := s.Write(cmd)
	if err != nil {
		log.Fatal(err)
	}

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

List serial ports

Hello,
I use your serial communication library and it works great ! Do you plan to develop a function to list available serial ports ?
Thanks in advance and well done for your work

OpenPort does not return an error when no baud rate is specified on Linux

When attempting to open a port without specifying a baud rate an error should be returned. On Linux a nil error and nil port is returned.

On line 49 in serial_linux.go you can see that the return occurs before any error is set.

It is also possible that this error is also occurring in the Windows implementation but I can't test that. On line 211 in serial_windows.go a syscall is made but the baud rate is never checked up to this point.

windows serial read anomaly

Hello. Thank you for this project; I've used in a number of test tools I've built, and it has saved me an immense amount of time.

Today I ported, from Mac to Windows, something that I've used for nearly a year that just does something incredibly simple: echo.

I've got a device on my pc/mac's serial port that intermittently transmits newline-delimited text messages. The transmit on the send side happens to be in 63-byte chunks, with a minor (tens of milliseconds) delay between the chunks, and then the final flushed segment typically less than 63 bytes.

In most cases the transmitter sends about a half dozen newline-delimited lines at a time, then pauses for about 30s, and then does it again.

On my receive side, I've got a super simple tarm serial.Read() loop that echos what it sees coming in. (I've validated this behavior with my code, and also with the stripped down simple serial loop in your basic_test.)

When I run the code on the mac, as I said, it works perfectly. It just echo's what I see coming in: a burst of newline-delimited lines, then a gap, then another burst of lines, etc. It looks something like this:

SYNC POWER ON: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was SLEEP)
SYNC POWER OFF: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was NORMAL)
SERIAL POWER ON: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was SLEEP)
SERIAL POWER OFF: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was NORMAL)
...then a delay, and then...
SYNC POWER ON: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was SLEEP)
SYNC POWER OFF: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was NORMAL)
SERIAL POWER ON: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was SLEEP)
SERIAL POWER OFF: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was NORMAL)
..etc

When I run the code on windows, though, I see the burst of lines until the final line - but there's always a problem on that final line of the burst which appears as a partial line. It looks something like this:

SYNC POWER ON: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was SLEEP)
SYNC POWER OFF: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was NORMAL)
SERIAL POWER ON: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was SLEEP)
SERIAL POWER OFF: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMA
...then the usual 30s gap, and then...
MUX1 (was NORMAL)
SYNC POWER ON: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was SLEEP)
SYNC POWER OFF: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was NORMAL)
SERIAL POWER ON: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMAMUX1 (was SLEEP)
SERIAL POWER OFF: HIGH, USB, USART1, LPUART1, I2C3, DMA1, DMA
...etc.

I have added a 5-second read timeout and debugging code that shows that after that partial line is displayed, I properly get the read timeout - but the returned length is 0 of course, even though it is buffered somewhere.

The missing text always is received the moment the next single character comes inbound.

Thoughts?

Builds serial_posix instead of serial_linux on Linux amd64

Hi,
Seems this package builds for posix on linux.
Here is the output of the build even with GOOS=linux, as you can see it builds the posix file.
Could it be an issue with the // +build build constraints?
For now I've tweaked the linux and posix files so that the linux one builds with "cgo". (removed the excluding ! )

$ GOOS=linux go install -x github.com/tarm/serial
WORK=/tmp/go-build450422516
mkdir -p $WORK/github.com/tarm/serial/_obj/
mkdir -p $WORK/github.com/tarm/
cd /home/simon/go/src/github.com/tarm/serial
CGO_LDFLAGS="-g" "-O2" /usr/local/go/pkg/tool/linux_amd64/cgo -objdir $WORK/github.com/tarm/serial/_obj/ -- -I $WORK/github.com/tarm/serial/_obj/ serial_posix.go
/usr/local/go/pkg/tool/linux_amd64/6c -F -V -w -trimpath $WORK -I $WORK/github.com/tarm/serial/_obj/ -I /usr/local/go/pkg/linux_amd64 -o $WORK/github.com/tarm/serial/_obj/_cgo_defun.6 -D GOOS_linux -D GOARCH_amd64 $WORK/github.com/tarm/serial/_obj/_cgo_defun.c
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -print-libgcc-file-name
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/github.com/tarm/serial/_obj/ -g -O2 -o $WORK/github.com/tarm/serial/_obj/_cgo_main.o -c $WORK/github.com/tarm/serial/_obj/_cgo_main.c
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/github.com/tarm/serial/_obj/ -g -O2 -o $WORK/github.com/tarm/serial/_obj/_cgo_export.o -c $WORK/github.com/tarm/serial/_obj/_cgo_export.c
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -I $WORK/github.com/tarm/serial/_obj/ -g -O2 -o $WORK/github.com/tarm/serial/_obj/serial_posix.cgo2.o -c $WORK/github.com/tarm/serial/_obj/serial_posix.cgo2.c
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -o $WORK/github.com/tarm/serial/_obj/_cgo_.o $WORK/github.com/tarm/serial/_obj/_cgo_main.o $WORK/github.com/tarm/serial/_obj/_cgo_export.o $WORK/github.com/tarm/serial/_obj/serial_posix.cgo2.o -g -O2
/usr/local/go/pkg/tool/linux_amd64/cgo -objdir $WORK/github.com/tarm/serial/_obj/ -dynimport $WORK/github.com/tarm/serial/_obj/_cgo_.o -dynout $WORK/github.com/tarm/serial/_obj/_cgo_import.c
/usr/local/go/pkg/tool/linux_amd64/6c -F -V -w -trimpath $WORK -I $WORK/github.com/tarm/serial/_obj/ -I /usr/local/go/pkg/linux_amd64 -o $WORK/github.com/tarm/serial/_obj/_cgo_import.6 -D GOOS_linux -D GOARCH_amd64 $WORK/github.com/tarm/serial/_obj/_cgo_import.c
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -o $WORK/github.com/tarm/serial/_obj/_all.o $WORK/github.com/tarm/serial/_obj/_cgo_export.o $WORK/github.com/tarm/serial/_obj/serial_posix.cgo2.o -g -O2 -Wl,-r -nostdlib /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.a -Wl,--build-id=none
/usr/local/go/pkg/tool/linux_amd64/6g -o $WORK/github.com/tarm/serial.a -trimpath $WORK -p github.com/tarm/serial -D _/home/simon/go/src/github.com/tarm/serial -I $WORK -pack ./serial.go $WORK/github.com/tarm/serial/_obj/_cgo_gotypes.go $WORK/github.com/tarm/serial/_obj/serial_posix.cgo1.go
pack r $WORK/github.com/tarm/serial.a $WORK/github.com/tarm/serial/_obj/_cgo_import.6 $WORK/github.com/tarm/serial/_obj/_cgo_defun.6 $WORK/github.com/tarm/serial/_obj/_all.o # internal
mkdir -p /home/simon/go/pkg/linux_amd64/github.com/tarm/
mv $WORK/github.com/tarm/serial.a /home/simon/go/pkg/linux_amd64/github.com/tarm/serial.a

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"

timeoutMs redeclared which leads to non-working read on Windows

Line 200 has := instead of = and creates a new variable instead of using the higher scope one

if readTimeout > 0 {
    // non-blocking read
    timeoutMs := readTimeout.Nanoseconds() / 1e6  // ERROR : should be timeoutMs = ......
    if timeoutMs < 1 {
        timeoutMs = 1
    } else if timeoutMs > MAXDWORD-1 {
        timeoutMs = MAXDWORD - 1
    }
}

Installation fails on Raspberry Pi

sudo go get github.com/tarm/serial
# github.com/tarm/serial
/usr/lib/go/src/pkg/github.com/tarm/serial/serial_linux.go:114: undefined: syscall.TCIOFLUSH

No EOF on ARM

I'm using this library on ARM (Raspberry Pi), I never seem to receive an EOF.
When I tested it on my laptop it worked fine. Is there possibly a difference between the two?
(I use github.com/mitchellh/gox to cross-compile)

could not be installed on PCDuino

I attempted to install go serial on PCDuino, a Raspberry Pi like device, it threw out an error as :

/usr/lib/go/src/pkg/github.com/tarm/serial/serial_linux.go:150: undefined: syscall.TCIOFLUSH

windows not close event

func (p *Port) Close() error {
return p.f.Close()
}

func newOverlapped() (*syscall.Overlapped, error) {
var overlapped syscall.Overlapped
r, _, err := syscall.Syscall6(nCreateEvent, 4, 0, 1, 0, 0, 0, 0)
if r == 0 {
return nil, err
}
overlapped.HEvent = syscall.Handle(r)
return &overlapped, nil
}

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

ARM - "errno 0" response on Flush()

I'm using serial on an rPi3 and it seems to work fine, except for the Flush call. It returns an error with "errno 0". This call works great on Darwin when using the same USB<->Serial adapter.

I'm not sure how to diagnose this further.

250K baud

I'm trying to adapt this code to support a 250000 baud rate for 3D printers. Unfortunately I don't fully understand how I would interface with the kernel to achieve this. Mostly I'm trying to use idiomatic go but the syscall package doesn't support non-standard baud rates. My plan was to build a function that will handle non-standard baud rates then rather than throwing an error and would instead emit a warning about using a non-standard baud rate, then attempt to set it. Is there anything someone can point me to that would allow for this?

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 ?

Serial only receive 1 byte

run on window

  • used modusslave-tool test .
	sendbuf := []byte{0x40, 0x02, 0x00, 0x00, 0x00, 0x6E, 0xF6, 0xF7}
		n, err := s.Write(sendbuf)
	if err != nil {
		s.Close()
		fmt.Println("write close")
		log.Fatal(err)
	}

	buf := make([]byte, 128)

	n, err = s.Read(buf)
	if err != nil {
		fmt.Println("read close")
		log.Fatal(err)
	}
  • receive len n=1 byte . // Normal receive is : 40 02 0E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4E C1 ,but I only got one byte.
  • serial config
  	c := &serial.Config{Name: "COM5", Baud: 9600, ReadTimeout: time.Second * 5}

No DTR and RTS control

This functionality is a must in serial communication, because some devices requires DTR to be set to wake up from sleep.

Adapt Serial to Parallel Port

During the past month I tried to adapt go serial to read/write to a parallel port unsuccessfully in order to perform an online EEG study.

I'm running windows 7, Do you have some clues how to make it work?

Thanks!

PD: I can do a fork and upload the code if you want :)

when i cross compile to arm

when i using windows to make code and complie to arm and sent to arm,it log out 2018/02/27 00:49:37 open COM3: no such file or directory, and ideas ?

Doesn't work on windows...

what i've done:
go get github.com/tarm/goserial
there is no error when the port it's opened and Write function works, but nothing is read on Read function...
Platform: Win7 x64, go 1.0.3

Nevermind, it works (virtualbox issue)

Read function always EOF

Hello, I tried exactly as the example (except the port name). I use tty0tty as the serial port. I successfully write string to the port but failed to read from it. It always return an empty string and raise the "EOF" error. I've used time interval to wait for the writing process but no luck.

Any suggestions?

Return an error when requested ReadTimeout is larger than supported max of 25.5s

Took me a while of debugging to find out that timeouts given to ReadTimeout never go longer than 25.5 s. I work with a modem that can take 3 minutes to respond to certain commands.

Would by nice to have the init error out when a timeout higher than 25.5s is given, instead of silently limiting the min/max values of ReadTimeout.

undefined: openPort

I get the following when trying to install the package:

$ go get github.com/tarm/goserial
# github.com/tarm/goserial
github.com/tarm/goserial/serial.go:92: undefined: openPort
github.com/tarm/goserial/serial.go:92: not enough arguments to return

I see that openPort is defined in serial_posix.go, but I don't find any references to that file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.