• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1706
  • Last Modified:

Send command to SerialPort and read answer

Hello,

I am trying to write a PERL script that sends 1-2 commands to a COM port that in turn must be read the output from and processed(different script).

Any idea on how I might acomplish this?

I found the examples for Win32::SerialPort a bit confusing since it was only setting it up, no example on how to send command and read output from it.


Thanks in advance!
0
TheFlyingCorpse
Asked:
TheFlyingCorpse
  • 5
  • 4
1 Solution
 
Adam314Commented:
Use the read and write methods...

From the documentation:
#Find how many bytes are waiting (and some other stuff)
($BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags) = $PortObj->status
  || warn "could not get port status\n";
 
#Read bytes, give warning if error
($count_in, $string_in) = $PortObj->read($InBytes);
warn "read unsuccessful\n" unless ($count_in == $InBytes);
#Now, $string_in contains the now bytes
 
 
#Write bytes, give warning if error
$count_out = $PortObj->write($output_string);
warn "write failed\n"         unless ($count_out);
warn "write incomplete\n"     if ( $count_out != length($output_string) );

Open in new window

0
 
TheFlyingCorpseAuthor Commented:
so if I want to use the following 2 commands, how would I then execute them in the script?
(I've only written scripts for local checking and webchecking before, never touched SerialPort in any form)
1st command: AT
2nd command: AT!TEST?

I want do use the output of the 2nd command in code I already have, as long as I can get it from a file or variable from this part.
0
 
Adam314Commented:

#Create $PortObj, and set it's properties here
 
#Send first command
my $StrToSend = 'AT';
my $count_out = $PortObj->write($StrToSend);
die "Tried to write ".length($StrToSend)." bytes, but wrote $count_out bytes\n"
  unless ($count_out and ($count_out == length($StrToSend));
 
#Do you need to check that the command was successful?
#If so, do that here.  I thought you should get an "OK" response back.
 
$StrToSend='AT!TEST?';
$count_out = $PortObj->write($StrToSend);
die "Tried to write ".length($StrToSend)." bytes, but wrote $count_out bytes\n"
  unless ($count_out and ($count_out == length($StrToSend));
 
#Find how many bytes are waiting (and some other stuff)
($BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags) = $PortObj->status
  || die "could not get port status\n";
 
#Read bytes, give warning if error
($count_in, $string_in) = $PortObj->read($InBytes);
die "read unsuccessful\n" unless ($count_in == $InBytes);
 
#You can now use $string_in

Open in new window

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
TheFlyingCorpseAuthor Commented:
How does this look as a solution?

I added the part with use Win32::SerialPort, what port and also an attempt to verify that the AT command recieves an OK before issuing the AT!TEST?


I have yet to test it on the computer that is to use it. (didnt bring it home from work), will drop by work tomorrow even though its a global holiday ;)

#Create $PortObj, and set it's properties here
 
use Win32::SerialPort
 
$PortName = "COM1";
 
$PortObj = new Win32::SerialPort ($PortName) 
     || die "Can't open $Portname: $^E\n";
 
#Send first command
my $StrToSend = 'AT';
my $count_out = $PortObj->write($StrToSend);
die "Tried to write ".length($StrToSend)." bytes, but wrote $count_out bytes\n"
  unless ($count_out and ($count_out == length ($StrToSend));
 
#Find how many bytes are waiting (and some other stuff)
($BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags) = $PortObj->status
  || die "could not get port status\n";
 
#Read bytes, give warning if error
($count_in, $string_in) = $PortObj->read($InBytes);
die "read unsuccessful\n" unless ($count_in == $InBytes);
if ($string_in = 'OK') {
 
#Send command for test 
$StrToSend='AT!TEST?';
$count_out = $PortObj->write($StrToSend);
die "Tried to write ".length($StrToSend)." bytes, but wrote $count_out bytes\n"
  unless ($count_out and ($count_out == length ($StrToSend));
 
#Find how many bytes are waiting (and some other stuff)
($BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags) = $PortObj->status
  || die "could not get port status\n";
 
#Read bytes, give warning if error
($count_in, $string_in) = $PortObj->read($InBytes);
die "read unsuccessful\n" unless ($count_in == $InBytes);
 } else {
print "Failed to communicate with the COM-port\n";
}
#You can now use $string_in

Open in new window

0
 
Adam314Commented:
It looks okay to me.
0
 
TheFlyingCorpseAuthor Commented:
ok, thanks :-)

Btw, i am unable to compile Win32::Serialport.
I get an error with it that it cannot find the html base directory, even though I've added it to the makefile.
I've tried it both on the computer in question and in a VMware instance.
I use the Strawberry-perl distro, also tried with the ActivePerl but havent got as far with that since there is no Win32::SerialPort already compiled for it.

I can open a different question for it if you want me to, but it would be really nice if I could get it to work!
0
 
Adam314Commented:
Looks like it is available here for ActiveState already compiled:
    http://www.bribes.org/perl/ppm/Win32-SerialPort.ppd

I'm not sure of the problem with the strawberry when you compile. You you have permission to write to the html directory?  Does it tell you what directory it expect for the html base directory?  Is it relative, or absolute?
0
 
TheFlyingCorpseAuthor Commented:
The expert was able to give a proper and very usable solution to my question, with a good understanding of the solution.
0
 
TheFlyingCorpseAuthor Commented:
I added the bribes repo, that solved the issue with the Win32::SerialPort.

It works now, thank you!
0
 
JCaturiaCommented:
Did you notice that in line #23 of your code above you are not doing a comparison, but an assignment?

if ($string_in = 'OK') {

This will _never_ fail - which defeats your purpose I'm sure.. :) Just thought you should know! You may have already fixed it, since the thread is so old.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now