I am trying to get perl and arduino talking via serial, but I am running into an issue.
If I disconnect the USB cable (going to the arduino) after the Perl script has successfully connected to the arduino, I am unable to re-establish a serial connection to the arduino via the Perl script. I can connect using the Serial Monitor though. The only way I am able to get the Perl script to talk to the arduino again is to re-upload the sketch to the arduino. I'm not sure if I need to change the sketch or the Perl script to account for this issue.
Here is a sample of the arduino sketch:
//Receive a 16 character string via serial, then print it back
#define baudrate 57600
char inData[15]; // Allocate space for incoming serial data
char *IRCode[3];
char inByte; // Incoming serial character
byte index = 0; // Index into array; where to store the character
void setup(){
Serial.begin(baudrate);
}
void loop() {
while (Serial.available() > 0){
inByte = Serial.read ();
inData[index] = inByte;
index++;
if (index > 15 || inByte == 10 || inByte == 13){
inData[index] = '\0'; //Null terminate the string
Serial.println(inData);
index = 0;
}
}
}
**And here is the perl script (Windows). ** I tried to add a mechanism to retry opening the port, but the only thing I could figure out to make it reconnect was to re upload the sketch.
use warnings;
use strict;
use Time::HiRes;
use Win32::Serialport;
my $debug = 1;
my $SerialPortObj = detectArduinoBoard('COM9');
my $serialDiscoveryAttempts = 0;
sub detectArduinoBoard{
if ($serialDiscoveryAttempts++ == 10){
die "Giving up after 10 connection attempts\n";
}
my @ports = shift;
my $sPort;
my $iteration = 1;
foreach (@ports){
die "No Arduino detected\n" unless $_;
print "Attempting handshake with $_\n";
#determine which port Arduino is attached to
$sPort = Win32::SerialPort->new($_);
Time::HiRes::usleep(250);
if ($sPort){
print "\tConnecting to $_\n";
$sPort->databits(8);
$sPort->baudrate(57600);
$sPort->parity("none");
$sPort->stopbits(1);
my ($BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags) = $sPort->status || print "could not get port status\n";
$sPort->lookclear; #empty buffer
Time::HiRes::usleep(250);
$sPort->write('XXX:XXXXXXXX:XXX');
Time::HiRes::usleep(250);
my $incoming = '';
while (length($incoming) < 16){
$incoming = $sPort->lookfor();
#print "|$incoming|\n";
Time::HiRes::usleep(1000);
$iteration++;
if ($iteration > 20){
print "\t$incoming\n";
print "\tTimed out. Retrying\n";
$sPort->restart();
$sPort->close();
detectArduinoBoard(@ports);
}
}
if ($incoming){
$incoming =~ /([A-Z0-9]{3}):([A-Z0-9]{8}):([A-Z0-9]{3})/;
$incoming = $1 . ':' . $2 . ':' . $3;
}
if ( $incoming eq 'XXX:XXXXXXXX:XXX'){
print "\tHandshake with $_ successful\n" if $debug;
print "\tReceived: $incoming from Arduino\n";
print "\tdetectArduinoBoard() complete\n" if $debug;
$serialDiscoveryAttempts = 0;
return $sPort;
} else {
print "\tHandshake with $_ failed\n" if $debug;
return undef;
}
}
}
}