The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

MBclient - Add modbus TCP or RTU functions for your program.

SYNOPSIS

  use strict;
  use MBclient;

  my $m = MBclient->new();
  # define server target
  $m->host("localhost");
  $m->unit_id(1);

  # read 16 bits register from ad 0 to 9
  my $words = $m->read_holding_registers(0, 10);

  # print words
  foreach my $word (@$words) {
    print $word."\n";
  }

  # clean exit
  $m->close();
  exit 0;

DESCRIPTION

Modbus is a standard serial communication protocol used to interconnect industrial PLC (and a lot of other things). This module gives you access to TCP and RTU version of this protocol, through the MBclient object.

You can have a look at http://en.wikipedia.org/wiki/Modbus for details.

USAGE

How you might use this

Here is how you might use the MBclient module.

First you have to create the object, and to set main params : host, port and unit_id.

Then call open() function, or directly a "modbus function". In any case, you have to call the close() method, in order to cleanly close the TCP link.

Functions

The following functions are defined in the MBclient module. Most of them are public, meaning that you're supposed to use them. Some are private, meaning that you're not supposed to use them. Assume that functions are public unless otherwise documented.

open()

open() funtion open the TCP link. If the TCP link is up when the function is called a close/open cycle is initiated.

This function return undef in case of error.

Example: $m->open();

is_open()

is_open() return True if TCP link is open, False when TCP is closed

Example: $m->is_open();

close()

close() function close the TCP link.

Return True if success, undef if error.

Example: $m->close();

mode(MODBUS_MODE)

Use to set modbus mode : TCP (default value) or RTU (add crc16 on every frame).

2 constants are import with this module MODBUS_TCP and MODBUS_RTU. Use it to define modbus mode.

Example: $m->mode(MODBUS_RTU);

host(hostname)

Use to set server IPv4 like "192.168.0.1" or URL name like "plc1.domain.net".

Return "hostname" if success, undef in other case.

Example: $m->host("192.168.0.1");

You can read hostname property if you call host() without arg.

port(port)

Use to set server port (default is 502).

Return "port" if success, undef in other case.

Example: $m->port(888);

You can read port property if you call port() without arg.

unit_id(uid)

Use to set server modbus unit id (default is 1).

Return "uid" if success, undef in other case.

Example: $m->unit_id(1);

You can read port property if you call unit_id() without arg.

last_error()

last_error() return last error on MBclient object.

See source code for "module error code" list.

Each error is a constant import in your program, so you can do thing like:

  if ($m->last_error() == MB_RESOLVE_ERR) {
    print "unable to resolve name\n";
    exit 2;
  }
last_except()

last_except() return last modbus exception code.

See source code for "modbus except code" list.

Each except is a constant import in your program, so you can do thing like:

  if ($m->last_except() == EXP_GATEWAY_PATH_UNAVAILABLE) {
    print "check your modbus gateway please\n";
    exit 3;
  }
version()

version() return current version.

Example: print $m->version();

read_coils(bit_addr, bit_nb)

read_coils() is standard modbus function 1.

This funtion read "bit_nb" number of bits at "bit_addr" bit address.

Return a ref to a bits array or undef if error.

Example read 10 bits at address 55:

  my $bits = $m->read_coils(55, 10);
  foreach my $bit ($@bits) {
    print $bit."\n";
  }
read_discrete_inputs(bit_addr, bit_nb)

read_discrete_inputs() is standard modbus function 2.

This funtion read "bit_nb" number of bits at "bit_addr" bit address.

Return a ref to a bits array or undef if error.

Example read 1 bit at hex address 45:

  my $bits = $m->read_discrete_inputs(1, 0x45);
  if ($bits) {
    print $$bits[0]."\n";
  } else {
    print "error code: ".$m->last_error()."\n";
  }
read_holding_registers(reg_addr, reg_nb)

read_holding_registers() is standard modbus function 3.

This funtion read "reg_nb" number of registers at "reg_addr" register address.

Return a ref to a registers array or undef if error.

Example read 2 registers at hex address 66:

  my $regs = $m->read_holding_registers(2, 0x66);
  foreach my $reg ($@regs) {
    print $reg."\n";
  }
read_input_registers(reg_addr, reg_nb)

read_input_registers() is standard modbus function 4.

This funtion read "reg_nb" number of registers at "reg_addr" register address.

Return a ref to a registers array or undef if error.

Example read 4 registers at hex address 100:

  my $regs = $m->read_input_registers(4, 0x100);
  foreach my $reg ($@regs) {
    print $reg."\n";
  }
write_single_coil(bit_addr, bit_value)

write_single_coil() is standard modbus function 5.

This funtion write "bit_value" (0 or 1) to "bit_addr" bit address.

Return True if write success, undef if error.

Example write 1 on bit at address 45:

  if ($m->write_single_coil(45, 1)) {
    print "write success\n";
  } else {
    print "write error\n";
  }
write_single_register(reg_addr, reg_value)

write_single_register() is standard modbus function 6.

This funtion write "reg_value" register value to "reg_addr" register address.

Return True if write success, undef if error.

Example write 578 on register at address 55:

  if ($m->write_single_register(55, 578)) {
    print "write success\n";
  } else {
    print "write error\n";
  }
write_multiple_registers(reg_addr, ref_array_reg)

write_multiple_registers() is standard modbus function 16.

This funtion write an array of register with reference to this array in "ref_array_reg" at "reg_addr" register address.

Return True if write success, undef if error.

Example write 3 registers at address 780:

  my @to_write = (45, 22, 33);
  if ($m->write_multiple_registers(780, \@to_write)) {
    print "write success\n";
  } else {
    print "write error\n";
  }
_mbus_frame(fc, body)

PRIVATE

Build the modbus frame. Called with "fc" as function code and "body" as modbus body frame.

Return the modbus frame or undef if error.

_send_mbus(frame)

PRIVATE

Send "frame" over the current socket with debug pretty print option.

Return the number of byte send or undef if error.

_recv_mbus()

PRIVATE

Receive modbus frame.

Return body of the modbus frame.

_send(data)

PRIVATE

Send "data" over the current socket.

Return the number of byte send or undef if error.

_recv(max_size)

PRIVATE

Receive "max_size" bytes of data from the current socket.

Return receive buffer or undef if error.

_can_read()

PRIVATE

This function wait for data available on socket, block for a max of timeout second.

_crc(frame)

PRIVATE

This function compute crc16 for arg "frame".

Return crc16.

_add_crc(frame)

PRIVATE

Return modbus arg "frame" with crc16 at the end.

_crc_is_ok(frame)

PRIVATE

Check the crc16 of modbus arg frame.

Return True if crc16 is ok, False in other case.

_pretty_dump(label, data)

PRIVATE

Print modbus/TCP frame in pretty format.

NOTES

- The file "examples/read_10_reg.pl " is provided as a basic script. You can use it as a skeleton to start writing a modbus script.

- Advance users can enable debug messages with $m->{debug}=1;

BUGS

Thanks to report issues at https://github.com/sourceperl/MBclient/