The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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.

INSTALL

You can install this module from:

CPAN, the easy way:

    sudo perl -MCPAN -e'install MBclient'

GitHub:

    git clone https://github.com/sourceperl/MBclient.git
    cd MBclient
    perl Makefile.PL
    make
    make test
    sudo make install

DEPENDENCIES

This module requires no other module or librarie.

It's pure Perl code without any extension.

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.

new()

new() create an MBclient object.

Example: my $m = MBclient->new();

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);

timeout(TIMEOUT)

Use to set modbus read timeout : 30 default value.

Timeout defines how long will read wait until it exits and aborts communication.

Example: $m->timeout(5);

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(0x45, 1);
  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(0x66, 2);
  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(0x100, 4);
  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/

AUTHOR

Loic Lefebvre, <lle@cpan.org>

COPYRIGHT & LICENSE

Copyright 2014 Loic Lefebvre

The MIT License (MIT)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.