Library provides versatile work with serial port for Linux, Windows and MacOS.
auto com = new SerialPortBlk("/dev/ttyUSB0", 19200);
// setting parameters example
com.config = SPConfig(9600, DataBits.data8, Parity.none, StopBits.one)
com.set(19200).set(DataBits.data8);
com.stopBits = StopBits.two;
// set 9600 baudrate, 8 data bits, no parity and one stop bit
com.set("9600:8N1");
auto cnt = com.write(someDataArray);
// cnt must be equal someDataArray.length
// res1 is slice of bufferForReading with readed data
auto res1 = com.read(bufferForReading);
See also example: monitor.
abstract
SerialPortBase
^ ^
| |
| SerialPortNonBlk
|
abstract
SerialPort
^ ^
| |
| SerialPortFR
|
SerialPortBlk
Class SerialPortBase
provides work with settings (baudrate, stop bits etc).
Class SerialPortNonBlk
provides non-blocking void[] read(void[] buf)
(immediatlly return data in system serial port buffer) and
size_t write(const(void[]))
(return writed bytes count at the first onset).
Class SerialPort
provides void[] read(void[] buf, CanRead cr=CanRead.allOrNothing)
,
void write(const(void[]))
and timeouts properties.
Class SerialPortBlk
provides blocking read
and write
.
If you want use library in fibers it provides SerialPortFR
(Fiber Ready),
where read
and write
is loops: call non-blocking read and write and
sleep between tries. Loops algorithms use Fiber.yield
if available,
or Thread.sleep
as failback. If you want redefine this behavior, you
can set void delegate(Duration) @nogc sleepFunc
field directly or through
last parameter of ctor.
write
method of SerialPort
can throw TimeoutException
if it can't
finish write all data to serial port during
timeout = writeTimeout + writeTimeoutMult * data.length
.
read
method of SerialPort
also can throw TimeoutException
,
but here the behavior can be different depending on the CanRead
flag.
Receive data time schema:
---|-------|--------------|-------|--> t
call | | |
read | | |
| |<----data receive---->|
| |===== ==== | ======|
| | |
| |<-readedData->|
| |
|<---readTimeoutSum--->|
| return
|<---read work time--->|
where readTimeoutSum = readTimeout + readTimeoutMult * dataBuffer.length;
if CanRead cr
flag is:
-
CanRead.allOrNothing
if (readedData.length < dataBuffer.length) throw TimeoutException(port); else return readedData;
-
CanRead.anyNonZero
if (readedData.length == 0) throw TimeoutException(port); else return readedData;
-
CanRead.zero
return readedData;
void[] readContinues(void[] arr, Duration startTimeout=1.seconds, Duration frameGap=50.msecs, bool expectAnything=true)
It reads in loop from serial port while silent time is less what frameGap
and
throws TimeoutException
only if timeout is expires when no data was readed and
expectAnything
flag is setted.
------|--------|-----|------------|-----|------------> t
call | | | |
readContinues | | | |
| | | | |
| |<---------data receive---------->|
| |=== ===== ======| | |== =| data stream
| | | | | | |
|<--timeout--->| | | | |
| |<-1->| |<2>| |<-3->|
| | | |
| |<---readedData--->| |
| return
|<-------readAll work time------->|
(1) if readedData.length > 0 then continue reading
else if expectAnything throw TimeoutException
else return readedData (empty)
(2) silent time, if silent < frameGap then continue reading
(3) else if silent > frameGap then stop reading
and return readedData
It's useful if you don't know how much data can come:
- allocate buffer for reading (4kB for example)
- call
readContinues
and get data frame
unix systems allow only standard speeds:
[0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400]
Two paired USB->UART (FTDI FT232RL) uses for tests on linux and windows.
For linux and OSX tested (socat as tty pipe creator)
- dmd (from 2.79.1 to actual and nightly)
- ldc (from 1.8.0 to actual and beta)
For windows tested (build only, see note) fox x86 and x64
- dmd stable and nightly
- ldc stable and beta
- Windows not full tested by CI (no real test with virtual com ports) because I did not configure to adjust the work com0com program https://help.appveyor.com/discussions/questions/427-how-can-i-use-com0com