Struct libmodbus_rs::Modbus
[−]
[src]
pub struct Modbus { pub ctx: *mut modbus_t, }
Safe interface for libmodbus
The different parts of libmodbus are implemented as traits. The modules of this crate contains these traits and a implementation with a, hopefully safe, interface.
Fields
ctx: *mut modbus_t
Methods
impl Modbus
[src]
const MAX_READ_BITS: u32
MAX_READ_BITS: u32 = ffi::MODBUS_MAX_READ_BITS
Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12) Quantity of Coils to read (2 bytes): 1 to 2000 (0x7D0)
const MAX_WRITE_BITS: u32
MAX_WRITE_BITS: u32 = ffi::MODBUS_MAX_WRITE_BITS
Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 11 page 29) Quantity of Coils to write (2 bytes): 1 to 1968 (0x7B0)
const MAX_READ_REGISTERS: u32
MAX_READ_REGISTERS: u32 = ffi::MODBUS_MAX_READ_REGISTERS
Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 3 page 15) Quantity of Registers to read (2 bytes): 1 to 125 (0x7D)
const MAX_WRITE_REGISTERS: u32
MAX_WRITE_REGISTERS: u32 = ffi::MODBUS_MAX_WRITE_REGISTERS
Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 12 page 31) Quantity of Registers to write (2 bytes) 1 to 123 (0x7B)
const MAX_WR_WRITE_REGISTERS: u32
MAX_WR_WRITE_REGISTERS: u32 = ffi::MODBUS_MAX_WR_WRITE_REGISTERS
Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 17 page 38) Quantity of Registers to write in R/W registers (2 bytes) 1 to 121 (0x79)
const MAX_WR_READ_REGISTERS: u32
MAX_WR_READ_REGISTERS: u32 = ffi::MODBUS_MAX_WR_READ_REGISTERS
Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 3 page 15) Quantity of Registers to read (2 bytes): 1 to 125 (0x7D)
const MAX_PDU_LENGTH: usize
MAX_PDU_LENGTH: usize = ffi::MODBUS_MAX_PDU_LENGTH as usize
The size of the MODBUS PDU is limited by the size constraint inherited from the first MODBUS implementation on Serial Line network (max. RS485 ADU = 256 bytes). Therefore, MODBUS PDU for serial line communication = 256 - Server address (1 byte) - CRC (2 bytes) = 253 bytes.
const MAX_ADU_LENGTH: usize
MAX_ADU_LENGTH: usize = ffi::MODBUS_MAX_ADU_LENGTH as usize
Consequently: - RTU MODBUS ADU = 253 bytes + Server address (1 byte) + CRC (2 bytes) = 256 bytes - TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes so the maximum of both backend in 260 bytes. This size can used to allocate an array of bytes to store responses and it will be compatible with the two backends.
const ENOBASE: u32
ENOBASE: u32 = ffi::MODBUS_ENOBASE
Random number to avoid errno conflicts
const RTU_MAX_ADU_LENGTH: usize
RTU_MAX_ADU_LENGTH: usize = ffi::MODBUS_RTU_MAX_ADU_LENGTH as usize
const TCP_DEFAULT_PORT: u32
TCP_DEFAULT_PORT: u32 = ffi::MODBUS_TCP_DEFAULT_PORT
const TCP_MAX_ADU_LENGTH: usize
TCP_MAX_ADU_LENGTH: usize = ffi::MODBUS_TCP_MAX_ADU_LENGTH as usize
const TCP_SLAVE: u8
TCP_SLAVE: u8 = ffi::MODBUS_TCP_SLAVE as u8
const BROADCAST_ADDRESS: u8
BROADCAST_ADDRESS: u8 = ffi::MODBUS_BROADCAST_ADDRESS as u8
pub fn connect(&self) -> Result<(), Error>
[src]
connect
- establish a Modbus connection
The connect()
function shall establish a connection to a Modbus server,
a network or a bus.
Return value
The function return an OK Result if successful. Otherwise it contains an Error.
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; // create server let mut server = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); // create client let client = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); // start server in listen mode let _ = server.tcp_listen(1).unwrap(); assert!(client.connect().is_ok())
pub fn flush(&self) -> Result<(), Error>
[src]
flush
- flush non-transmitted data
The flush()
function shall discard data received but not read to the socket or file
descriptor associated to the context ctx.
Return value
The function return an OK Result if successful. Otherwise it contains an Error.
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); assert!(modbus.flush().is_ok());
pub fn set_slave(&mut self, slave: u8) -> Result<(), Error>
[src]
set_slave
- set slave number in the context
The set_slave()
function shall set the slave number in the libmodbus context.
The behavior depends of network and the role of the device:
- RTU
- Define the slave ID of the remote device to talk in master mode or set the internal slave ID in slave mode. According to the protocol, a Modbus device must only accept message holding its slave number or the special broadcast number.
- TCP
- The slave number is only required in TCP if the message must reach a device on a serial network. Some not compliant devices or software (such as modpoll) uses the slave ID as unit identifier, that’s incorrect (see page 23 of Modbus Messaging Implementation Guide v1.0b) but without the slave value, the faulty remote device or software drops the requests! The special value MODBUS_TCP_SLAVE (0xFF) can be used in TCP mode to restore the default value. The broadcast address is MODBUS_BROADCAST_ADDRESS. This special value must be use when you want all Modbus devices of the network receive the request.
Return value
The function return an OK Result if successful. Otherwise it contains an Error.
Parameters
slave
- new slave ID
Examples
use libmodbus_rs::{Modbus, ModbusRTU}; const YOUR_DEVICE_ID: u8 = 1; let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1).unwrap(); assert!(modbus.set_slave(YOUR_DEVICE_ID).is_ok());
pub fn get_slave(&self) -> Result<u8, Error>
[src]
get_slave
- get slave number from current context
Examples
use libmodbus_rs::{Modbus, ModbusRTU}; let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1).unwrap(); modbus.set_slave(10); assert_eq!(modbus.get_slave().unwrap(), 10);
pub fn set_debug(&mut self, flag: bool) -> Result<(), Error>
[src]
set_debug
- set debug flag of the context
The set_debug()
function shall set the debug flag of the modbus_t context by using the
argument flag.
By default, the boolean flag is set to FALSE. When the flag value is set to TRUE, many verbose messages are
displayed on stdout and stderr.
For example, this flag is useful to display the bytes of the Modbus messages.
[00][14][00][00][00][06][12][03][00][6B][00][03]
Waiting for a confirmation…
<00><14><00><00><00><09><12><03><06><02><2B><00><00><00><00>
Return value
The function return an OK Result if successful. Otherwise it contains an Error.
Parameters
flag
-true
offalse
, enables or disables debug mode
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); assert!(modbus.set_debug(true).is_ok());
pub fn get_byte_timeout(&self) -> Result<Timeout, Error>
[src]
get_byte_timeout
- get timeout between bytes
get_byte_timeout()
function returns a
Timeout
with the timeout interval between
two consecutive bytes of the same message.
Return value
The function return a Result containing a Timeout
if successful.
Otherwise it contains an Error.
Examples
use libmodbus_rs::{Modbus, ModbusTCP, Timeout}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); assert_eq!(modbus.get_byte_timeout().unwrap(), Timeout { sec: 0, usec: 500000 });
pub fn set_byte_timeout(&mut self, timeout: Timeout) -> Result<(), Error>
[src]
set_byte_timeout
- set timeout between bytes
The set_byte_timeout()
function shall set the timeout interval between two
consecutive bytes of the same message.
The timeout is an upper bound on the amount of time elapsed before select() returns, if the time elapsed is
longer than the defined timeout,
an ETIMEDOUT error will be raised by the function waiting for a response.
The value of usec argument must be in the range 0 to 999999.
If both sec and usec are zero, this timeout will not be used at all. In this case,
set_byte_timeout()
governs the entire handling of the response, the full confirmation response must be received before expiration
of the response timeout.
When a byte timeout is set, the response timeout is only used to wait for until the first byte of the response.
Return value
The function return an OK Result if successful. Otherwise it contains an Error.
Parameters
timeout
- Timeout struct withsec
andusec
Examples
use libmodbus_rs::{Modbus, ModbusTCP, Timeout}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let timeout = Timeout { sec: 1, usec: 500000 }; assert!(modbus.set_byte_timeout(timeout).is_ok());
pub fn get_response_timeout(&self) -> Result<Timeout, Error>
[src]
get_response_timeout
- get timeout for response
The get_response_timeout()
function shall return the timeout interval used to
wait for a response
in the sec and usec arguments.
Return value
The function return a Result containing a Timeout
if successful.
Otherwise it contains an Error.
Examples
use libmodbus_rs::{Modbus, ModbusTCP, Timeout}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); assert_eq!(modbus.get_response_timeout().unwrap(), Timeout { sec: 0, usec: 500000 });
pub fn set_response_timeout(&mut self, timeout: Timeout) -> Result<(), Error>
[src]
set_response_timeout
- set timeout for response
The set_response_timeout()
function shall set the timeout interval used to
wait for a response.
When a byte timeout is set, if elapsed time for the first byte of response is longer than the given timeout,
an ETIMEDOUT error will be raised by the function waiting for a response. When byte timeout is disabled,
the full confirmation response must be received before expiration of the response timeout.
If the Timeout
members are both sec and usec are zero,
this timeout will not be used at all. In this case, set_response_timeout()
governs the entire handling of the response, the full confirmation response must be received before expiration
of the response timeout.
When a byte timeout is set, the response timeout is only used to wait for until the first byte of the response.
Return value
The function return an OK Result if successful. Otherwise it contains an Error.
Parameters
Timeout
- Timeout
Examples
use libmodbus_rs::{Modbus, ModbusTCP, Timeout}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let timeout = Timeout { sec: 1, usec: 500000 }; assert!(modbus.set_response_timeout(timeout).is_ok());
pub fn set_error_recovery(
&mut self,
flags: Option<&[ErrorRecoveryMode]>
) -> Result<(), Error>
[src]
&mut self,
flags: Option<&[ErrorRecoveryMode]>
) -> Result<(), Error>
set_error_recovery
- set the error recovery mode
The set_error_recovery()
function shall set the error recovery mode to apply
when the connection fails or the byte received is not expected.
By default there is no error recovery so the application is responsible for controlling the error values returned by libmodbus functions and for handling them if necessary.
When ErrorRecoveryMode::Link
is set, the library will attempt an reconnection after a delay defined by
response timeout (set_response_timeout()
) of the libmodbus context.
This mode will try an infinite close/connect loop until success on send call and will just try one time to
re-establish the connection on select/read calls (if the connection was down, the values to read are certainly
not available any more after reconnection, except for slave/server).
This mode will also run flush requests after a delay based on the current response timeout in some situations
(eg. timeout of select call).
The reconnection attempt can hang for several seconds if the network to the remote target unit is down.
When ErrorRecoveryMode::Protocol
is set, a sleep and flush sequence will be used to clean up the ongoing
communication, this can occurs when the message length is invalid, the TID is wrong or the received function
code is not the expected one.
The response timeout delay will be used to sleep.
The modes are mask values and so they are complementary.
It’s not recommended to enable error recovery for slave/server.
Return value
The function return an OK Result if successful. Otherwise it contains an Error.
Parameters
ErrorRecoveryMode
- Timeout
Examples
use libmodbus_rs::{Modbus, ModbusTCP, ErrorRecoveryMode}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); assert!(modbus.set_error_recovery(Some(&[ErrorRecoveryMode::Link, ErrorRecoveryMode::Protocol])).is_ok());
pub fn set_socket(&mut self, socket: i32) -> Result<(), Error>
[src]
set_socket
- set socket of the context
The set_socket()
function shall set the socket or file descriptor in the libmodbus
context.
This function is useful for managing multiple client connections to the same server.
Return values
The function return an OK Result if successful. Otherwise it contains an Error.
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); assert!(modbus.set_socket(1337).is_ok());
pub fn get_socket(&self) -> Result<i32, Error>
[src]
get_socket
- set socket of the context
The get_socket()
function shall return the current socket or file descriptor of the
libmodbus context.
Return value
The function returns a Result containing the current socket or file descriptor of the context if successful. Otherwise it contains an Error.
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let _ = modbus.set_socket(1337).unwrap(); assert_eq!(modbus.get_socket().unwrap(), 1337);
pub fn get_header_length(&self) -> i32
[src]
get_header_length
- retrieve the current header length
The get_header_length()
function shall retrieve the current header length from
the backend.
This function is convenient to manipulate a message and so its limited to low-level operations.
Return values
The header length as integer value.
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); assert_eq!(modbus.get_header_length(), 7);
pub fn reply_exception(
&self,
request: &[u8],
exception_code: Exception
) -> Result<i32, Error>
[src]
&self,
request: &[u8],
exception_code: Exception
) -> Result<i32, Error>
reply_exception
- send an exception reponse
The modbus_reply_exception() function shall send an exception response based on the exception_code in argument.
The libmodbus provides the following exception codes:
- Modbus::Exception::IllegalFunction (1)
- Modbus::Exception::IllegalDataAddress (2)
- Modbus::Exception::IllegalDataValue (3)
- Modbus::Exception::SlaveOrServerFailure (4)
- Modbus::Exception::Acknowledge (5)
- Modbus::Exception::SlaveDeviceBusy (6)
- Modbus::Exception::NegativeAcknowledge (7)
- Modbus::Exception::MemoryParity (8)
- Modbus::Exception::NotDefined (9)
- Modbus::Exception::GatewayPath (10)
- Modbus::Exception::GatewayTarget (11)
The initial request request
is required to build a valid response.
Return value
The function returns the length of the response sent if successful, or an Error.
Parameters
request
- initial request, required to build a valid responseexception_code
- Exception Code
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); use libmodbus_rs::Exception; let request: Vec<u8> = vec![0x01]; assert_eq!(modbus.reply_exception(&request, Exception::Acknowledge).unwrap(), 9);
pub fn strerror(errnum: i32) -> String
[src]
strerror
- return the error message
The strerror()
function shall return a message String
corresponding to the error number
specified by the errnum
argument.
use libmodbus_rs::{Modbus, ModbusTCP}; assert_eq!(Modbus::strerror(112345694), "Too many data");
pub fn close(&self)
[src]
close
- close a Modbus connection
The close()
function shall close the connection established with the backend set in the
context.
It should not nessesary to call these function. Because rusts drop trait handles that for you!
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); modbus.close();
pub fn free(&mut self)
[src]
free
- free a libmodbus context
The free()
function shall free an allocated modbus_t structure.
It should not nessesary to call these function. Because rusts drop trait handles that for you!
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); modbus.free();
Trait Implementations
impl ModbusClient for Modbus
[src]
fn read_bits(
&self,
address: u16,
num: u16,
dest: &mut [u8]
) -> Result<u16, Error>
[src]
&self,
address: u16,
num: u16,
dest: &mut [u8]
) -> Result<u16, Error>
read_bits
- read many bits
The read_bits()
function shall read the status of the num
bits (coils) to the
address
of the remote device. The result of reading is stored in dest
slice as unsigned bytes (8 bits) set
to TRUE or FALSE.
The function uses the Modbus function code 0x01 (read coil status).
Return value
The function returns a Result
containing the number of read bits if successful. Otherwise it returns an Error.
Parameters
address
- address of the remote devicenum
- number of coils to readdest
- the result of the reading is stored here
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let mut dest = vec![0u8; 100]; assert!(modbus.read_bits(0, 1, &mut dest).is_ok());
fn read_input_bits(
&self,
address: u16,
num: u16,
dest: &mut [u8]
) -> Result<u16, Error>
[src]
&self,
address: u16,
num: u16,
dest: &mut [u8]
) -> Result<u16, Error>
read_input_bits
- read many input bits
The read_input_bits()
function shall read the content of the num
input bits to
the address
of the remote device. The result of reading is stored in dest
slice as unsigned bytes (8 bits)
set to TRUE or FALSE.
The function uses the Modbus function code 0x02 (read input status).
Return value
The function returns a Result
containing the number of read bits if successful. Otherwise it returns an Error.
Parameters
address
- address of the remote devicenum
- number of input bits to readdest
- the result of the reading is stored here
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let mut dest = vec![0u8; 100]; assert!(modbus.read_input_bits(0, 1, &mut dest).is_ok());
fn read_registers(
&self,
address: u16,
num: u16,
dest: &mut [u16]
) -> Result<u16, Error>
[src]
&self,
address: u16,
num: u16,
dest: &mut [u16]
) -> Result<u16, Error>
read_registers
- read many registers
The read_registers()
function shall read the content of the num
holding registers
to the address
of the remote device. The result of reading is stored in dest
slice as u16 word values.
The function uses the Modbus function code 0x03 (read holding registers).
Return value
The function returns a Result
containing the number of read bits if successful. Otherwise it returns an Error.
Parameters
address
- address of the remote devicenum
- number of holding registers to readdest
- the result of the reading is stored here
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let mut dest = vec![0u16; 100]; assert!(modbus.read_registers(0, 1, &mut dest).is_ok());
fn read_input_registers(
&self,
address: u16,
num: u16,
dest: &mut [u16]
) -> Result<u16, Error>
[src]
&self,
address: u16,
num: u16,
dest: &mut [u16]
) -> Result<u16, Error>
read_input_registers
- read many input registers
The read_input_registers()
function shall read the content of the num
holding registers to the address
of the remote device. The result of reading is stored in dest
slice as u16
word values.
The function uses the Modbus function code 0x04 (read input registers). The holding registers and input registers have different historical meaning, but nowadays it’s more common to use holding registers only.
Return value
The function returns a Result
containing the number of read bits if successful. Otherwise it returns an Error.
Parameters
address
- address of the remote devicenum
- number of input registers to readdest
- the result of the reading is stored here
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let mut dest = vec![0u16; 100]; assert!(modbus.read_input_registers(0, 1, &mut dest).is_ok());
fn report_slave_id(
&self,
max_dest: usize,
dest: &mut [u8]
) -> Result<u16, Error>
[src]
&self,
max_dest: usize,
dest: &mut [u8]
) -> Result<u16, Error>
report_slave_id
- returns a description of the controller
The report_slave_id()
function shall send a request to the controller to obtain a
description of the controller. The response stored in dest
contains:
* the slave ID, this unique ID is in reality not unique at all so it's not possible to depend on it to know
how the information are packed in the response.
* the run indicator status (0x00 = OFF, 0xFF = ON)
* additional data specific to each controller. For example, libmodbus returns the version of the library as
a string.
Return value
The function returns a Result
containing the number of read bits if successful. If the output was truncated
due the max_dest
limit then the return value is the number of bytes which would have been written to dest
.
Thus, a return value greater than the max_dest
means that the resonse data was truncated.
Otherwise the Result contains an Error.
Parameters
max_dest
- limit, writemax_dest
bytes from the response todest
dest
- the result of the reading is stored here
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let mut bytes = vec![0u8; Modbus::MAX_PDU_LENGTH]; assert!(modbus.report_slave_id(Modbus::MAX_PDU_LENGTH, &mut bytes).is_ok()); // assert_eq!(bytes, vec![180, 255, 76, 77, 66, 51, 46, 49, 46, 52]));
fn write_bit(&self, address: u16, status: bool) -> Result<(), Error>
[src]
write_bit
- write a single bit
The write_bit()
function shall write the status
at the address
of the remote device.
The value must be set to true
of false
.
The function uses the Modbus function code 0x05 (force single coil).
Return value
The function return an OK Result, containing a one, if successful. Otherwise it contains an Error.
Parameters
address
- address of the remote devicestatus
- status that should write at the addressaddr
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let address = 1; assert!(modbus.write_bit(address, true).is_ok());
fn write_register(&self, address: u16, value: u16) -> Result<(), Error>
[src]
write_register
- write a single register
The write_register()
function shall write the value of value holding registers at
the address addr of the remote device.
The function uses the Modbus function code 0x06 (preset single register).
Return value
The function return an OK Result, containing a one, if successful. Otherwise it contains an Error.
Parameters
address
- address of the remote devicevalue
- vec with the value of the holding register which shall be written
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let address = 1; let value = u16::max_value(); assert!(modbus.write_register(address, value).is_ok());
fn write_bits(&self, address: u16, num: u16, src: &[u8]) -> Result<u16, Error>
[src]
write_bits
- write many bits
The write_bits()
function shall write the status of the bits (coils) from src
at the
address
of the remote device. The src
array must contains bytes set to TRUE or FALSE.
The function shall return the number of written bits if successful. Otherwise it contains an Error.
Return value
The function returns a Ok Result containing the number of written bits. Otherwise it contains an Error.
Parameters
address
- address of the remote devicenum
- number or bits that should be writen at the addressaddress
src
- vec of0
and1
(true and false) values
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let address = 1; let tab_bytes = vec![0u8]; assert_eq!(modbus.write_bits(address, 1, &tab_bytes).unwrap(), 1);
fn write_registers(
&self,
address: u16,
num: u16,
src: &[u16]
) -> Result<u16, Error>
[src]
&self,
address: u16,
num: u16,
src: &[u16]
) -> Result<u16, Error>
write_registers
- write many registers
The write_registers()
function shall write the content of the num
holding
registers
from the array src
at address
of the remote device.
The function uses the Modbus function code 0x10 (preset multiple registers).
Return value
The function returns a Ok Result containing the number of written bytes. Otherwise it contains an Error.
Parameters
address
- address of the remote devicenum
- number of holding registers that should write at the addressaddress
src
- holding register
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let address = 1; let tab_bytes = vec![0u16]; assert_eq!(modbus.write_registers(address, 1, &tab_bytes).unwrap(), 1);
fn write_and_read_registers(
&self,
write_address: u16,
write_num: u16,
src: &[u16],
read_address: u16,
read_num: u16,
dest: &mut [u16]
) -> Result<u16, Error>
[src]
&self,
write_address: u16,
write_num: u16,
src: &[u16],
read_address: u16,
read_num: u16,
dest: &mut [u16]
) -> Result<u16, Error>
write_and_read_registers
- write and read many registers in a single transaction
The write_and_read_registers()
function shall write the content of the
write_nb holding registers from the array src to the address write_addr of the remote device then shall read
the content of the read_nb holding registers to the address read_addr of the remote device. The result of
reading is stored in dest array as word values (16 bits).
The function uses the Modbus function code 0x17 (write/read registers).
Return value
The function returns a Ok Result containing the number of read registers. Otherwise it contains an Error.
Parameters
write_address
- address of the remote devicewrite_num
- number of holding registerssrc
- holding registerread_address
- address of the remote deviceread_num
- number of holding registersdest
- holding register
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let address = 1; let request_bytes = vec![1u16]; let mut response_bytes = vec![0u16]; assert_eq!(modbus.write_and_read_registers( address, 1, &request_bytes, address, 1, &mut response_bytes).unwrap(), 1);
fn mask_write_register(
&self,
address: u16,
and_mask: u16,
or_mask: u16
) -> Result<(), Error>
[src]
&self,
address: u16,
and_mask: u16,
or_mask: u16
) -> Result<(), Error>
mask_write_register
- mask a single register
The mask_write_register()
function shall modify the value of the
holding register at the address address
of the remote device using the algorithm:
new value = (current value AND 'and') OR ('or' AND (NOT 'and'))
The function uses the Modbus function code 0x16 (mask single register).
Return value
The function returns a Ok Result if succesful. Otherwise it contains an Error.
Parameters
address
- address of the remote deviceand_mask
- AND maskor_mask
- OR mask
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); assert!(modbus.mask_write_register(1, 0xF2, 0x25).is_ok());
fn send_raw_request(
&self,
raw_request: &mut [u8],
lenght: usize
) -> Result<u16, Error>
[src]
&self,
raw_request: &mut [u8],
lenght: usize
) -> Result<u16, Error>
send_raw_request
- send a raw request
The send_raw_request()
function shall send a request via the socket of the
current modbus contest.
This function must be used for debugging purposes because you have to take care to make a valid request by hand.
The function only adds to the message, the header or CRC of the selected backend, so raw_request
must start
and contain at least a slave/unit identifier and a function code.
This function can be used to send request not handled by the library.
The enum FunctionCode
provides a list of supported Modbus functions codes, to help
build of raw requests.
Parameters
raw_request
- raw request to sendlength
- raw request length
Return value
The function returns a Result, containing the full message lenght, counting the extra data relating to the backend, if successful. Otherwise it contains an Error.
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP, FunctionCode}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let mut raw_request: Vec<u8> = vec![0xFF, FunctionCode::ReadHoldingRegisters as u8, 0x00, 0x01, 0x0, 0x05]; let mut response = vec![0u8; Modbus::TCP_MAX_ADU_LENGTH]; let request_len = raw_request.len(); assert_eq!(modbus.send_raw_request(&mut raw_request, request_len).unwrap(), 6); assert!(modbus.receive_confirmation(&mut response).is_ok());
fn receive_confirmation(&self, response: &mut [u8]) -> Result<u16, Error>
[src]
receive_confirmation
- receive a confirmation request
The receive_confirmation()
function shall receive a request via the socket of
the context ctx
Member of the Modbus struct.
This function must be used for debugging purposes because the received response isn’t checked against the
initial request.
This function can be used to receive request not handled by the library.
The maximum size of the response depends on the used backend,
in RTU the response
array must be Modbus::RTU_MAX_ADU_LENGTH
bytes and in TCP it must be
Modbus::TCP_MAX_ADU_LENGTH
bytes.
If you want to write code compatible with both, you can use the constant MODBUS_MAX_ADU_LENGTH (maximum value
of all libmodbus backends).
Take care to allocate enough memory to store responses to avoid crashes of your server.
Return value
The function returns a Result containing the response length if successful. The returned request length can be zero if the indication request is ignored (eg. a query for another slave in RTU mode). Otherwise it contains an Error.
Parameters
response
- store for the received response
Examples
use libmodbus_rs::{Modbus, ModbusClient, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let mut response = vec![0u8; Modbus::MAX_ADU_LENGTH]; assert!(modbus.receive_confirmation(&mut response).is_ok());
impl ModbusRTU for Modbus
[src]
fn new_rtu(
device: &str,
baud: i32,
parity: char,
data_bit: i32,
stop_bit: i32
) -> Result<Modbus, Error>
[src]
device: &str,
baud: i32,
parity: char,
data_bit: i32,
stop_bit: i32
) -> Result<Modbus, Error>
new_rtu
- create a libmodbus context for RTU
The new_rtu()
function shall allocate and initialize a structure
to communicate in RTU mode on a serial line.
The device argument specifies the name of the serial port handled by the OS, eg. "/dev/ttyS0" or "/dev/ttyUSB0". On Windows, it’s necessary to prepend COM name with "\." for COM number greater than 9, eg. "\\.\COM10". See http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx for details The baud argument specifies the baud rate of the communication, eg. 9600, 19200, 57600, 115200, etc.
The parity argument can have one of the following values: * N for none * E for even * O for odd
The data_bits argument specifies the number of bits of data, the allowed values are 5, 6, 7 and 8.
The stop_bits argument specifies the bits of stop, the allowed values are 1 and 2.
Once the modbus structure is initialized, you must set the slave of your device with
set_slave()
and connect to the serial bus with connect()
.
Examples
use libmodbus_rs::{Modbus, ModbusRTU}; const YOUR_DEVICE_ID: u8 = 1; let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1).unwrap(); modbus.set_slave(YOUR_DEVICE_ID); match modbus.connect() { Ok(_) => { } Err(e) => println!("Error: {}", e), }
fn rtu_get_serial_mode(&self) -> Result<SerialMode, Error>
[src]
rtu_get_serial_mode
- get the current serial mode
The rtu_get_serial_mode()
function shall return the serial mode currently
used by the libmodbus context:
SerialMode::RtuRS232
the serial line is set for RS232 communication. RS-232 (Recommended Standard 232)
is the traditional name for a series of standards for serial binary single-ended
data and control signals connecting between a DTE (Data Terminal Equipment) and a
DCE (Data Circuit-terminating Equipment). It is commonly used in computer serial ports
SerialMode::RtuRS485
the serial line is set for RS485 communication.
EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the electrical
characteristics of drivers and receivers for use in balanced digital multipoint systems.
This standard is widely used for communications in industrial automation because it can be
used effectively over long distances and in electrically noisy environments.
This function is only available on Linux kernels 2.6.28 onwards and can only be used with a context using a RTU backend.
Examples
use libmodbus_rs::{Modbus, ModbusRTU, SerialMode}; let modbus = Modbus::new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1).unwrap(); assert_eq!(modbus.rtu_get_serial_mode().unwrap(), SerialMode::RtuRS232);
fn rtu_set_serial_mode(&mut self, mode: SerialMode) -> Result<(), Error>
[src]
rtu_set_serial_mode
- set the serial mode
The rtu_set_serial_mode()
function shall set the selected serial mode:
RTU_RS232
the serial line is set for RS232 communication.
RS-232 (Recommended Standard 232) is the traditional name for a series of
standards for serial binary single-ended data and control signals connecting
between a DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating Equipment).
It is commonly used in computer serial ports
RTU_RS485
the serial line is set for RS485 communication.
EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the
electrical characteristics of drivers and receivers for use in balanced digital multipoint systems.
This standard is widely used for communications in industrial automation
because it can be used effectively over long distances and in electrically noisy environments.
This function is only supported on Linux kernels 2.6.28 onwards.
Return value
The function return an OK Result if successful. Otherwise it contains an Error.
Examples
use libmodbus_rs::{Modbus, ModbusRTU, SerialMode}; let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1).unwrap(); assert!(modbus.rtu_set_serial_mode(SerialMode::RtuRS232).is_ok());
fn rtu_set_rts(&mut self, mode: RequestToSendMode) -> Result<(), Error>
[src]
rtu_set_rts
- set the RTS mode in RTU
The rtu_set_rts()
function shall set the Request To Send mode to communicate on a
RS485 serial bus.
By default, the mode is set to RequestToSendMode::RtuRtsNone
and no signal is issued before writing
data on the wire.
To enable the RTS mode, the values RequestToSendMode::RtuRtsUp
or
RequestToSendMode::RtuRtsDown
must be used,
these modes enable the RTS mode and set the polarity at the same time. When
RequestToSendMode::RtuRtsUp
is used,
an ioctl call is made with RTS flag enabled then data is written on the bus after a delay of 1 ms,
then another ioctl call is made with the RTS flag disabled and again a delay of 1 ms occurs.
The RequestToSendMode::RtuRtsDown
mode applies the same procedure but with an inverted RTS flag.
This function can only be used with a context using a RTU backend.
Examples
use libmodbus_rs::{Modbus, ModbusRTU, SerialMode, RequestToSendMode}; let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1).unwrap(); let serial_mode = modbus.rtu_set_serial_mode(SerialMode::RtuRS485); assert!(modbus.rtu_set_rts(RequestToSendMode::RtuRtsUp).is_ok());
fn rtu_get_rts(&self) -> Result<RequestToSendMode, Error>
[src]
rtu_get_rts
- get the current RTS mode in RTU
The rtu_get_rts()
function shall get the current Request To Send mode of the libmodbus
context ctx. The possible returned values are:
* MODBUS_RTU_RTS_NONE
* MODBUS_RTU_RTS_UP
* MODBUS_RTU_RTS_DOWN
This function can only be used with a context using a RTU backend.
Examples
use libmodbus_rs::{Modbus, ModbusRTU, SerialMode}; let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1).unwrap(); assert!(modbus.rtu_set_serial_mode(SerialMode::RtuRS485).is_ok());
fn rtu_set_custom_rts(&mut self, _mode: RequestToSendMode) -> Result<i32, Error>
[src]
rtu_set_custom_rts
- set a function to be used for custom RTS implementation
The modbus_rtu_set_custom_rts() function shall set a custom function to be called when the RTS pin is to be set before and after a transmission. By default this is set to an internal function that toggles the RTS pin using an ioctl call.
Note that this function adheres to the RTS mode, the values MODBUS_RTU_RTS_UP or MODBUS_RTU_RTS_DOWN must be used for the function to be called.
This function can only be used with a context using a RTU backend.
TODO: implement rtu_set_custom_rts()!
fn rtu_get_rts_delay(&self) -> Result<i32, Error>
[src]
rtu_get_rts_delay
- get the current RTS delay in RTU
The rtu_get_rts_delay()
function shall get the current
Request To Send delay period of the libmodbus context ctx.
This function can only be used with a context using a RTU backend.
Return value
The rtu_get_rts_delay()
function shall return the current RTS delay in
microseconds
if successful. Otherwise it shall return ModbusError::NotRTU
.
Examples
use libmodbus_rs::{Modbus, ModbusRTU}; let modbus = Modbus::new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1).unwrap(); modbus.rtu_get_rts_delay();
fn rtu_set_rts_delay(&mut self, us: i32) -> Result<(), Error>
[src]
rtu_set_rts_delay
- get the current RTS delay in RTU
The rtu_set_rts_delay()
function shall set the Request To Send delay period of
the libmodbus context.
This function can only be used with a context using a RTU backend.
Return value
The rtu_set_rts_delay()
function return an OK Result if successful. Otherwise it
contains an Error.
Examples
use libmodbus_rs::{Modbus, ModbusRTU}; let mut modbus = Modbus::new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1).unwrap(); let _ = modbus.rtu_set_rts_delay(100).unwrap();
impl ModbusServer for Modbus
[src]
fn receive(&self, request: &mut [u8]) -> Result<i32, Error>
[src]
receive
- receive an indication request
The receive()
function shall receive an indication request from the socket of the context
ctx.
This function is used by Modbus slave/server to receive and analyze indication request sent by the
masters/clients.
If you need to use another socket or file descriptor than the one defined in the context ctx, see the function
set_socket()
.
Examples
use libmodbus_rs::{Modbus, ModbusServer, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let mut query = vec![0; Modbus::MAX_ADU_LENGTH as usize]; assert!(modbus.receive(&mut query).is_ok());
fn reply(
&self,
request: &[u8],
request_len: i32,
modbus_mapping: &ModbusMapping
) -> Result<i32, Error>
[src]
&self,
request: &[u8],
request_len: i32,
modbus_mapping: &ModbusMapping
) -> Result<i32, Error>
modbus_reply
- send a reponse to the received request
The reply()
function shall send a response to received request. The request req given in
argument is analyzed, a response is then built and sent by using the information of the modbus context ctx.
If the request indicates to read or write a value the operation will done in the modbus mapping mb_mapping
according to the type of the manipulated data.
If an error occurs, an exception response will be sent.
This function is designed for Modbus server.
Examples
use libmodbus_rs::{Modbus, ModbusServer, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let mut query = vec![0; Modbus::MAX_ADU_LENGTH as usize]; assert!(modbus.receive(&mut query).is_ok());
impl ModbusTCPPI for Modbus
[src]
fn new_tcp_pi(node: &str, service: &str) -> Result<Modbus, Error>
[src]
new_tcp_pi
- create a libmodbus context for TCP Protocol Independent
The new_tcp_pi()
function shall allocate and initialize a modbus_t structure to
communicate with a Modbus TCP IPv4 or IPv6 server.
The node argument specifies the host name or IP address of the host to connect to, eg. "192.168.0.5" , "::1" or "server.com". A NULL value can be used to listen any addresses in server mode.
The service argument is the service name/port number to connect to. To use the default Modbus port use the string "502". On many Unix systems, it’s convenient to use a port number greater than or equal to 1024 because it’s not necessary to have administrator privileges.
Examples
use libmodbus_rs::{Modbus, ModbusTCPPI}; let modbus = Modbus::new_tcp_pi("::1", "1502").unwrap(); match modbus.connect() { Ok(_) => {} Err(e) => println!("Error: {}", e), }
fn tcp_pi_accept(&mut self, socket: &mut i32) -> Result<i32, Error>
[src]
tcp_pi_accept
- accept a new connection on a TCP PI Modbus socket (IPv6)
The tcp_pi_accept()
function shall extract the first connection on the
queue of pending connections and create a new socket given as argument.
Parameters
socket
- Socket
Examples
use libmodbus_rs::{Modbus, ModbusMapping, ModbusServer, ModbusTCPPI}; let mut modbus = Modbus::new_tcp_pi("::0", "1502").unwrap(); let mut socket = modbus.tcp_pi_listen(1).unwrap(); modbus.tcp_pi_accept(&mut socket).unwrap();
fn tcp_pi_listen(&mut self, num_connection: i32) -> Result<i32, Error>
[src]
tcp_pi_listen
- create and listen a TCP PI Modbus socket (IPv6)
The tcp_pi_listen()
function shall create a socket and listen to maximum
num_connection
incoming connections on the specifieded node.
Parameters
num_connection
- maximum number of incoming connections on the specified IP address
If node is set to ""
or 0.0.0.0
, any addresses will be listen.
Examples
For detailed examples, look at the examples directory of this crate.
- unit-test-server.rs - simple but handle only one connection
- bandwidth-server-many-up.rs - handles several connection at once
use libmodbus_rs::{Modbus, ModbusMapping, ModbusServer, ModbusTCPPI}; let mut modbus = Modbus::new_tcp_pi("::0", "1502").unwrap(); let mut socket = modbus.tcp_pi_listen(1).unwrap(); modbus.tcp_pi_accept(&mut socket); let modbus_mapping = ModbusMapping::new(500, 500, 500, 500).unwrap(); let mut query = vec![0u8; Modbus::MAX_ADU_LENGTH as usize]; loop { let request_len = modbus.receive(&mut query).unwrap(); modbus.reply(&query, request_len, &modbus_mapping); }
impl ModbusTCP for Modbus
[src]
fn new_tcp(ip: &str, port: i32) -> Result<Modbus, Error>
[src]
new_tcp
- create a libmodbus context for TCP/IPv4
The new_tcp()
function shall allocate and initialize a modbus_t structure
to communicate with a Modbus TCP IPv4 server.
The ip argument specifies the IP address of the server to which the client wants to
establish a connection. A empty string ""
value can be used to listen any addresses in server mode.
The port argument is the TCP port to use. Set the port to MODBUS_TCP_DEFAULT_PORT
to use the default one (502). It’s convenient to use a port number greater than or
equal to 1024 because it’s not necessary to have administrator privileges.
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; let modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let modbus = Modbus::new_tcp("127.0.0.1", Modbus::TCP_DEFAULT_PORT as i32).unwrap(); match modbus.connect() { Ok(_) => { } Err(e) => println!("Error: {}", e), }
fn tcp_accept(&mut self, socket: &mut i32) -> Result<i32, Error>
[src]
tcp_accept
- accept a new connection on a TCP Modbus socket (IPv4)
The tcp_accept()
function shall extract the first connection on the
queue of pending connections and create a new socket given as argument.
Parameters
socket
- Socket
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let mut socket = modbus.tcp_listen(1).unwrap(); modbus.tcp_accept(&mut socket);
fn tcp_listen(&mut self, num_connection: i32) -> Result<i32, Error>
[src]
tcp_listen
- create and listen a TCP Modbus socket (IPv4)
The tcp_listen()
function shall create a socket and listen to maximum
num_connection
incoming connections on the specified IP address.
If IP address is set to NULL or '0.0.0.0', any addresses will be listen.
Parameters
num_connection
- maximum number of incoming connections on the specified IP address
Examples
use libmodbus_rs::{Modbus, ModbusTCP}; let mut modbus = Modbus::new_tcp("127.0.0.1", 1502).unwrap(); let socket = modbus.tcp_listen(1);
impl Debug for Modbus
[src]
fn fmt(&self, __arg_0: &mut Formatter) -> Result
[src]
Formats the value using the given formatter. Read more