The socket.serial module opens a serial device (e.g. /dev/ttyUSB0) and exposes it through the same buffered, timeout-aware send/receive interface used by TCP and Unix domain stream objects.
Note: This module is only built on Unix-like platforms (Linux, macOS, BSD, Haiku). It is not available on Windows.
Serial port support is a separate module that must be required explicitly. Unlike most other LuaSocket modules, it returns a function directly — the constructor — rather than a table of functions:
-- loads the socket.serial module; note this is the constructor itself
local serial_open = require("socket.serial")
-- open the device
local port = assert(serial_open("/dev/ttyUSB0"))
port:settimeout(1)
assert(port:send("AT\r\n"))
print(port:receive())
port:close()
Note: There is currently no API to configure the serial line itself — baud rate, parity, data/stop bits or flow control. The device is opened non-blocking with whatever settings the OS driver or a prior external configuration (e.g. stty) left it in. This is a known current limitation of the module, not a deliberate protection against misuse; a future version may add a setoption-style API for these settings the way tcp:setoption does for TCP.
Until such an API exists, the workaround is to configure the line with the platform's own stty utility (via os.execute) before opening the device with socket.serial:
local serial_open = require("socket.serial")
local dev = "/dev/ttyUSB0"
-- Linux: stty -F <device> ...
local ok = os.execute(string.format(
"stty -F %s 115200 cs8 -cstopb -parenb raw -echo", dev))
-- macOS/BSD use -f instead of -F:
-- os.execute(string.format("stty -f %s 115200 cs8 -cstopb -parenb raw -echo", dev))
assert(ok, "failed to configure serial line with stty")
local port = assert(serial_open(dev))
port:settimeout(1)
assert(port:send("AT\r\n"))
print(port:receive())
port:close()
Note: raw -echo puts the line in raw mode, which matters for LuaSocket's framing: without it, the TTY driver applies its own line editing/echo, which can interfere with receive patterns and send content. Adjust the stty flags (baud rate, parity, stop bits, flow control) to match your device; consult man stty for the full option set on your platform, since flag names and defaults vary between Linux, macOS and the BSDs.
port:close()
Closes a serial object. No further operations (except further calls to close) are allowed on a closed object.
Note: Garbage-collected objects are automatically closed before destruction.
port:dirty()
Check the read buffer status.
Returns true if there is any data in the read buffer, false otherwise.
Note: This is an internal method, use at your own risk.
port:getfd()
Returns the underlying file descriptor associated to the object.
The descriptor.
Note: This is an internal method. Unlikely to be portable. Use at your own risk.
port:getstats()
Returns accounting information on the port, useful for throttling of bandwidth. Works exactly like tcp:getstats.
The method returns the number of bytes received, the number of bytes sent, and the age of the object in seconds.
port:receive([pattern [, prefix [, maxsize]]])
Reads data from the serial port, according to the specified read pattern. Works exactly like tcp:receive, including the *a/*l/number patterns and the prefix/maxsize parameters.
port:send(data [, i [, j]])
Sends data through the serial port. Works exactly like tcp:send, including the optional i/j substring selection.
port:setfd(fd)
Sets the underlying file descriptor associated to the object. The current one is simply replaced, not closed, and no other change to the object state is made.
No return value.
Note: This is an internal method. Unlikely to be portable. Use at your own risk.
port:setstats(received, sent, age)
Resets accounting information on the port, useful for throttling of bandwidth. Works exactly like tcp:setstats.
The method returns 1 in case of success and nil otherwise.
port:settimeout(value [, mode])
Changes the timeout values for the object. Works exactly like tcp:settimeout, including the 'b' (block) and 't' (total) modes.
serial_open(path)
Opens the serial device at path and returns a serial object. This is the value returned directly by require("socket.serial") — there is no separate module table to index into, unlike socket.unix.stream() or socket.tcp().
Path is a string with the device path (e.g. "/dev/ttyUSB0" or "/dev/ttyS0").
In case of success, a new serial object is returned. In case of error, the function returns nil, followed by an error message, followed by the numeric errno value.