Coder Social home page Coder Social logo

libserialport.jl's Introduction

LibSerialPort.jl

libserialport is a small, well-documented C library for general-purpose serial port communication. This is a julia wrapper for the library.

Apart from a very few non-essential functions, the entire library API (about 75 functions) is wrapped using ccall. In addition, a higher-level interface is also provided that follows Julia's IO stream interface.

Installation

pkg> add LibSerialPort

Usage

Try

julia> using LibSerialPort
julia> list_ports()  # or get_port_list() for an array of names

The examples/ directory contains a simple serial console for the command line. This may serve as a useful starting point for your application. The serial_example.ino sketch can be flashed to a microcontroller supported by the Arduino environment.

using LibSerialPort

# Modify these as needed
portname = "/dev/ttyS0"
baudrate = 115200

# Snippet from examples/mwe.jl
LibSerialPort.open(portname, baudrate) do sp
	sleep(2)

	if bytesavailable(sp) > 0
    	println(String(read(sp)))
	end

    write(sp, "hello\n")
    sleep(0.1)
    println(readline(sp))
end

The tests are also worth looking at for demonstration of i/o and configuration. They can be run via julia test/runtests.jl <address> <baudrate>. Unless the address of your device matches that in runtests.jl, doing pkg> test LibSerialPort will fail. This problem would be addressed by support for args in the Pkg REPL.

Note that on Windows, returning an OS-level port handle is not yet supported.

libserialport.jl's People

Contributors

andrewadare avatar bjack205 avatar dependabot[bot] avatar ianbutterworth avatar juliatagbot avatar mattettus avatar mgkuhn avatar octogonapus avatar ranocha avatar reubenhill avatar samuelpowell avatar scls19fr avatar sjkelly avatar tknopp avatar yakir12 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

Watchers

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

libserialport.jl's Issues

lose data when read binary data !

Same problem happens as PR #61 (branch: ams/fix-read-methods). I meet some strange problems. I've made couple tests:

A. send binary data (such .jpg ) to serial A Tx, which connect to serial B Rx
B . send binary data (such .jpg ) to serial A Tx, which connect to serial A Rx
The function readuntil() (read() or nonblocking_read() in branch: ams/fix-read-methods) from Rx port (for both A and B test) will lose one byte every 1023 bytes received, or lose the last byte if I send less than 1024 bytes.

For example, If I send 1024 bytes (raw) to Tx, I got 1023 bytes from Rx port.
If I send 2048 bytes to Tx, I got 2046 bytes from Rx port !
If I send 100 bytes to Tx, I got 99 bytes from Rx port !
This strange problem happens no matter how much baudrate I set, e.g, 115200,921600.
BTW: The software cutecom test binary file send and receive without any problem for above hardware setup !

If I send a pure text file (all ASCII) to Tx, the above problem is gone!

[new test] function sp_blocking_read() : SAME problem: lose one byte every 1023 bytes received, or lose the last byte if less than 1024 bytes was sent !

Type piracy with `Base.open`

I was just adapting some of my code to use the newest release and I noticed that there appears to be some type piracy with extending Base.open. Specifically it gets extended with

[12] open(portname::AbstractString, baudrate::Integer; mode, ndatabits, parity, nstopbits) in LibSerialPort at C:\Users\db9052\.julia\packages\LibSerialPort\zyrgR\src\LibSerialPort.jl:456

which doesn't use any types defined by LibSerialPort (hence the piracy). While I can see that this is a convenience function (and currently doesn't cause problems), it's probably better not to do it since a string and an integer as inputs is quite generic.

An alternative might be to introduce a string macro/lightweight struct such that you can do

open(sp"/dev/ttyUSB0", 9600)

I'd be happy to add the required code if that would help.

Test fails for `test_high_level_api(port, baudrate) == nothing`

How to reproduce with Julia 1.4 .0 on Ubuntu Linux 18.04:

(@v1.4) pkg> add LibSerialPort
(@v1.4) pkg> status LibSerialPort
Status `~/.julia/environments/v1.4/Project.toml`
  [a05a14c7] LibSerialPort v0.3.0
(@v1.4) pkg> test LibSerialPort
[...]
Usage: test-high-level-api.jl port baudrate
Available ports:
/dev/ttyS0
	Description:	ttyS0
	Transport type:	SP_TRANSPORT_NATIVE
Usage: test-high-level-api.jl port baudrate
Available ports:
/dev/ttyS0
	Description:	ttyS0
	Transport type:	SP_TRANSPORT_NATIVE

Port name:	/dev/ttyS0
Manufacturer:	
Product:	
USB serial number:	
Bluetooth address:	
File descriptor:	20
┌ Warning: Port does not use USB transport
└ @ LibSerialPort ~/.julia/packages/LibSerialPort/xvkkM/src/wrap.jl:217
High level API: Error During Test at ~/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:38
  Test threw exception
  Expression: test_high_level_api(port, baudrate) == nothing
  MethodError: no method matching iterate(::Nothing)
  Closest candidates are:
    iterate(!Matched::Core.SimpleVector) at essentials.jl:603
    iterate(!Matched::Core.SimpleVector, !Matched::Any) at essentials.jl:603
    iterate(!Matched::ExponentialBackOff) at error.jl:253
    ...
  Stacktrace:
   [1] indexed_iterate(::Nothing, ::Int64) at ./tuple.jl:84
   [2] print_port_metadata(::Ptr{LibSerialPort.SPPort}; show_config::Bool) at ~/.julia/packages/LibSerialPort/xvkkM/src/high-level-api.jl:167
   [3] print_port_metadata(::SerialPort; show_config::Bool) at ~/.julia/packages/LibSerialPort/xvkkM/src/high-level-api.jl:155
   [4] print_port_metadata at ~/.julia/packages/LibSerialPort/xvkkM/src/high-level-api.jl:155 [inlined]
   [5] test_high_level_api(::String, ::Vararg{String,N} where N) at ~/.julia/packages/LibSerialPort/xvkkM/test/test-high-level-api.jl:86
   [6] top-level scope at ~/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:38
   [7] top-level scope at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/Test/src/Test.jl:1113
   [8] top-level scope at ~/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:36
   [9] top-level scope at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/Test/src/Test.jl:1113
   [10] top-level scope at ~/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:28
  
Test Summary:    | Pass  Error  Total
LibSerialPort    |    3      1      4
  Low level API  |    2             2
  High level API |    1      1      2
ERROR: LoadError: Some tests did not pass: 3 passed, 0 failed, 1 errored, 0 broken.
in expression starting at ~/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:14
ERROR: Package LibSerialPort errored during testing

Merge or split high-level and low-level API

This suggestion would be a big breaking change, but possibly worth it.

I believe LibSerialPort would become far more user friendly if we merged the high-level and low-level APIs. The resulting single API is closer to the current high-level API, in that almost all methods in it have a first argument of type LibSerialPort.SerialPort (or the IO supertype), but it also provides all the advanced facilities currently only found in the low-level API.

  • Users of the high-level interface will often want to have access to many of the methods of the low-level interface (e.g., draining buffers, accessing modem control lines, etc.). But duplicating large parts of the low-level interface in the high-level interface could leads to duplication of code, documentation and tests.

  • It is much more user friendly if there is only one documented function for each purpose, and that function should copy an adapted version of most of the text found in the documentation of the corresponding libserialportfunction (such that LibSerialPort users do not have to read the libserialport C documentation).

  • New users should not have to be confronted with first having to make a choice between using one of two APIs, unless there are extremely good technical reasons for having to make such a choice (which I doubt we have here).

flush versus drain

It seems the verbs “flush” and “drain” are used differently in Julia and libserialport, and LibSerialPort.jl 0.4.0 got caught in between:

In Julia (as with libc's fflush), flush() ensures that all data written by the user to a stream is actually handed over to the operating-system kernel via a system call. This function is mainly intended for stream implementations that buffer written data in user space such that a large number of user-space writes do not result in a large number of kernel context switches.

In libserialport, sp_flush instead resets the input or output buffers (as does POSIX's tcflush()), discarding any bytes still waiting in them. That is very different from Julia's flush, which does not discard any data.

Since libserialport does not implement its own user-space buffers, it has no exact equivalent to Julia's flush(). The closest analog that libserialport has is probably sp_drain() (like POSIX's tcdrain()), which waits until until all bytes have left the UART and the output buffer has become empty.

We could perhaps set

flush(sp::SerialPort) = sp_drain(sp.ref)

instead of calling sp_flush in flush(sp::SerialPort, ...).

Or, perhaps more cleanly, we could not implement a flush() function at all in the high-level interface (as we have no exact equivalent), and just pass through the two sp_flush() and sp_drain() functions from the low-level interface directly.

Julia 1.0

Hello Andrew,

related to #14 with Julia 0.7

julia> readstring(IOBuffer())
┌ Warning: `readstring(s::IO)` is deprecated, use `read(s, String)` instead.
│   caller = top-level scope at none:0
└ @ Core none:0

it's still broken with Julia 1.0 when doing

using LibSerialPort

Kind regards

`OS error code 5: Input/output` error on ubuntu

Test errors on master. Ubuntu 18.04. User in the dialout group.

...
/dev/ttyUSB0
    Description:    xxxxxx USB Device - xxxx
    Transport type: SP_TRANSPORT_USB
OS error code 5: Input/output error
Low level API: Error During Test at /home/ian/GitHub/LibSerialPort.jl/test/runtests.jl:31
  Test threw exception
  Expression: test_low_level_api(port, baudrate) == nothing
  From /home/ian/GitHub/LibSerialPort.jl/src/wrap.jl: 141:
  
  libserialport returned SP_ERR_FAIL - Host OS reported a failure.
  Stacktrace:
   [1] error(::String) at ./error.jl:33
   [2] handle_error(::SPReturn, ::String) at /home/ian/GitHub/LibSerialPort.jl/src/wrap.jl:136
   [3] sp_open at /home/ian/GitHub/LibSerialPort.jl/src/wrap.jl:185 [inlined]
   [4] test_low_level_api(::String, ::Vararg{String,N} where N) at /home/ian/GitHub/LibSerialPort.jl/test/test-low-level-api.jl:226
   [5] top-level scope at /home/ian/GitHub/LibSerialPort.jl/test/runtests.jl:31
   [6] top-level scope at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.3/Test/src/Test.jl:1107
   [7] top-level scope at /home/ian/GitHub/LibSerialPort.jl/test/runtests.jl:29
   [8] top-level scope at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.3/Test/src/Test.jl:1107
   [9] top-level scope at /home/ian/GitHub/LibSerialPort.jl/test/runtests.jl:28
  
...
  
Test Summary:    | Pass  Error  Total
LibSerialPort    |    2      2      4
  Low level API  |    1      1      2
  High level API |    1      1      2
error in running finalizer: ErrorException("From /home/ian/GitHub/LibSerialPort.jl/src/wrap.jl: 141:

libserialport returned SP_ERR_ARG - Function was called with invalid arguments.")
ERROR: LoadError: Some tests did not pass: 2 passed, 0 failed, 2 errored, 0 broken.
in expression starting at /home/ian/GitHub/LibSerialPort.jl/test/runtests.jl:14
ERROR: Package LibSerialPort errored during testing

Build issues on OS X

I've used this package to build a simple GUI controlling a LED strip from an Arduino for our lab (see code here). Everything works fine, except for one user who has Mojave 10.14.3. She does not have the usual build-tools installed on her machine to ] build LibSerialPort. Apart from googling solutions, is there a nifty way to take care of such issues, or did I miss some simple trick?

I realize and recognize that this does not have to do with LibSerialPort specifically.

no method matching readline(::SerialPort, ::Float64)

Hi there,

the first example with timeouts is broken in Julia 1.3, Linux 64bit.

using LibSerialPort
LibSerialPort.open("/dev/ttyACM0", 115200) do s
    ret = readline(s, 1.0) #try to readline with a 1 second timeout
    @show ret
end
ERROR: LoadError: MethodError: no method matching readline(::SerialPort, ::Float64)
Closest candidates are:
  readline(::IO; keep) at io.jl:454

readuntil(s, '\n', 1.0) still works, so its not a big deal.

Cheers,
Andi

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

Improve testing / continuous integration

Hello,

it will be nice to improve testing of this library.

You could:

  • Add a test/runtests.jl file like most Julia package does

with

using LibSerialPort
using Test

include("test-low-level-api.jl")
include("test-high-level-api.jl")

It will at least insure that this library can be built.

  • Enable code coverage (for perfectionists)

You should probably create a dummy package using the new package manager (Pkg3) and Pkg REPL-mode because PkgDev doesn't seems to work anymore with Julia 0.7 JuliaLang/PkgDev.jl#143
Creating this dummy package will give you example of all useful files (.travis.yml, appveyor.yml, Project.toml ... ).

Kind regards

Templatize parameter type of `readuntil` (to be able to change Char to UInt8)

Hello,

https://github.com/andrewadare/LibSerialPort.jl/blob/61674ec9a8054b46f02fa8a6a2688c7743ef3feb/src/high-level-api.jl#L377-L396

uses Char

I was using this function to read response message from a Nextion screen with a USB TTL converter but received message wasn't as expected.

Here is my code

using LibSerialPort


v_uint8_eoc = [0xff, 0xff, 0xff]  # Array{UInt8,1}
v_char_eoc = Char.([0xff, 0xff, 0xff])  # Array{Char,1} ['ÿ', 'ÿ', 'ÿ']
s_eoc = String(copy(v_uint8_eoc))  # "\xff\xff\xff"

function _format_command(cmd)
    cmd * s_eoc
end

port = "/dev/ttyUSB0"
baudrate = 9600

sp = open(port, baudrate)

cmd = "sendme"
cmd = _format_command(cmd)
write(sp, cmd)

function my_readuntil(sp::SerialPort, delim::AbstractString, timeout_ms::Real)
   return String(take!(readuntil(sp, Vector{Char}(delim), timeout_ms)))
end

function my_readuntil(sp::SerialPort, delim::Vector{T}, timeout_ms::Real) where {T}
    start_time = time_ns()
    out = Vector{T}()
    lastchars = T[0 for i=1:length(delim)]
    while !eof(sp)
        if (time_ns() - start_time)/1e6 > timeout_ms
            break
        end
        if bytesavailable(sp) > 0
            c = read(sp, T)
            push!(out, c)
            lastchars = circshift(lastchars,-1)
            lastchars[end] = c
            if lastchars == delim
                break
            end
        end
    end
    return out
end

timeout_ms = 4000


#s = readuntil(sp, s_eoc, timeout_ms)
#println(s)
#r = transcode(UInt8, s)
#println(r)

#r = my_readuntil(sp, v_char_eoc, timeout_ms)
#println(r)

r = my_readuntil(sp, v_uint8_eoc, timeout_ms)
println(r)

With your readuntil function I get:

┌ Warning: `convert(::Type{Vector{Char}}, s::AbstractString)` is deprecated, use `Vector{Char}(s)` instead.
│   caller = readuntil(::SerialPort, ::String, ::Int64) at high-level-api.jl:374
└ @ LibSerialPort ~/.julia/dev/LibSerialPort/src/high-level-api.jl:374
fÿÿÿ
UInt8[0x66, 0x00, 0xc3, 0xbf, 0xc3, 0xbf, 0xc3, 0xbf]

but with mine I get:

UInt8[0x66, 0x00, 0xff, 0xff, 0xff]

or

Char['f', '\0', 'ÿ', 'ÿ', 'ÿ']

Which is the correct answer.

Kind regards

PS : #23 is a related issue

Method ambiguity in read()

@hofmannmartin after merging your PR #4, I see the following error when running e.g. examples/console.jl:

ERROR (unhandled task failure): MethodError: read(::LibSerialPort.SerialPort, ::Type{UInt8}) is ambiguous. Candidates:
  read(s::IO, ::Type{UInt8}) at io.jl:40
  read(sp::LibSerialPort.SerialPort, T::Union{Type{Char},Type{UInt8}}) at /Users/adare/.julia/v0.5/LibSerialPort/src/high-level-api.jl:309
 in readuntil(::LibSerialPort.SerialPort, ::UInt8) at ./io.jl:294
 in readuntil(::LibSerialPort.SerialPort, ::Char) at ./io.jl:278
 in (::##4#8{LibSerialPort.SerialPort})() at ./task.jl:360

I'm a bit puzzled by this because issubtype(LibSerialPort.SerialPort, IO) is true, so I would expect no trouble with dispatching to the correct method.

function to output array of available ports

There currently isn't a way (that I can find) to obtain the list of ports. list ports() prints them to the REPL but doesn't return them in any way for a function to do further processing. Would it be possible to add a function or add this functionality to list_ports?

I'd be happy to help but I don't quite know how the internals with ptrs and refs works.

Cannot open a Linux device via a symbolic link

As Linux assigns the digits in /dev/ttyUSB0, /dev/ttyUSB1, etc. dynamically, it can be very useful to instead open a serial-port device via the symbolic links with more persistent names that Linux offers in /dev/serial/by-id/ or /dev/serial/by-path/, e.g.

$ ls -l /dev/serial/by-id/
[...] usb-Digilent_Digilent_USB_Device_210321A6A8A3-if00-port0 -> ../../ttyUSB1
[...] usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 -> ../../ttyUSB0

Unfortunately, it seems sp_get_port_by_name() does not like symbolic links (on Ubuntu Linux 18.04 x86_64, Julia 1.4.1):

$ julia test/test-high-level-api.jl /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 115200
ERROR: LoadError: libserialport returned SP_ERR_ARG - Function was called with invalid arguments.
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] check(::SPReturn) at /home/mgk25/.julia/dev/LibSerialPort/src/wrap.jl:138
 [3] sp_get_port_by_name at /home/mgk25/.julia/dev/LibSerialPort/src/wrap.jl:144 [inlined]
 [4] SerialPort(::String) at /home/mgk25/.julia/dev/LibSerialPort/src/high-level-api.jl:23
 [5] open(::String, ::Int64; mode::SPMode, ndatabits::Int64, parity::SPParity, nstopbits::Int64) at /home/mgk25/.julia/dev/LibSerialPort/src/high-level-api.jl:277
 [6] open at /home/mgk25/.julia/dev/LibSerialPort/src/high-level-api.jl:277 [inlined]

Looking at the C function sp_get_port_by_name() in serialport.c, that does appear to call realpath() to resolve symlinks, but only if the flag HAVE_REALPATH is set.

So I now wonder whether HAVE_REALPATH wasn't set when the version of libserialport that I got was compiled.

LibSerialPort/Project.toml contains the lines

[deps]
libserialport_jll = "220460dc-b50e-5ed0-8176-09b0fd261e90"
[compat]
libserialport_jll = "0.1.1"

and I don't have the Ubuntu 18.04 package libserialport0 installed, so I'm probably using a JLL “artifact”, right? (Installing the Ubuntu 18.04 package libserialport0 made no difference either.)

It appears so:

$ nm ~/.julia/artifacts/939cdd32e306775f4c57d49341082a747bb8b561/lib/libserialport.so | grep real
                 U realloc@@GLIBC_2.2.5
$

Reaquire a port by id

A common situation I've encountered: I have the port name (i.e. as a String, e.g. "/dev/serial/by-id/usb-Arduino__www.arduino.cc__0043_95735353032351F0F0F0-if00"), I open it, do stuff with the SerialPort object, and then for various reasons I "lose" the SerialPort object. I then have no means of reacquiring it. In fact, the only real option I have is to restart the Julia session and get it by name again.

One way would be for me to keep my own record of the SerialPort object (like a const Ref of the object) and maintain it that way. But perhaps it would be better if that functionality existed in LibSerialPort.jl. Simply put, just like there is an open port function that accepts the port name as a string, there should be a close function that accepts the port name as a string (and not just as a SerialPort).

`readline()` example in README.md does not work

How to reproduce with Julia 1.4.0 on Ubuntu Linux 18.04 (x86_64):

using LibSerialPort
port="/dev/ttyS0"

LibSerialPort.open(port, 115200) do s
    write(s, "input")
    ret = readline(s, 1.0) #try to readline with a 1 second timeout
    @show ret
end

This results in

ERROR: MethodError: no method matching readline(::SerialPort, ::Float64)
Closest candidates are:
  readline(::IO; keep) at io.jl:454

Thread safety

The libserialport documentation says under “Thread safety”:

“Certain combinations of calls can be made concurrently, as follows.

  • Calls using different ports may always be made concurrently, i.e. it is safe for separate threads to handle their own ports.
  • Calls using the same port may be made concurrently when one call is a read operation and one call is a write operation, i.e. >it is safe to use separate "reader" and "writer" threads for the same port. See below for which operations meet these >definitions.

Read operations: sp_blocking_read(), sp_blocking_read_next(), sp_nonblocking_read(), sp_input_waiting(), sp_flush() with SP_BUF_INPUT only, sp_wait() with SP_EVENT_RX_READY only.

Write operations: sp_blocking_write(), sp_nonblocking_write(), sp_output_waiting(), sp_drain(), sp_flush() with SP_BUF_OUTPUT only, sp_wait() with SP_EVENT_TX_READY only.

If two calls, on the same port, do not fit into one of these categories each, then they may not be made concurrently.”

Julia has claimed thread safety for its I/O operations since release 1.3, so I wonder if we shouldn't aim to ensure the same for LibSerialPort.

To enforce the constraints required above, e.g. for applications where multiple threads send data to the same serial port, we could add to the SerialPort type two new ReentrantLock members:

rlock::ReentrantLock
wlock::ReentrantLock

each to be initialized with ReentrantLock(). And then each call to one of the read operations above will have to be enclosed with corresponding lock(rlock) and unlock(rlock) methods, and equivalently with wlock for the write operations.

ERROR: LoadError: ArgumentError: LibSerialPort not found in path

I am having troubles with LibSerialPort or at least I think this error is telling me:

ERROR: LoadError: ArgumentError: LibSerialPort not found in path
 in require at ./loading.jl:233
 in include at ./boot.jl:261
 in include_from_node1 at ./loading.jl:304
 in process_options at ./client.jl:280
 in _start at ./client.jl:378

I went through all of the information to get libserialport installed from http://sigrok.org/wiki/Libserialport.
No errors happened during the compile process, except for missing compiler tools.
make and make install completed without errors.

Here is the information when I fired up julia:

              _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.4.2 (2015-12-06 21:47 UTC)
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org release
|__/                   |  x86_64-linux-gnu




julia> Pkg.build("LibSerialPort")

INFO: Building LibSerialPort

julia> 

julia> using LibSerialPort
ERROR: ArgumentError: LibSerialPort not found in path
 in require at ./loading.jl:233

julia> readdir(joinpath(Pkg.dir("LibSerialPort"), "deps/usr/lib"))
6-element Array{ByteString,1}:
 "libserialport.a"       
 "libserialport.la"      
 "libserialport.so"      
 "libserialport.so.0"    
 "libserialport.so.0.1.0"
 "pkgconfig"      

Julia 0.7 / Julia 1.0

Hello,

With Julia 0.7 I get the following warnings

julia> using LibSerialPort
[ Info: Precompiling LibSerialPort [8d099cbf-8da3-5ec2-a1c2-df122ad121d3]
┌ Warning: Package LibSerialPort does not have Libdl in its dependencies:
│ - If you have LibSerialPort checked out for development and have
│   added Libdl as a dependency but haven't updated your primary
│   environment's manifest file, try `Pkg.resolve()`.
│ - Otherwise you may need to report an issue with LibSerialPort
└ Loading Libdl into LibSerialPort from project dependency, future warnings for LibSerialPort are suppressed.
WARNING: importing deprecated binding Base.Void into LibSerialPort.
WARNING: Base.Void is deprecated, use Nothing instead.
  likely near /home/scls/.julia/dev/LibSerialPort/src/wrap.jl:125
WARNING: Base.Void is deprecated, use Nothing instead.
  likely near /home/scls/.julia/dev/LibSerialPort/src/wrap.jl:148
┌ Warning: `is_windows` is deprecated, use `Sys.iswindows` instead.
│   caller = top-level scope at none:0
└ @ Core none:0
WARNING: Base.Void is deprecated, use Nothing instead.
  likely near /home/scls/.julia/dev/LibSerialPort/src/wrap.jl:277
WARNING: Base.Void is deprecated, use Nothing instead.
  likely near /home/scls/.julia/dev/LibSerialPort/src/wrap.jl:713

Kind regards

REPL crash code 3221226356 when `sp_free_port` twice

In a REPL calling sp_free_port twice on the same port causes a crash in 64 bit Julia:

using LibSerialPort

Main> sp_ref = sp_get_port_by_name("COM4")
Ptr{LibSerialPort.SPPort} @0x000000000fff7090

Main> sp_free_port(sp_ref)

Main> sp_free_port(sp_ref)

REPL crashes with code 3221226356.

@async behavior

using LibSerialPort

list_ports()
ports = get_port_list()

sp = LibSerialPort.open(ports[1], 115200)
set_flow_control(sp)
sp_flush(sp, SP_BUF_BOTH)

@async while isopen(sp)
    while bytesavailable(sp) > 0
        data = readline(sp)
        println(stdout,  "read :$data")
    end
end

I don't know why this blocked REPL. How can I keep receiving while running other codes.

list_ports() throws SP_ERR_MEM on Linux Arm64

Any idea why the Travis CI checks fail for Linux Arm64 (e.g. in #74)?

$ julia --check-bounds=yes --color=yes -e "if VERSION < v\"0.7.0-DEV.5183\"; Pkg.test(\"${JL_PKG}\", coverage=true); else using Pkg; Pkg.test(coverage=true); end"
   Testing LibSerialPort
 Resolving package versions...
LibSerialPort CI port listing: Error During Test at /home/travis/build/JuliaIO/LibSerialPort.jl/test/runtests.jl:21
  Got exception outside of a @test
  libserialport returned SP_ERR_MEM - Memory allocation failed.
  Stacktrace:
   [1] error(::String) at ./error.jl:33
   [2] check(::SPReturn) at /home/travis/build/JuliaIO/LibSerialPort.jl/src/wrap.jl:299
   [3] #list_ports#3(::Int64, ::typeof(list_ports)) at /home/travis/build/JuliaIO/LibSerialPort.jl/src/wrap.jl:323
   [4] list_ports() at /home/travis/build/JuliaIO/LibSerialPort.jl/src/LibSerialPort.jl:280
   [5] top-level scope at /home/travis/build/JuliaIO/LibSerialPort.jl/test/runtests.jl:22

Array versions of write() don't work

How to reproduce problem:

using LibSerialPort
dev= "/dev/ttyS0"
s = LibSerialPort.open_serial_port(dev, 115200)
write(s, ['@'])

This results in

ERROR: MethodError: no method matching sp_nonblocking_write(::Ptr{LibSerialPort.SPPort}, ::Array{Char,1})
Closest candidates are:
  sp_nonblocking_write(::Ref{LibSerialPort.SPPort}, ::Array{UInt8,N} where N) at ~/.julia/packages/LibSerialPort/xvkkM/src/wrap.jl:634
  sp_nonblocking_write(::Ref{LibSerialPort.SPPort}, ::Ptr{UInt8}) at ~/.julia/packages/LibSerialPort/xvkkM/src/wrap.jl:641
  sp_nonblocking_write(::Ref{LibSerialPort.SPPort}, ::String) at ~/.julia/packages/LibSerialPort/xvkkM/src/wrap.jl:648

Shouldn't the type signatures

write(sp::SerialPort, data::Array{Char})
write(sp::SerialPort, data::Array{UInt8})

really be

write(sp::SerialPort, data::Vector{Char})
write(sp::SerialPort, data::Vector{UInt8})

and likewise for sp_nonblocking_write()?

These functions seem not covered by the tests.

inefficient handle_error implementation

In wrap.jl, almost every function calls handle_error(ret, loc()). The problem with that is that evaluating loc() causes a hand full of completely unnecessary allocations each time in the common case of ret == SP_OK. That can cause significant headaches in real-time applications, where programmers may try to avoid allocations (and their highly unpredictable timing).

Suggestion: drop the loc() function entirely, as this merely seems to be a relic from the early days of Julia when there were no proper stack traces available. It seems unnecessary in Julia 1.

test-low-level-api.jl fails due to 6-bit config test

I noticed that julia test/test-low-level-api.jl /dev/ttyUSB0 115200 outputs string "\x14%34 -%33!'% 1\n" instead of the expected Test message 1, Test message 2, etc. I ran the test while I had arranged a loop-back configuration with my serial-port adapter (e.g. Adafruit USB to TTL serial cable with its white/green RX/TX lines simply connected with each other with a piece of wire).

I then got it to work (via trial and error) by uncommenting in function test_low_level_api of test/test-low-level-api.jl the call to test_port_configuration(port). That function appears to leaves the port handle in an unusable state, despite it claiming in the doc string: The original port configuration should not be modified by these tests!.

Something seems very confused here: both test_change_port_copy_method1() and test_change_port_copy_method2() each have in their second line sp_close(port), while the rest of test_low_level_api() afterwards happily tries to continue using the port handle that has been closed twice!

How was this meant to work?

list_ports() doesn't display anything on Windows

Hello,

Just testing today LibSerialPort.jl (latest master) on Windows with Julia 0.7.

using LibSerialPort
list_ports()

doesn't display anything (despite the fact that my USB-TTL converter is plugged).

My main use case is with Linux as OS, so I can live without Windows support... but I'd prefer that you know this.

Kind regards

PS : I also tried Pkg.build("LibSerialPort") and build.log is empty.

purpose of seteof() and reseteof()

What's the purpose (“use case”) of method seteof() in the high-level API? It seems currently the sole way to influence the return value of eof().

A serial port does not really have any notion of “file” and therefore no inherent way of communicating an “end of file” condition. So I would have expected either

  1. eof(sp::SerialPort) = false as a minimalist implementation of that Base.IO function, or
  2. methods to define some EOF symbol that, if received, will cause eof() == true after the preceding byte has been read.

Are there any particular EOF signals that people would like to be interpreted that way? For example:

  1. Ctrl-Z = 0x1a (as on MS-DOS)?
  2. break signal?
  3. some particular modem status-line change?

Otherwise, why not simply set eof(sp::SerialPort) = false?

Safe open

Is there some way I can open a port (i.e. "/dev/ttyACM0") "safely"? Alternatively, test to see if a port is already open? Currently I can only do:

isopen(sp)

but this only works for a SerialPort type, that has already been opened before (and maybe closed at some point). My point is, if you don't know what ports are available, open, or closed, you can only start from get_port_list(), which gives you a list of strings. How can I, from that point, safely test if a port is already open, so I'll know to close it before attempting to open it again?

ERROR: LoadError: LoadError: syntax: extra token "SPPort" after end of expression

When trying to

use LibSerialPort

I get the error with julia 0.5.2

ERROR: LoadError: LoadError: syntax: extra token "SPPort" after end of expression
 in include_from_node1(::String) at ./loading.jl:488 (repeats 2 times)
 in eval(::Module, ::Any) at ./boot.jl:234
 in require(::Symbol) at ./loading.jl:415
while loading /home/hofmann/.julia/v0.5/LibSerialPort/src/wrap.jl, in expression starting on line 1
while loading /home/hofmann/.julia/v0.5/LibSerialPort/src/LibSerialPort.jl, in expression starting on line 191

One of the latest changes seems to have introduced a bug.

EXCEPTION_ACCESS_VIOLATION when listing ports on windows

Hi,

Trying to list serial ports on Julia 1.4.1 on Windows 10(guest) on a Virtualbox 6.1/Ubuntu 20.04(host) I get the following error message (LIBSERIALPORT_DEBUG environment variable was set).

julia> get_port_list()
sp: sp_list_ports(000000001DE1F1C0) called.
sp: Enumerating ports.
sp: Opening registry key.
sp: Querying registry key value and data sizes.
sp: Iterating over values.
sp: Found port COM3.
sp: sp_get_port_by_name(COM3, 000000001ED2A4B0) called.
sp: Building structure for port COM3.

Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x7ffcbf8607d3 -- RtlGetCurrentServiceSessionId at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
in expression starting at REPL[5]:1
RtlGetCurrentServiceSessionId at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
RtlFreeHeap at C:\Windows\SYSTEM32\ntdll.dll (unknown line)
free at C:\Windows\System32\msvcrt.dll (unknown line)
get_usb_details at /workspace/srcdir/libserialport-0.1.1\windows.c:340 [inlined]
get_port_details at /workspace/srcdir/libserialport-0.1.1\windows.c:468
sp_get_port_by_name at /workspace/srcdir/libserialport-0.1.1\serialport.c:109
list_append at /workspace/srcdir/libserialport-0.1.1\serialport.c:316
list_ports at /workspace/srcdir/libserialport-0.1.1\windows.c:535
sp_list_ports at /workspace/srcdir/libserialport-0.1.1\serialport.c:350
sp_list_ports at C:\Users\User\.julia\packages\LibSerialPort\d8jfU\src\wrap.jl:155 [inlined]
#get_port_list#4 at C:\Users\User\.julia\packages\LibSerialPort\d8jfU\src\high-level-api.jl:138
get_port_list at C:\Users\User\.julia\packages\LibSerialPort\d8jfU\src\high-level-api.jl:138
unknown function (ip: 000000001D62D0B3)
jl_apply at /cygdrive/d/buildbot/worker/package_win64/build/src\julia.h:1700 [inlined]
do_call at /cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:369
eval_value at /cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:458
eval_stmt_value at /cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:409 [inlined]
eval_body at /cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:799
jl_interpret_toplevel_thunk at /cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:911
jl_toplevel_eval_flex at /cygdrive/d/buildbot/worker/package_win64/build/src\toplevel.c:814
jl_toplevel_eval_flex at /cygdrive/d/buildbot/worker/package_win64/build/src\toplevel.c:764
jl_toplevel_eval at /cygdrive/d/buildbot/worker/package_win64/build/src\toplevel.c:823 [inlined]
jl_toplevel_eval_in at /cygdrive/d/buildbot/worker/package_win64/build/src\toplevel.c:843
eval at .\boot.jl:331
eval_user_input at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\REPL\src\REPL.jl:86
macro expansion at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\REPL\src\REPL.jl:118 [inlined]
#26 at .\task.jl:358
jl_apply at /cygdrive/d/buildbot/worker/package_win64/build/src\julia.h:1700 [inlined]
start_task at /cygdrive/d/buildbot/worker/package_win64/build/src\task.c:687
Allocations: 1740597 (Pool: 1740157; Big: 440); GC: 2
PS C:\Users\User>

The same error occurs when I try to do anything else with the, e.g. open.

Any clues on why this is happening?
The c-library libserialport has received many commits since version 1.1.0 was released four years ago, it might be nice to build from master in libserialport_jll ? ( https://sigrok.org/gitweb/?p=libserialport.git;a=shortlog )

Thx

runtests.jl fails using Windows Subsystem for Linux(WSL)

Hi there,
for arduino communication using windows subsystem for linux it would be great to able to use LibSerialPort.

include(".julia/packages/LibSerialPort/xvkkM/test/runtests.jl")                                                                                                                                                                      Usage: test-low-level-api.jl port [baudrate]  
Available ports:                                                                                                                                                                                    OS error code 2: No such file or directory                      
                                                                                                                                                                             Low level API: Error During Test at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:28

Got exception outside of a @test 
LoadError: From /home/flothieben/.julia/packages/LibSerialPort/xvkkM/src/wrap.jl: 141:      
libserialport returned SP_ERR_FAIL - Host OS reported a failure.       
                                                                                                                                                                      Stacktrace:     
                                                                                                                                                                                                                              [1] error(::String) at ./error.jl:33           
                                                                                                                                                                                              [2] handle_error(::SPReturn, ::String) at /home/flothieben/.julia/packages/LibSerialPort/xvkkM
/src/wrap.jl:136                                                                                                                              
 [3] sp_list_ports at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/src/wrap.jl:164 [inlined]    

 [4] #list_ports#29(::Int64, ::typeof(list_ports)) at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/src/high-level-api.jl:114                                                                                                          
[5] list_ports at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/src/high-level-api.jl:114 [inlined]                                                                                                                                   
[6] test_low_level_api() at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/test-low-level-api.jl:211                                                                                                                              
[7] top-level scope at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/test-low-level-api.jl:241
 [8] include at ./boot.jl:328 [inlined]   
[9] include_relative(::Module, ::String) at ./loading.jl:1105        
[10] include(::Module, ::String) at ./Base.jl:31      
[11] include(::String) at ./client.jl:424     
[12] top-level scope at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:29    
[13] top-level scope at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.3/Test/src/Test.jl:1107
[14] top-level scope at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:29     
[15] top-level scope at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.3/Test/src/Test.jl:1107
[16] top-level scope at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:28  
[17] include at ./boot.jl:328 [inlined]       
[18] include_relative(::Module, ::String) at ./loading.jl:1105                   
[19] include(::Module, ::String) at ./Base.jl:31               
[20] include(::String) at ./client.jl:424             
[21] top-level scope at REPL[3]:1             
[22] eval(::Module, ::Any) at ./boot.jl:330          
[23] eval_user_input(::Any, ::REPL.REPLBackend) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.3/REPL/src/REPL.jl:86           
[24] macro expansion at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.3/REPL/src/REPL.jl:118 [inlined]           
[25] (::REPL.var"#26#27"{REPL.REPLBackend})() at ./task.jl:333     
in expression starting at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/test-low-level-api.jl:241 

                                                                                                                                                                                                                                                                                                                                                                   Usage: test-high-level-api.jl port baudrate        
Available ports:    
OS error code 2: No such file or directory    
High level API: Error During Test at /home/flothieben/.julia/packages/LibSerialPort/xvkkM
/test/runtests.jl:35          
Got exception outside of a @test          
LoadError: From /home/flothieben/.julia/packages/LibSerialPort/xvkkM/src/wrap.jl: 141:        
libserialport returned SP_ERR_FAIL - Host OS reported a failure.     
Stacktrace:         
[1] error(::String) at ./error.jl:33          
[2] handle_error(::SPReturn, ::String) at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/src/wrap.jl:136        
[3] sp_list_ports at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/src/wrap.jl:164 [inlined]   
[4] #list_ports#29(::Int64, ::typeof(list_ports)) at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/src/high-level-api.jl:114
[5] list_ports at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/src/high-level-api.jl:114 [inlined] 
[6] test_high_level_api() at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/test-high-level-api.jl:75  
[7] top-level scope at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/test-high-level-api.jl:96
[8] include at ./boot.jl:328 [inlined]         
[9] include_relative(::Module, ::String) at ./loading.jl:1105               
[10] include(::Module, ::String) at ./Base.jl:31    
[11] include(::String) at ./client.jl:424         
[12] top-level scope at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:36  
[13] top-level scope at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.3/Test/src/Test.jl:1107 
 [14] top-level scope at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:36    
[15] top-level scope at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.3/Test/src/Test.jl:1107
[16] top-level scope at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:28  
[17] include at ./boot.jl:328 [inlined]              
[18] include_relative(::Module, ::String) at ./loading.jl:1105                     
[19] include(::Module, ::String) at ./Base.jl:31                    
[20] include(::String) at ./client.jl:424  
[21] top-level scope at REPL[3]:1            
[22] eval(::Module, ::Any) at ./boot.jl:330     
[23] eval_user_input(::Any, ::REPL.REPLBackend) at /buildworker/worker/package_linux64/build
/usr/share/julia/stdlib/v1.3/REPL/src/REPL.jl:86          
[24] macro expansion at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.3/REPL/src/REPL.jl:118 [inlined]        
[25] (::REPL.var"#26#27"{REPL.REPLBackend})() at ./task.jl:333       
in expression starting at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/test-high-level-api.jl:96            
Test Summary:    | Error  Total   
LibSerialPort    |     2      2    
Low level API  |     1      1  
High level API |     1      1    
ERROR: LoadError: Some tests did not pass: 0 passed, 0 failed, 2 errored, 0 broken.        
in expression starting at /home/flothieben/.julia/packages/LibSerialPort/xvkkM/test/runtests.jl:14 

avoid duplicating read functions from base/io.jl

Is this package really the right place to duplicate various IO read utility functions from Base, just to add a timeout argument?

After all, the need to read from a byte stream with a timeout is not specific to serial ports in any way: you need the same functionality from lots of other character devices (TCP sockets, stdin from a terminal, GPIB interfaces, etc.).

Therefore, it would make sense to find ways to deal with this without duplicating code. The LibSerialPort high-level API should probably just implement the basic read(s::SerialPort, ::Type{UInt8}), unsafe_read(s::SerialPort, p::Ptr{UInt8}, n::UInt) and peek(s::SerialPort) methods expected by all IO subtypes, and inherit all the higher-level read utility functions from IO. (In essence, doing for reading what PR #56 does for writing.)

One example solution:

We could add a read_timeout parameter to the SerialPort struct. As long as read_timeout < Inf, then the read(s::SerialPort, ::Type{UInt8}), unsafe_read(s::SerialPort, p::Ptr{UInt8}, n::UInt) and peek(s::SerialPort) implementations should record the time t1 they were called, pass timeout to the low-level API, record the time t2-t1 spent there, and subtract it from read_timeout. If read_timeout reaches zero, they could throw a TimeoutException to abort any higher-level utility functions that called them. From a user's point of view, if you want to call any function with a read timeout, just call set_read_timeout(sp, timeout) first, and be prepared that the subsequent read method call comes back with a TimeoutException. To disable timeouts use set_read_timeout(sp, Inf). The default for read_timeout should be Inf, whereas read_timeout ≤ 0 might be used to cause invocation of the non-blocking read functions of the low-level API.

This way, users have full control over timeouts and blocking/non-blocking behaviour, without changing the parameter signature of IO functions, or duplicating them.

(Are there other solutions, e.g. involving Julia's asynchronous event or multi-threading APIs?)

Please enable CI build of documentation

In commit 75d6ddc (part of PR #74) I added a CI build target for documentation formatted by Documenter.jl. Could you please complete the steps needed to host this documentation on GitHub pages (setting up the SSH key, check again that everything is still in line with the latest conventions), and then add to the README.md the customary shields:

(Alternatively, if you allow me to join the JuliaIO organization, I'd also be delighted to finish this myself.)

1.0 issue

Hi, I get this:

ERROR: LoadError: LoadError: UndefVarError: readstring not defined
Stacktrace:
 [1] getproperty(::Module, ::Symbol) at ./sysimg.jl:13
 [2] top-level scope at none:0
 [3] include at ./boot.jl:317 [inlined]
 [4] include_relative(::Module, ::String) at ./loading.jl:1038
 [5] include at ./sysimg.jl:29 [inlined]
 [6] include(::String) at /Users/knopp/.julia/dev/LibSerialPort/src/LibSerialPort.jl:2
 [7] top-level scope at none:0
 [8] include at ./boot.jl:317 [inlined]
 [9] include_relative(::Module, ::String) at ./loading.jl:1038
 [10] include(::Module, ::String) at ./sysimg.jl:29
 [11] top-level scope at none:2
 [12] eval at ./boot.jl:319 [inlined]
 [13] eval(::Expr) at ./client.jl:389
 [14] top-level scope at ./none:3
in expression starting at /Users/knopp/.julia/dev/LibSerialPort/src/high-level-api.jl:416
in expression starting at /Users/knopp/.julia/dev/LibSerialPort/src/LibSerialPort.jl:192
ERROR: LoadError: Failed to precompile LibSerialPort [8d099cbf-8da3-5ec2-a1c2-df122ad121d3] to /Users/knopp/.julia/compiled/v1.0/LibSerialPort/UB8VU.ji.

If I remove the Base. in front of readstring then it seems to work.

"Inappropriate ioctl for device" when opening Port

Hi alltogether,

I am experimenting with LibSerialPort.jl, got it working a few weeks ago ... and suddenly it stopped working with the mentioned error message from the title 🤔

I.e. with

• LibSerialPort v0.5.0
• Julia v1.6.1
• x64 Archlinux with kernel v5.12.7

when trying

using LibSerialPort
sp = LibSerialPort.open("/dev/ttyUSB0", 115200)

then, I receive the following error:

@0x00005596f79cfc40, SP_MODE_READ_WRITE)
OS error code 25: Inappropriate ioctl for device
ERROR: libserialport returned SP_ERR_FAIL - Host OS reported a failure.
Stacktrace:
 [1] check(ret::LibSerialPort.Lib.SPReturn)
   @ LibSerialPort.Lib ~/.julia/packages/LibSerialPort/zyrgR/src/wrap.jl:299
 [2] sp_open(port::Ptr{LibSerialPort.Lib.SPPort}, mode::SPMode)
   @ LibSerialPort.Lib ~/.julia/packages/LibSerialPort/zyrgR/src/wrap.jl:342
 [3] open(portname::String, baudrate::Int64; mode::SPMode, ndatabits::Int64, parity::SPParity, nstopbits::Int64)
   @ LibSerialPort ~/.julia/packages/LibSerialPort/zyrgR/src/LibSerialPort.jl:463
 [4] open(portname::String, baudrate::Int64)
   @ LibSerialPort ~/.julia/packages/LibSerialPort/zyrgR/src/LibSerialPort.jl:462
 [5] top-level scope
   @ REPL[2]:1

However: the serial device is responsive with screen and with other programs

screen /dev/ttyUSB0 115200

This might not be directly related to LibSerialPort.jl but I would appreciate any advice for debugging this issue

kind regards,
Christian

[code] 'convert(Vector{Char},delim)' make MethodError for julia 1.4

The following function in high-level-api.jl contains the code convert(Vector{Char},delim) which introduce an ERROR!

function Base.readuntil(sp::SerialPort, delim::AbstractString, timeout_ms::Real)
    return readuntil(sp,convert(Vector{Char},delim),timeout_ms)
end

julia> convert(Vector{Char},"ab")
ERROR: MethodError: Cannot convert an object of type String to an object of type Array{Char,1}

It seems correct if we change the above code convert(Vector{Char},delim) to Vector{Char}(delim) .

julia> Vector{Char}("ab")
2-element Array{Char,1}:
'a'
'b'

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.