Giter Site home page Giter Site logo

go-serial's Introduction

Build Status

go.bug.st/serial

A cross-platform serial port library for Go.

Documentation and examples

See the package documentation here: https://pkg.go.dev/go.bug.st/serial

go.mod transition

This library supports go.mod with the import go.bug.st/serial.

If you came from the pre-go.mod era please update your import paths from go.bug.st/serial.v1 to go.bug.st/serial to receive updates. The latest v1 release is still available using the old import path.

Credits

✨ Thanks to all awesome contributors! ✨

License

This software is released under the BSD 3-clause license.

go-serial's People

Contributors

albenik avatar andrerenaud avatar angri avatar cbrake avatar cmaglie avatar ctarsjp avatar deadprogram avatar deining avatar facchinm avatar fbettag avatar giacomoberlin avatar jackdoanrivian avatar jekaxv avatar jes avatar lukasbeckercode avatar maddie avatar martinzak-zaber avatar niondir avatar palazzol avatar paralin avatar pho avatar polomsky avatar quite avatar qulogic avatar tobiaskohlbau avatar twpayne 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

go-serial's Issues

Windows: Set DTS via setCommState

I found this comment:

func (port *windowsPort) SetRTS(rts bool) error {
	// It seems that there is a bug in the Windows VCP driver:
	// it doesn't send USB control message when the RTS bit is
	// changed, so the following code not always works with
	// USB-to-serial adapters.

But have the same problem for DTR, setting DTR does not work correctly when using escapeCommFunction.

Observed behavior:
Connect -> RTS = true (low) DTR = true (low) OKAY
SetDTR(false) -> RTS = true (low) DTR = false (heigh) OKAY
SetRTS(false) -> RTS = false (heigh) DTR = true (low) ERROR: DTR toggled

This does not happen with the following fix, were one has better control over the state of the line:

func (port *windowsPort) SetDTR(dtr bool) error {
	/*
		var res bool
		if dtr {
			res = escapeCommFunction(port.handle, commFunctionSetDTR)
		} else {
			res = escapeCommFunction(port.handle, commFunctionClrDTR)
		}
		if !res {
			return &PortError{}
		}
	*/

	params := &dcb{}
	if err := getCommState(port.handle, params); err != nil {
		return &PortError{causedBy: err}
	}
	params.Flags &= dcbDTRControlDisableMask
	if dtr {
		params.Flags |= dcbDTRControlEnable
	}
	if err := setCommState(port.handle, params); err != nil {
		return &PortError{causedBy: err}
	}

	return nil
}

Plus there is a typo in dcbRTSControlDisbaleMask -> Disable

I have a problem if using serial.v1/enumerator on macOS High Sierra (10.13.5)

Hi I'm trying to get information about the connected serial devices using the serial.v1/enumerator library but I get the following error:

go build go.bug.st/serial.v1/enumerator: invalid flag in #cgo LDFLAGS: -fconstant-cfstrings

My sample code used which comes from the godoc documentation of the serial.v1 library (https://godoc.org/go.bug.st/serial.v1) is:

package main

import "go.bug.st/serial.v1"
import "go.bug.st/serial.v1/enumerator"
import "fmt"
import "log"

func main() {

    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);
    }   

    ports, err = enumerator.GetDetailedPortsList()
    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);
    }   
}

go env:

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/gibranvargas/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/gibranvargas/go"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/vm/fs2hwdyd6gg88yt_k41zmjwm0000gp/T/go-build854035366=/tmp/go-build -gno-record-gcc-switches -fno-common"

I tried the code in a Windows and Linux environment and I dont get the error. Has anybody encounter this issue?

Fast Transfers Data-Loss

I'm using bugst/go-serial to send data from my computer to a embedded system. My current application uses some buffering and C-libraries to handle the data (framing) so I have to use the Write call byte-by-byte.

This results in very fast subsequent calls to .Write. While this was not a problem for a small amount of data on larger amounts (100+ Bytes) the write call produces invalid data:

  • I am verifying that the data I pass to port.Write is indeed what I want to send (logging it)
  • I am checking the return values of port.Write - no issues there
  • the serial port does produce the correct number of bytes but the content is not correct (some 22 bytes have the wrong content)

a snippet of my function-call:

func goSerialTx(data C.uint8_t) int {
	byteData := byte(data)
	fmt.Printf(" 0x%02X\n", byteData)

	if Wire().serialPort == nil {
		return 1
	}

	// time.Sleep(1 * time.Millisecond)

	n, err := Wire().serialPort.Write([]byte{byteData})
	if (err != nil) || (n == 0) {
		log.Warning("call to serialPort.Write failed")
		return 1
	}
	// fmt.Println("n bytes written ", n)
	return 0
}

Here Wire().serialPort simply returns a reference to the singleton (port). I've tried lowering the baudrate but the problem is not on the wire: I am using a logic analyzer to check the logged data against what's really on the wire to make sure it's not the embedded device that's not working.

I've tried adding a time.Sleep call > this would resolve the issue (data is transferred correctly) but would cripple the communication.

Any ideas? Thanks!

stop reading

In the example Project, there is this block of code:

// 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]))
}

However, if n==0 never becomes true on my machine, so the reading doesn´t stop

Certificate expired for go.bug.st

When running go get go.bug.st/serial

root@47206a184542:/go# go get go.bug.st/serial
package go.bug.st/serial: unrecognized import path "go.bug.st/serial" (https fetch: Get https://go.bug.st/serial?go-get=1: x509: certificate has expired or is not yet valid)

Accessing via Chrome https://go.bug.st reports the following:

NET::ERR_CERT_DATE_INVALID
Subject: go.bug.st

Issuer: Let's Encrypt Authority X3

Expires on: Jan 10, 2020

Current date: Jan 11, 2020

Submit custom syscalls to golang

I'm wondering if we can submit the missing syscalls (that we generate with mksyscall & friend) to upstream golang developers to be added to the syscall package, so they could be removed from this library.

After some research here's what I've found:

  • syscall is a frozen package, is kept alive just for the go v1 compatibility promise, here the notice coming from https://golang.org/pkg/syscall/:

    NOTE: This package is locked down. Code outside the standard Go repository should be migrated to use the corresponding package in the golang.org/x/sys repository. That is also where updates required by new systems or versions should be applied. See https://golang.org/s/go1.4-syscall for more information.

  • The new golang.org/x/sys package looks promising but we should first migrate the library to use golang.org/x/sys instead of syscall.

@albenik (or anyone esle) do you have any experience/opinion on that?

Trouble using GetDetailedPortsList on Mac

Hello - I'm trying out the GetDetailedPortsList(), because it'd be a great way to help choosing from a list of serial ports to connect to, but get the following errors on macOS 10.12.4:

# go.bug.st/serial.v1/enumerator
../../Go/src/go.bug.st/serial.v1/enumerator/usb_darwin.go:155: cannot use property (type C.CFTypeRef) as type *C.struct___CFString in argument to func literal
../../Go/src/go.bug.st/serial.v1/enumerator/usb_darwin.go:161: cannot use property (type C.CFTypeRef) as type *C.struct___CFString in argument to func literal
../../Go/src/go.bug.st/serial.v1/enumerator/usb_darwin.go:176: cannot use property (type C.CFTypeRef) as type *C.struct___CFNumber in argument to func literal

The irony being that on macOS, I don't really need this, since the /dev/tty.* names are usually self-descriptive already (i.e. serial # included in device name). For Linux and Windows however, that extra information would be very useful, especially since assigned device names can change.

Is there a way to disable the macOS variants to avoid the above errors, and still get this functionality for Linux and Windows? (I'm guessing it can be done with some mix of blah_arch.go and blah.go files)

Darwin 64-bit not sending

I can't get the 64-bit version of this package to work on macOS:

package main

import (
    "go.bug.st/serial.v1"
    "time"
)

func main() {
    tty, err := serial.Open("/dev/cu.usbserial-A600dW4s", &serial.Mode{
        BaudRate: 115200,
    })
    if err != nil {
        panic(err)
    }

    for {
        tty.Write([]byte("xxxxxxxxxxxxxxxxxxxxxxxxxx"))
        time.Sleep(time.Second)
    }
}

This works: GOOS=darwin GOARCH=386 go run try.go and blinks the TX LED.
This doesn't: GOOS=darwin GOARCH=amd64 go run try.go.

Malformed data being sent on Windows

Hello,

We have been using this library for some time and we have encountered an issue which is very difficult to reproduce and debug. The problem is caused by the Read function in the windows implementation:

func (port *windowsPort) Read(p []byte) (int, error) {
	var readed uint32
	params := &dcb{}
	ev, err := createOverlappedEvent()
	if err != nil {
		return 0, err
	}
	defer syscall.CloseHandle(ev.HEvent)
	for {
		err := syscall.ReadFile(port.handle, p, &readed, ev)
		switch err {
		case nil:
			// operation completed successfully
		case syscall.ERROR_IO_PENDING:
			// wait for overlapped I/O to complete
			if err := getOverlappedResult(port.handle, ev, &readed, true); err != nil {
				return int(readed), err
			}
		default:
			// error happened
			return int(readed), err
		}

		if readed > 0 {
			return int(readed), nil
		}
		if err := resetEvent(ev.HEvent); err != nil {
			return 0, err
		}

		// At the moment it seems that the only reliable way to check if
		// a serial port is alive in Windows is to check if the SetCommState
		// function fails.

		getCommState(port.handle, params)
		if err := setCommState(port.handle, params); err != nil {
			port.Close()
			return 0, err
		}
	}
}

If there is no traffic on the port this function calls setCommState every 1 second. If there is also an ongoing Write operation at the same time, the transmitted data gets malformed and the other side receives gibberish. The race condition requires very precise timing to be reproduced. We are very confident that the issue is not caused by our code.

As this library is used by your customers I thought this may be quite critical information for you. We have spent around two days hunting this down. Feel free to contact me for more details.

Thank you for implementing this awesome library.

Windows port.Read() returns wrong count of readed bytes in OVERLAPPED mode

See: https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa365467(v=vs.85).aspx

lpNumberOfBytesRead [out, optional]
A pointer to the variable that receives the number of bytes read when using a synchronous hFile parameter. ReadFile sets this value to zero before doing any work or error checking. Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results.
This parameter can be NULL only when the lpOverlapped parameter is not NULL.
For more information, see the Remarks section.

I my case alwaysn=1 so, all checks on this value now broken.

Unblock Read on Close

At least on linux I have the problem that my reading goroutine just hangs in blocking Read until the cable is pulled. One small hack/fix that seemed to work - but should probably be done in a cleaner way was:

// Close the serial port
func (port *SerialPort) Close() error {
	syscall.SetNonblock(port.handle, true)  <----
	port.releaseExclusiveAccess()
	return syscall.Close(port.handle)
}

thoughts?

go module picks untagged revision

Hello

I have not used the module system much before but I've recently started using it in a new project and I've noticed that the your package gets picked up as the raw commit, not the tagged version. For example, this is what I got in my go.mod file:

	go.bug.st/serial.v1 v0.0.0-20191202182710-24a6610f0541

Since there are three tags on the project I was expecting go to pick v1.1.1. Do you know if this is expected?

Read from port blocks forever when data is received

Device constantly sends data to host. Upon reading first time, text is read that device never sends and second read blocks forever. But if I use "github.com/tarm/serial", everything works ok. My OS is windows 10 x64. My code:

package main

import (
	"fmt"
	"log"
	"regexp"

	serial "go.bug.st/serial.v1"
)

func main() {
	config := serial.Mode{BaudRate: 115200, DataBits: 8, Parity: serial.NoParity, StopBits: serial.OneStopBit}
	p, err := serial.Open("COM8", &config)
	if err != nil {
		log.Fatal(err)
	}
	buf := make([]byte, 512)
	totalBuf := make([]byte, 0, 5000)
	var n int
	var foundLineIndex int
	search, err := regexp.Compile("([0-9\\.]*)/([0-9\\.]*)")
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Start scaning")
	for {
		log.Println("read data")
		n, err = p.Read(buf)
		if err != nil {
			log.Println("Error! Failed to read:", err)
			continue
		}
		// log.Println(buf[:n])
		for i, v := range buf[:n] {
			if v == '\r' {
				log.Println("Found line end")
				foundLineIndex = i + 1
			}
		}
		if foundLineIndex > 0 {
			totalBuf = append(totalBuf, buf[:foundLineIndex]...)
			result := search.FindAllSubmatch(totalBuf, -1)
			fmt.Println(result)
			if foundLineIndex < n {
				totalBuf = append(totalBuf[:0], buf[foundLineIndex:n]...)
				fmt.Println("there are leftovers")
			}
		} else {
			totalBuf = append(totalBuf, buf[:n]...)
		}
	}
}

how to get a bluetooth's serail port name?

first thank you for the working of this project, really help me

but I hava question with it.

how to get a bluetooth's serail port name? instead of COMxx
in mac I get /dev/tty.XXXxxx but in windows i get only COM[1-9]

go get fails...

command:
go get github.com/bugst/go-serial

Error message:
package go.bug.st/serial/unixutils: unrecognized import path "go.bug.st/serial/unixutils" (parse https://go.bug.st/serial/unixutils?go-get=1: no go-import meta tags ())
go version:
go version go1.13.1 linux/arm

Serial.print() equivalent

This is more of an "advice please" post than an issue; so please advise if there is a better forum to post it on.

Is there an equivalent to https://www.arduino.cc/reference/en/language/functions/communication/serial/print/?

I've seen a few notes regarding the potential for framing errors using https://www.arduino.cc/reference/en/language/functions/communication/serial/write/ which I assume is analogous to https://github.com/bugst/go-serial/blob/master/serial.go#L25

As I understand print also sends a few more bytes than write - so I'm trying to think through how to handle that correctly on the Arduino which receives the data.

What approach would be advisable to try and send the same data as in this python example (hope the question makes sense; as appreciate there might not be a direct equivalent) https://forum.arduino.cc/index.php?topic=225329.msg1810764#msg1810764 there is an attached file
The python serial client has a method ser.write(sendStr) ComArduino2PY3.txt

Double Close() on the same port should be a no-op

If the user do a double Close() on the same port object the underlying handle is actually closed twice.
This may not be a problem when working with one Port object at a time, but it may result in problematic behavior in multi-threaded environments (in particular on unix where handles are reused this may result in the first object 'leaking' the handle).

Ideally the Close() method should return the PortClosed error if called twice.

Read() and Write() return -1 on error

Read() and Write() return -1 on error, while specs of io.Reader and io.Writer say the return value should be always >= 0. I am running macOS, but the same is true for Linux and BSD.

Here is an example that demonstrates the issue. I have a USB to serial converter (Arduino Mega2560)

package main

import sp "go.bug.st/serial.v1"
import "fmt"
import "time"

func main() {
	opts := &sp.Mode{
		BaudRate: 115200,
		DataBits: 8,
		StopBits: sp.OneStopBit,
	}
	rwc, err := sp.Open("/dev/cu.usbmodem1421", opts)
	if err != nil {
		panic(err)
	}
	var buf [128] byte
	for {

		n, err := rwc.Write([]byte{'?'})
		fmt.Println("Write", n, err)
		n, err = rwc.Read(buf[:])
		fmt.Println("Read", n, err)
		if err != nil {
			break
		}
		<-time.After(time.Second)
	}
}

After few seconds I unplug the USB cable

Output:

Write 1 <nil>
Read 41 <nil>
Write 1 <nil>
Read 14 <nil>
Write 1 <nil>
Read 85 <nil>
Write 1 <nil>
Read 72 <nil>
Write 1 <nil>
Read 57 <nil>
Write -1 device not configured
Read -1 device not configured

This makes a huge problem, for example when using the serial port with bufio.Scanner, unplugging the cable causes a panic

Timeouts

Hi,
I would like to know if it is possible to add timeouts on read/write operations. Either by setting a timeout value, or a deadline value.
Thanks.

Add API to check if port is alive

It would be nice to have a function on the Port that allows to check if the port is still alive.

It's already done in the Read() methods.

On Windows:

getCommState(port.handle, params)
if err := setCommState(port.handle, params); err != nil {
	port.Close()
	return 0, err
}

On Linux:

port.closeLock.RLock()
defer port.closeLock.RUnlock()
if !port.opened {
	return 0, &PortError{code: PortClosed}
}

fds := unixutils.NewFDSet(port.handle, port.closeSignal.ReadFD())
res, err := unixutils.Select(fds, nil, fds, -1)
if err != nil {
	return 0, err
}
if res.IsReadable(port.closeSignal.ReadFD()) {
	return 0, &PortError{code: PortClosed}
}

Single byte []byte{0x0f} is not transmitted

When I try to send a single byte of code 0x0F the data is not transmitted. Write function does not error.

Other single byte transmissions appear not to be affected, although I haven't tested exhaustively.
I have observed this behaviour on MacOS but haven't tried it on Windows or Linux.
This maybe a syscall issue?

README.md instructions for installing incomplete

After cloning, you cannot just run go test go.bug.st/serial.v1, since you may not have certain dependencies, like github.com/creack/goselect.
There should be another line, like go get -v go.bug.st/serial.v1 after cloning to fetch the other deps.

Support non-blocking mode

I would prefer to set a timeout for reading data instead of blocking till the connection get's closed.

Add PnP info and VID/PID to listing

For easier identification (well. any really :)) it would make sense to add VID/PID and PnP info to the listing when the serial port originates from USB (not legacy RS232).

If dev time is an issue, I'd be happy to give it a go.

BTW (offtopic) - might facchinm@3cfbd2f make the windows comm more stable?

Higher baud rate support

Running MacOS I can't seem to open a port at rates higher than 230,400 bps. I know the hardware is capable. I used the same port at 1,000,000 bps with a different go library. I like the functionality of go-serial better than the other library. It would be nice if go-serial supported higher rates.

ResetOutputBuffer/ResetInputBuffer fails on MacOS

	mode := &serial.Mode{
		BaudRate: 115200,
	}
	port, err := serial.Open("/dev/cu.usbserial-1410", mode)
	if err != nil {
		log.Fatal(err)
	}
	defer port.Close()

	if err := port.ResetOutputBuffer(); err != nil {
		log.Fatal(err)
	}
	if err := port.ResetInputBuffer(); err != nil {
		log.Fatal(err)
	}

Fails with bad address.

Tested on Catalina (0.15.7 (19H15)) and BigSur (11.0.1 (20B29)).
Versions checked: v1.1.1, v1.1.0, v1.0.0.

slow sends on Windows (USB)

Hello Cristian,

Your serial package is getting better and better all the time - first off, a huge thanks for creating this, covering all the platforms, and doing so in pure Go. As you may remember, I ran into an issue (#9) on macOS a while back, and am happy to report that it has been working charmingly ever since.

On Windows, there's still an issue we can't quite figure out - some details here, but that won't be very helpful yet, I'm afraid.

The behaviour is that communication is really slow - one line of text is sent, and then I need to wait for its echo and prompt coming back. This cycle repeats until an entire file is sent - it works quickly on Linux and Mac, but not on Windows.

Someone mentioned seeing this behaviour elsewhere, and that it might be related to hardware handshaking (this is USB, so all virtual). The USB device on the other end is custom-coded (not C), and completely ignores RTS/CTS etc, so I'm not really sure where to look next.

Anyway, just wanted to flag this here as placeholder, until we can figure out a bit more. The problem has been reported by at least two people, both Win10 AFAIK.

Cheers,
Jean-Claude

PS. Saw your new work on a new USB API - no rush, but I'm looking forward to seeing that in the main branch eventually. It means I could provide device info in the port selection menu I'm currently presenting in Folie. Fantastic work, all of it. Many thanks for taking it further and sharing it all.

Can't get data using win10

package main

import (
    "log"
    "time"
    "go.bug.st/serial"
)

func main() {
    mode := &serial.Mode{
        BaudRate: 115200,
    }
    port, err := serial.Open("COM4", mode)
    if err != nil {
        log.Fatal(err)
    }

    go func() {
        for {
            _, err := port.Write([]byte("get_down"))
            log.Println("send: ", "get_down")
            if err != nil {
                log.Fatal(err)
            }
            time.Sleep(time.Millisecond * 200)
        }
    }()

    go func() {
        for {
            buf := make([]byte, 128)
            log.Print("read...")
            n, err := port.Read(buf)
            log.Printf("read count[%d]\n", n)
            if err != nil {
                log.Fatal(err)
            }
            if n != 0 {
                log.Printf("recv: %s\n", string(buf[:n]))
            }
        }
    }()


    time.Sleep(time.Hour * 1)
}

this is my code,the results are as follows:

2020/01/14 11:17:52 read...
2020/01/14 11:17:52 send:  get_down
2020/01/14 11:17:52 send:  get_down
2020/01/14 11:17:52 send:  get_down
2020/01/14 11:17:52 send:  get_down
2020/01/14 11:17:53 send:  get_down
2020/01/14 11:17:53 send:  get_down
2020/01/14 11:17:53 send:  get_down
2020/01/14 11:17:53 send:  get_down
2020/01/14 11:17:53 send:  get_down
2020/01/14 11:17:54 send:  get_down
2020/01/14 11:17:54 send:  get_down
2020/01/14 11:17:54 send:  get_down
2020/01/14 11:17:54 send:  get_down
2020/01/14 11:17:54 send:  get_down
2020/01/14 11:17:55 send:  get_down
2020/01/14 11:17:55 send:  get_down
..........................................

The normal situation is that every get_down will respond to down done:

send:  get_down
read...
read count[9]
recv: down done
send:  get_down
read...
read count[9]
recv: down done
send:  get_down
read...
read count[9]
recv: down done
send:  get_down
read...
read count[9]
recv: down done
.........

In the same operating environment (system, serial port, serial device), can get correct results by sending get_down with java.

Reading error on windows

Hello,
using this library on windows, I encountered an error on reading. I know for sure that there is something to read, but the Read method is blocking (even after the read timeout is elapsed) and it never returns. After a debug session, I found out that it's waiting for overlapped I/O to complete (here) that apparently never happens.
Here's my code:

mode := &serial.Mode{
		BaudRate: 115200,
		Parity:   serial.OddParity,
		DataBits: 8,
		StopBits: serial.TwoStopBits,
	}

port, err := serial.Open("COM1", mode)
n, err := port.Write([]byte("data\r"))
if err != nil {
	log.Fatal(err)
}
fmt.Printf("Sent %v bytes\n", n)

buff := make([]byte, 1024)
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]))
	fmt.Println(n)
}

Am I doing something wrong?

Also I found out that on handle creation (here), passing 0 instead of syscall.FILE_FLAG_OVERLAPPED, will make Read work.

go.bug.st returning 404

Hi @cmaglie and all, it appears that go.bug.st is down and I am not able to pull packages. A few colleagues are also seeing 404's when visiting https://go.bug.st. Hopefully this issue helps bring some awareness to it.

Thanks all!

No longer compiles under macOS due to dependency problem

Since golang.org/x/sys/unix was being updated regularly, the following error occurs when compiling under macOS:

zsyscall_darwin.go:16:27: undefined: unix.SYS_IOCTL

This is due to golang/sys@6fcdbc0 removing all the SYS_* constants, the reason being that direct syscalls under Darwin are no longer supported.

Is there a fix for this?

EDIT: The temporary workaround for this problem is adding this line to the project's go.mod to use an older version of golang.org/x/sys/unix:

replace golang.org/x/sys => golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6

But this is not a long-term solution.

Syscall: project file organisation proposal/discussion

So, about albenik/go-serial@68d334c

My motivation is simple. Currently I very active using go-serial (thanks!) in my current work. I working with many vending devices, where I have often switch read timeouts while single packet read operation. So I have to implement some new methods peeped in the project https://github.com/pyserial/pyserial (it's only for windows yet, I plans to complete work and propose it to you)

While I learning and comparing both pyserial and go-serial and looking for simplest way to port code, it was very difficult for me finding syscall definitions scattered throughout the code. Also It was difficult for me to choose a place for new syscalls.
My be if you project fresh for you, and as author you keep in mind design features it's easy. But for me it was difficult. I talks predominantly windows syscalls of course, not for single unix ioctl

Therefore I propose to consolidate syscall definitions. There is two way:

  1. Put it to one place in serial_* files
  2. Put it to separated files like in syscall package

I choose second way, because I think it's generic apporoach. And it's possible more common for any new people which will want to commit in you prtoject.

support darwin arm64

This package should support darwin arm64.

From the looks of it the fix could be done by removing the build constraint to only support amd64 and x86.

Read crashes on closed handle, Windows

Read() methods crashes on Windows in the (#13) scenario:

Port opened
goroutine: reading
Port closing
Exception 0xc0000008 0x0 0x0 0x7ffb7b06e78a
PC=0x7ffb7b06e78a

syscall.Syscall(0x7ffb7a5c0a20, 0x1, 0x130, 0x0, 0x0, 0x0, 0x0, 0x0)
	.../golang/src/runtime/syscall_windows.go:172 +0xc6
Port closed
syscall.CloseHandle(0x130, 0x0, 0x0)
	.../golang/src/syscall/zsyscall_windows.go:353 +0x71
go.bug.st/serial%2ev1.(*windowsPort).Close(0xc00004e200, 0x0, 0x0)
	.../go/src/go.bug.st/serial.v1/serial_windows.go:58 +0x3f
go.bug.st/serial%2ev1.(*windowsPort).Read(0xc00004e200, 0xc0000b6000, 0x3e8, 0x3e8, 0x0, 0x0, 0x0)
	.../go/src/go.bug.st/serial.v1/serial_windows.go:97 +0x3f2
main.main.func1(0x54b180, 0xc00004e200)
	.../src/test.go:90 +0x147
created by main.main
	.../src/test.go:87 +0xc96

goroutine 1 [syscall, locked to thread]:
syscall.Syscall(0x7ffb7a5c0a20, 0x4490ab, 0xc000075a08, 0x4490ab, 0xc000000008, 0x53df70, 0x608520, 0x0)
	.../golang/src/runtime/syscall_windows.go:172 +0xc6
runtime: unexpected return pc for syscall.CloseHandle called from 0x608520
stack: frame={sp:0xc0000759a8, fp:0xc000075a20} stack=[0xc00006e000,0xc000076000)
000000c0000758a8:  0000000000000001  0000000000000000 
000000c0000758b8:  0000000000000000  0000000000515600 
000000c0000758c8:  000000c00008e101  000102000043c495 
000000c0000758d8:  0000000000000008  0000000000000008 
000000c0000758e8:  000000c0000c4000  00000000006079a0 
000000c0000758f8:  0000000000000000  0000000000000010 
000000c000075908:  0000000000608100  0000000000140d40 
000000c000075918:  0000000000000000  000000000000000c 
000000c000075928:  000000c00008e100  000000c000075960 
000000c000075938:  00000000004b5820 <fmt.(*pp).free+192>  000000c0000759b8 
000000c000075948:  00000000004403d7 <runtime.growslice+567>  000000c0000c4000 
000000c000075958:  0000000000000000  0000000000000000 
000000c000075968:  0000000000437adc <runtime.newproc+140>  000000c000075988 
000000c000075978:  0000000000000008  000000c0000759d8 
000000c000075988:  0000000000455610 <runtime.newproc.func1+0>  000000c0000759d0 
000000c000075998:  000000c0000759d8  0000000000000008 
000000c0000759a8: <000000c000002180  00000000004490ab <runtime.(*timersBucket).addtimerLocked+283> 
000000c0000759b8:  000000c000075a08  00000000004490ab <runtime.(*timersBucket).addtimerLocked+283> 
000000c0000759c8:  000000c000000008  000000000053df70 
000000c0000759d8:  0000000000608520  0000000000000000 
000000c0000759e8:  0000000000000001  000000c0000c4000 
000000c0000759f8:  0000000000000000  0000000000000001 
000000c000075a08:  000000c000075a48  0000000000448e1a <time.Sleep+266> 
000000c000075a18: !0000000000608520 >000000c00004a200 
000000c000075a28:  0000000000000000  0000000000608520 
000000c000075a38:  000000c00004a200  000000c000002180 
000000c000075a48:  000000c000075f88  00000000004f840d <main.main+3773> 
000000c000075a58:  000000012a05f200  0000000000000001 
000000c000075a68:  0000000000000001  000000000000000c 
000000c000075a78:  0000000000000000  0000000000000000 
000000c000075a88:  0000000000000000  0000000000000000 
000000c000075a98:  0000000000000002  0000000000000002 
000000c000075aa8:  0000000000000002  0000000000000002 
000000c000075ab8:  0000000000000002  0000000000000002 
000000c000075ac8:  0000000000000000  0000000000000000 
000000c000075ad8:  0000000000000000  0000000000000000 
000000c000075ae8:  000000c0000821e0  000000c000075c90 
000000c000075af8:  0000000000030000  0000000002030000 
000000c000075b08:  000000c000075cb0  000000c000075cc0 
000000c000075b18:  0203000000000000 
syscall.CloseHandle(0xc00004a200, 0x0, 0x608520)
	...golang/src/syscall/zsyscall_windows.go:353 +0x71
rax     0x7ffb78369a9a
rbx     0x130
rcx     0x201f840
rdi     0x2e7000
rsi     0xc0000afcf8
rbp     0xc0000afca0
rsp     0x201fd50
r8      0x1
r9      0x2e7000
r10     0x7ffb7afd83d0
r11     0x201f830
r12     0x2030000
r13     0x0
r14     0x20
r15     0xc000032ad8
rip     0x7ffb7b06e78a
rflags  0x200
cs      0x33
fs      0x53
gs      0x2b

Seems like all what have to be done to fix it is to remove port.Close() from line 97 in go.bug.st\serial.v1\serial_windows.go:

		getCommState(port.handle, params)
		if err := setCommState(port.handle, params); err != nil {
			port.Close() // <--
			return 0, err
		}

Reading too few bytes

I'm trying to read from a serial connection to a RS485 bus and the messages are 6 bytes in length. But for some reason I end up only getting 5 bytes out from the serial connection at a time. I tried using a Python library to quickly test the connection out and that seems to properly get me 6 bytes, but that also has a parameter for the Read function that can specify how many bytes should be read. Is this possible with this library? And how does it determine when it has read enough bytes from the serial connection and returns from Read?

Add RS485 port options

Some time back I added RS485 support to the jacobsa/go-serial package:

jacobsa/go-serial@53b6b26

Is there interest in having similar functionality in this package? If so, how do you envision the RS485 options being configured? Options I can see are:

  • add a SetRS485Mode() function to the Port interface
  • add additional fields to the Mode struct.

Getting garbled text in Windows serial port

Hi there,

I'm using this library via Faccinm's version for the Arduino.cc Web IDE Bridge which is actually using Serial Port JSON Server. However, since I've moved to this library I'm getting garbled text on Windows. On Linux I don't get any problems. Have you seen this problem before or am I blazing new territory here such that I'm the first to see it?

image

The project using your code is:
https://github.com/arduino/serial-port-json-server

My project is:
https://github.com/johnlauer/serial-port-json-server

I used to use this serial library.
https://github.com/johnlauer/goserial

The old serial lib did have port closing problems and your library doesn't, which is awesome, but I never got garbled text with the other library. Is it possible just default settings are off? I've tried lots of tweaking to parity and stop bits to no avail.

Thanks,
John

Support for OpenBSD?

Greetings. I previously built a small application in Go for a hardware controller using tarm/serial. It worked well on OS X, but switching to OpenBSD/amd64 made it pretty clear that that wasn't a supported platform (reading stale data, reading unexpected linefeed characters, writes appearing to go missing). My needs are fairly simple, I connect to a "FTDI FT232R USB UART" device, write 2-3 bytes, and read one byte back.

This seemed like the most active Go serial port project, so I figured I'd drop a note. How can I help add OpenBSD support? I skimmed the FreeBSD files, but it was mostly Greek to me. I have plenty of OpenBSD systems to test against, though.

Thanks.

trying out the USB enumerator

Hey Cristian,

I'm trying out your new USB code on macOS/64b w/ Go 1.7.5 and get this compiler message:

~/G/s/g/s/enumerator (v1|✔) $ go test
# go.bug.st/serial.v1/enumerator
./usb_darwin.go:25: undefined: PortError
./usb_darwin.go:32: undefined: PortError
FAIL	go.bug.st/serial.v1/enumerator [build failed]

Anything I can do to get past this hurdle? ("wait" is also fine with me...)

Cheers,
-jcw

Cannot install via "go get go.bug.st/serial" with Go 1.5.1

go get -v go.bug.st/serial outputs:

https fetch failed.
import "go.bug.st/serial": https fetch: Get https://go.bug.st/serial?go-get=1: tls: first record does not look like a TLS handshake
package go.bug.st/serial: unrecognized import path "go.bug.st/serial"

go version:

go version go1.5.1 darwin/amd64

Work around for now: go get -insecure -v go.bug.st/serial

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.