PaulNg has asked for the wisdom of the Perl Monks concerning the following question:

Latest update: Hi all, It's not the negative values that is throwing it off, rather the ff (Ascii chr 255) that the Telnet.pm can't seem to send! Can anyone advise me how can I do this? Thanks

Hi all,

I'm having problems with Telnet.pm and negative values. For some unknown reason, the reply in the buffer seems to be dropping characters, even a send doesn't seem to be sending correctly as the value on the controller did not respond. However, using a simulator, the value seems to have been sent correctly. Does anyone know why? All help is greatly appreciated. The controller I'm connected to is a WATLOW F4.

---MODBUS Packet details--- Slave address: 1 Read Write: 6 Start Address 1: 01 Start Address 2: 2c Value 1: ff Value 2: 9b CRC 1: 73 CRC 2: 164 ASCII characters sent: !,ÿI¤! Buff data: !,I¤!
$data = join('',@buffor); #M +odbus frame to scalar # chomp($data); print "ASCII characters sent: !$data!\n"; if ($Telnet) { $pass=$ob->print($data) or warn "Modbus client : problem with send: $! +\n"; } else { $pass=$ob->write($data) or warn "Modbus client : problem with send: $! +\n"; } if ($Telnet) { # Telnet $TimeOut = int($TimeOut / 1000); # Con +vert to seconds $ob->errmode('return'); my $i = 0; do { $Buffer = $ob->get(TimeOut => 1); print "Buff data: !$Buffer!\n"; if (defined($Buffer)) { $i = 0; $Reply .= $Buffer; } else { $i++; } } until ((! defined($Buffer) and $i >= $TimeOu +t) or length($Reply) >= 8);

Replies are listed 'Best First'.
Re: Telnet.pm and Negative Values for Modbus
by thundergnat (Deacon) on Feb 23, 2012 at 19:20 UTC

    I must confess, I'm somewhat mystified how this could work at all (unless you are leaving out an awful lot of details.)

    Net::Telnet communicates using sockets in TCP over ethernet. The Watlow F4 only has RS232 or RS485 support built in. Are you communicating through a protocol converter? Or to a Modbus Master controller which is doing pass-through to the F4? Or something else?

    Net::Telnet doesn't seem like such a great choice anyway for Modbus TCP. Telnet is generally geared toward ASCII (not absolutely, but in general,) and Modbus deals with raw, byte encoded hexadecimal strings. It probably isn't impossible to make it work, but it seems less than ideal.

    Anyway, for anyone to give you better help, you are going to need to supply more detail about exactly what you are trying to do, what you expect to get, and what you are actually getting.

      Hi thndergnat, I'm using ModBus RTU via a Digi CM-32 NTS. Basically I telnet onto the port and transmit the data over the Telnet line using ASCII characters. Weird enough it works perfectly with positive integers but once I use negative values, it seems to have a lot of problems. @buffor is the buffer I'm using to hold the data and it's a global array. Thanks for the help! Regards, Paul.
      $buffor[0] = chr($slave_add); $buffor[1] = chr($readwrite); my $pack_val = unpack("H*",pack("n",$start_add)); my $tmp1= (substr $pack_val, 0, 2); my $tmp2= (substr $pack_val, 2, 2); $buffor[2] = chr(hex (substr $pack_val, 0, 2)); $buffor[3] = chr(hex (substr $pack_val, 2, 2)); $pack_val = unpack("H*",pack("n",$quantity)); my $tmp3= (substr $pack_val, 0, 2); #FF my $tmp4= (substr $pack_val, 2, 2); #EB $buffor[4] = chr(hex (substr $pack_val, 0, 2)); $buffor[5] = chr(hex (substr $pack_val, 2, 2)); $buffor[6] = chr(CRC_calc(1)); $buffor[7] = chr(CRC_calc(0)); my $tmp5 = CRC_calc(1); my $tmp6 = CRC_calc(0);
Re: Telnet.pm and Negative Values for Modbus
by thundergnat (Deacon) on Feb 24, 2012 at 15:52 UTC

    Regarding your update. Character 255 is the Telnet IAC (Interpret as Command) escape character. Telnet commands are two byte sequences with the IAC as the first byte and the command character as the second byte. You may be able to get away with just doubling the IAC character whenever you want send it (\xff) as data. If that doesn't work, you'll probably need to not use Telnet and just set up your own raw TCP connections using IO::Socket or an equivalent.