RS-485 and MODBUS
RS-485 and MODBUS Functions
This category contains functions specific to RS-485 or MODBUS devices.
| API Name | Brief Description |
|---|---|
| api.rs485Send(msg) | Sends message to RS-485 bus. |
| api.rs485Setup() | Configures the RS-485 communication interface. Multiple variants. See below. |
| api.rs485State(state) | Controls the RS-485 circuitry. |
| api.rs485Receive() | Waits for data reception from RS-485 bus. Multiple variants. See below. |
| api.modbusCrc(msg) | Calculates MODBUS request checksum. |
| api.modbusRTU(addr, rAddr, fCode, typeSpec, regCount, tout, rtry, intBTout, ignCRC) | Communicates with a MODBUS device over a serial connection using the RTU protocol. |
| api.nvtProcess(buf) | Processes NVT message and configures M-Bus or MODBUS settings. |
| api.nvtEncode(msg) | Encodes message to NVT format. |
api.rs485Send(msg)
api.rs485Send('test')
Sends message to RS-485 bus.
Tip: Ensure RS-485 is turned on using api.rs485State(1) first.
Arguments
- msg (string): Data to be sent to RS-485 bus.
Example
-- Sends 'test' string to RS-485
api.rs485Send('test')
--------------------------------
--read temperature
api.rs485State(1)
api.voltageSourceState(1)
api.delayms(500)
req = pack.pack('<b8', 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA)
api.rs485Receive(0) -- flush input buffer
api.rs485Send(req)
ans,len = api.rs485Receive(500)
api.rs485Setup()
Configures the RS-485 communication interface.
| API Name | Brief Description |
|---|---|
| api.rs485Setup("RX_BUFFER", value) | Sets or gets the size of the receive buffer. |
| api.rs485Setup(baudrate, parity, stopBits, dataBits) | Configures RS-485 communication parameters. |
api.rs485Setup("RX_BUFFER", value)
api.rs485Setup("RX_BUFFER")
Sets or gets the size of the receive buffer.
Arguments
- "RX_BUFFER" (string): Operation to set or get the size of receive buffer.
Optional
- value (integer, optional): Set the size of receive buffer.
Return
- value (integer): Size of the receive buffer.
Example
-- Get the size of the receive buffer
size = api.rs485Setup("RX_BUFFER")
--------------------------------
--set RS485 buffer to 3000
api.rs485Setup("RX_BUFFER",3000)
api.rs485Setup(baudrate, parity, stopBits, dataBits)
api.rs485Setup(9600, 2, 1, 8)
Configures RS-485 communication parameters.
Arguments
- baudrate (integer): Baudrate to use for communication (up to
921600baud). - parity (integer): Parity,
0for none,1for odd,2for even. - stopBits (integer): Number of stop bits,
1or2allowed. - dataBits (integer): Number of data bits,
7or8allowed.
Example
-- Setup RS-485 interface to 9600 Baud, 8E1
api.rs485Setup(9600, 2, 1, 8)
--------------------------------
api.rs485Setup(baudrate[tonumber(newspeed)], parity, stopBits, dataBits)
api.rs485State(state)
api.rs485State(1)
Controls the RS-485 circuitry.
Warning: This function must be called before api.rs485Send() or api.rs485Receive().
Arguments
- state (integer): New state of RS-485 circuitry:
0for off.1for on (fast power-up).
Example
api.rs485State(1) -- turn on RS-485
api.rs485State(0) -- turn off RS-485
api.rs485Receive()
Waits for data reception from RS-485 bus.
Tip: Ensure RS-485 is turned on using api.rs485State(1) first.
Info: After the first character is received, the inter-character (i.e., inter-byte) timeout delay is set to 10 ms by default. This can be modified by providing an optional argument to the function.
| API Name | Brief Description |
|---|---|
| api.rs485Receive(timeout, interByteTimeout) | Waits for data with specified inter-byte timeout. |
| api.rs485Receive(timeout, terminator) | Waits for data until a terminator is found. |
| api.rs485Receive(timeout, interByteTimeout, terminator) | Waits for data with specified inter-byte timeout and terminator. |
api.rs485Receive(timeout, interByteTimeout)
ans, len = api.rs485Receive(1000)
Waits for data reception from RS-485 bus with a specified inter-byte timeout.
Arguments
- timeout (integer): Maximum time in milliseconds to wait for RS-485 device answer.
Optional
- interByteTimeout (integer, optional): Inter-byte timeout in milliseconds.
Return
- answer (string): Data received from RS-485 bus in given time.
- len (integer): Number of bytes received.
Example
-- Waits 1s for answer from RS-485 bus
ans, len = api.rs485Receive(1000)
api.rs485Receive(timeout, terminator)
ans, len = api.rs485Receive(1000, "!")
Waits for data reception from RS-485 bus until a terminator is found.
Arguments
- timeout (integer): Maximum time in milliseconds to wait for RS-485 device answer.
Optional
- terminator (string, optional): Terminator (can be more than one character).
Return
- answer (string): Data received from RS-485 bus in given time.
- len (integer): Number of bytes received.
Example
-- Waits 1s for answer from RS-485 bus and gets everything until it finds "!" character
collectgarbage("stop") -- Stop garbage collector to prevent losing characters
ans, len = api.rs485Receive(1000, "!")
collectgarbage("restart") -- Restart the garbage collector
api.rs485Receive(timeout, interByteTimeout, terminator)
ans, len = api.rs485Receive(1000, 10, "!")
Waits for data reception from RS-485 bus with specified inter-byte timeout and terminator.
Arguments
- timeout (integer): Maximum time in milliseconds to wait for RS-485 device answer.
- interByteTimeout (integer, optional): Inter-byte timeout in milliseconds.
- terminator (string, optional): Terminator (can be more than one character).
Return
- answer (string): Data received from RS-485 bus in given time.
- len (integer): Number of bytes received.
Example
-- Waits 1s for answer from RS-485 bus with 10ms inter-byte timeout and "!" terminator
collectgarbage("stop") -- Stop garbage collector to prevent losing characters
ans, len = api.rs485Receive(1000, 10, "!")
collectgarbage("restart") -- Restart the garbage collector
api.modbusCrc(msg)
crc = api.modbusCrc(string.char(0x11,0x01,0x00,0x01,0x00,0x02))
Calculates MODBUS request checksum.
Arguments
- msg (string): MODBUS request.
Return
- crc (string): MODBUS CRC for request.
Example
-- Calculate checksum for MODBUS request 110100010002
req = pack.pack('<b6', 0x11, 0x01, 0x00, 0x01, 0x00, 0x02)
crc = api.modbusCrc(req) -- crc = "EE9B"
api.modbusRTU(addr, rAddr, fCode, typeSpec, regCount, tout, rtry, intBTout, ignCRC)
x = api.modbusRTU(10, 0x4003, 3, ">h", 1, 2000, 3, 10)
Communicates with a MODBUS device over a serial connection using the RTU (Remote Terminal Unit) protocol.
Info: It can be used to read or write one or more registers of various data types. The typeSpec parameter uses Lua Packing and Unpacking syntax to specify the type and formatting of the data. For example, to read a single 16-bit unsigned integer, typeSpec would be "H". If the function fails, it retries according to the retry parameter. Returns nil on failure after retries.
Arguments
- address (integer): The address of the MODBUS device to communicate with.
- registerAddr (integer): The starting address of the MODBUS register to read or write.
- functionCode (integer): The MODBUS function code (e.g., read coils, read input registers, write multiple coils, etc.).
- typeSpec (string): Specifies the data type of the register(s) being read or written. If
"", returns data as received. - registerCount (integer): The number of registers to read or write.
- timeout (integer): Timeout (in milliseconds) for the MODBUS communication operation.
- retry (integer): Number of times to retry the operation if it fails.
- interByteTimeout (integer): Timeout (in milliseconds) between receiving bytes.
- ignoreCRC (boolean, optional): If
true, function does not check MODBUS CRC.
Return
- The value(s) read from or written to the MODBUS register(s), according to the specified
typeSpec.
Example
-- Setup the RS-485 and turn on the RS-485 module
api.rs485Setup(9600, 2, 1, 8)
api.rs485State(1)
-- Read 0x4003 register (MODBUS ID in case of INEPRO PRO1)
x = api.modbusRTU(10, 0x4003, 3, ">h", 1, 2000, 3, 10)
print(x)
api.nvtProcess(buf)
msg, answer = api.nvtProcess("AT+BAUD=9600\r\n")
Processes NVT message and either sets baudrate, datasize, parity, or stop size for M-Bus or MODBUS.
Arguments
- buf (string): Message to be processed.
Return
- msg (string): Message without NVT sequence.
- answer (string): NVT answer.
Example
-- If message received (buf), send it to RS-485
ret, port, buf = api.loraSend(0, 1000, data)
if buf ~= nil then
buf, nvtans = api.nvtProcess(buf)
api.rs485Send(buf)
end
api.nvtEncode(msg)
nvt = api.nvtEncode("payload")
Encodes message to NVT format.
Arguments
- msg (string): Message to be encoded to NVT.
Return
- answer (string): NVT message.
Example
ans, len = api.rs485Receive(50)
ans = api.nvtEncode(ans)
api.loraSend(0, 1, ans)