Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
01-16-2004, 05:37 AM
|
#1
|
LQ Newbie
Registered: Jan 2004
Posts: 2
Rep:
|
Sending commands and viewing replies from a serial-attached appliance
Hi everybody.
I need to communicate with an appliance, the consolle port of which is linked to my RedHat 7.2 system's serial port.
I started writing a Perl programs that uses the basic filehandle syntax
open(PORTA, "+</dev/ttyS0");
...
print PORTA $stringout;
...
$answer = <PORTA>;
I tested it connecting my serial port to a Windows workstation running Hyperterminal, and it worked out ok!
Sadly, when I tried it on the needed connection, I got absolutely no response from the appliance.
I blamed it on the different serial port configuration requested by the appliance (9600 bps, 8-bit, 1-stop, no parity, “flow control” = none), and so I turned to the more sophisticated "Device::SerialPort" module, which should provide the right tools to set the port parameters.
I tested it again using Hyperterminal but this time, though I managed to get my strings sent, the replies I sent from the Windows hyperterminal never reached my Linux PC...naturally, it didn't work with the appliance either.
I must certainly be going wrong somewhere, but I have no clue at all.
Could you please help?
I attach hereby the two versions of the program (both of which read the strings that must be sent from an input text file) and the script I used to set the port parameters.
Thank you very much in advance.
Best regards
Bruno
-------
serial_old.pl - The first version of the program
================================================
#!/usr/bin/perl -w
# Routines
# comunicate: adds a customary terminator to the string, which is then sent to
# the serial port, the standard output and the logfile; finally it reads the
# reply coming from the serial port and prints it on the standard output and
# the logfile
sub comunicate{
$terminator = "\n";
$stringout = $_[0].$terminator;
print PORTA $stringout;
print "Sent: $stringout\n";
print FOUT "Sent: $stringout\n";
ascspell($stringout);
$answer = <PORTA>;
print "Received: $answer\n";
print FOUT "Received: $answer\n";
ascspell($answer);
}
# ascspell: displays the ASCII codes for each character in a given string
sub ascspell{
@array = unpack("C*", $_[0]);
print "[";
foreach $ch (@array) {
print "$ch ";
print FOUT "$ch ";
}
print "]\n";
}
# Main
open(FIN,$ARGV[0])
or
die ("error opening input file because: $!");
@inner = <FIN>;
close(FIN);
open(FOUT, "+>serial_old.log");
open(PORTA, "+</dev/ttyS0");
foreach $riga (@inner)
{
chomp($riga);
comunicate($riga);
}
close(PORTA);
close(FOUT);
============
serconf.pl - The script that sets the port parameters and writes them to a config file
======================================================================================
#!/usr/bin/perl -w
use Device::SerialPort;
# Initialisation
$PortName="/dev/ttyS0";
$ConfigurationFileName="./ttyS0.conf";
$quiet=1;
$lockfile="./lock";
$PortObj = new Device::SerialPort ($PortName, $quiet, $lockfile)
|| die "Can't open $PortName: $!\n";
$PortObj->user_msg(ON);
$PortObj->databits(8);
$PortObj->baudrate(9600);
$PortObj->parity("none");
$PortObj->stopbits(1);
$PortObj->handshake("rts");
print "Given configuration\n\n";
print "Port Name: $PortName\n";
$baud = $PortObj->baudrate;
$parity = $PortObj->parity;
$data = $PortObj->databits;
$stop = $PortObj->stopbits;
$hshake = $PortObj->handshake;
print "B = $baud, D = $data, S = $stop, P = $parity, H = $hshake\n";
$PortObj->write_settings;
$PortObj->save($ConfigurationFileName) || warn "Can't save $ConfigurationFileName: $!\n";
=========================================================================================
serial.pl - The Device::SerialPort version
==========================================
#!/usr/bin/perl -w
use Device::SerialPort;
# Routines
# comunicate: adds a customary terminator to the string, which is then sent to
# the serial port, the standard output and the logfile; finally it reads the
# reply coming from the serial port and prints it on the standard output and
# the logfile
sub comunicate{
$terminator = "\n";
$stringout = $_[0].$terminator;
print PORTA $stringout;
print "Sent: $stringout\n";
print FOUT "Sent: $stringout\n";
ascspell($stringout);
$answer = <PORTA>;
print "Received: $answer\n";
print FOUT "Received: $answer\n";
ascspell($answer);
}
# ascspell: displays the ASCII codes for each character in a given string
sub ascspell{
@array = unpack("C*", $_[0]);
print "[";
foreach $ch (@array) {
print "$ch ";
print FOUT "$ch ";
}
print "]\n";
}
# Initialisation
$cfgfile="./ttyS0.conf"; # created by serconf.pl
$PortObj= tie(*PORTA,'Device::SerialPort', $cfgfile)
|| die "Can't start $cfgfile\n";
my $name= $PortObj->alias;
my $baud = $PortObj->baudrate;
my $parity = $PortObj->parity;
my $data = $PortObj->databits;
my $stop = $PortObj->stopbits;
my $hshake = $PortObj->handshake;
print "Port: $name\nB = $baud, D = $data, S = $stop, P = $parity, H = $hshake\n";
# Main
open(FIN,$ARGV[0])
or
die ("error opening input file because: $!");
@inner = <FIN>;
close FIN;
open(FOUT, "+>serial.log");
foreach $riga (@inner)
{
chomp($riga);
comunicate($riga);
}
close PORTA || print "port close failed\n";
undef $PortObj;
untie *PORTA;
close FOUT;
|
|
|
01-17-2004, 09:07 AM
|
#2
|
Moderator
Registered: Aug 2002
Posts: 26,336
|
I do not know Perl very well so I will leave debugging to others.
Make sure the appliance end of the serial interface is configured correctly. Even though it works with Hyperterminal do you need any jumpers for DTR etc? But since you said it didn't require flow control that probably isn't a problem. Do you need to reverse the TX/RX pins between going from the appliance to PC? (Just trying to cover everything so please do not take offense)
Make sure the string your transmitting to the appliance is the correct command and syntax.
Is it possible to communicate between Hyperterminal and the appliance just to make sure your commands are correct?
|
|
|
01-19-2004, 03:11 AM
|
#3
|
LQ Newbie
Registered: Jan 2004
Posts: 2
Original Poster
Rep:
|
michaelk wrote:
> Make sure the appliance end of the serial interface is configured correctly.
It is: it's the same cable I used to connect it to the Hyperterminal
> Even though it works with Hyperterminal do you need any jumpers for
> DTR etc?
Mmm...no, it has no jumpers
> But since you said it didn't require flow control that probably isn't a
> problem. Do you need to reverse the TX/RX pins between going from the
> appliance to PC? (Just trying to cover everything so please do not take
> offense)
I don't think so because, as I said before, the cable is working fine, and so is the transmission between the appliance and the Windows PC
> Make sure the string your transmitting to the appliance is the correct
> command and syntax.
> Is it possible to communicate between Hyperterminal and the appliance
> just to make sure your commands are correct?
Actually it seems that transmission IS working: when I connected to the appliance via Hyperterminale after one run of my Perl script, the situation was the one I expected. In fact, I found myself logged in, while prior to the execution of the script I was not.
As a matter of fact, the problem seems to be I can send, but I'm not able to receive!
Thank you very much for your attention!
Best regards
Bruno
|
|
|
01-19-2004, 12:00 PM
|
#4
|
Member
Registered: Jun 2003
Location: Long Island, NY
Distribution: Gentoo Unstable (what a misnomer)
Posts: 380
Rep:
|
Try taking a look at the hex output of the device.
gtkterm is a nice hyperterm like program for dealing
with this kind of thing and it can output what it
recieves in hex.
http://www.jls-info.com/julien/linux/
You can build a protocol analyser which is really helpful for
debugging this sort of thing
http://www.beyondlogic.org/protocola...olanalyser.htm
Hook everything up and see where your program output differs
Edit:
Put in the url for gtkterm
Last edited by LogicG8; 01-19-2004 at 12:01 PM.
|
|
|
All times are GMT -5. The time now is 11:34 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|