Problem Reading Serial with Perl

This is probably something simple. I can write to the serial port easy in the perl script. I can't seem to read from it though.

The Arduino code works fine from the Arduino17 IDE serialmonitor. I know the problem is in the perl code because i used this exact code in a C# program that i made that works fine.

Example: perl arduino.pl test

This will send ~test~ to the arduino It will strip the '~' chars from it (used as terminal chars) Then shoot it back to me "test"

Perl Code

# Arduino Bridge

my $msg = shift;

use Device::SerialPort;
use strict;
use warnings;

my $result;


# Set up the serial port
# 19200, 81N on the USB ftdi driver
my $port = Device::SerialPort->new("/dev/tty.usbserial-A6008nhG");
$port->databits(8);
$port->baudrate(9600);
$port->parity("none");
$port->stopbits(1); 

$port->write("~" . "$msg" . "~");
print "TX: ~$msg~ \n";

# receive
$result = $port->lookfor();

print "RX: $result\n";
$port->close();

Arduino Code

char incomingByte;              // for incoming serial data
char cmdMsg[100];

void
setup ()
{
  Serial.begin (9600);
  //digitalWrite (13, HIGH);      //turn on debugging LED
}

byte nextByte() { 
    while(1) {
      if(Serial.available() > 0) {
          byte b =  Serial.read();
        return b;
       }
    }
}

//  MAIN CODE
void
loop ()
{
   int cmd = nextByte();
   if(cmd == 126)
    {
      char charIn = 0;
      byte i = 0;
      while (charIn != 126) // wait for header byte again
      {   
        charIn = nextByte();
        if(charIn != 126)
        {
          cmdMsg[i] = charIn;
          i += 1;
        }
      } 
  
      
      Serial.print (cmdMsg);
      
      
      //Serial.println("gotit");
    }
}

Again if i'm doing something dumb i'm sorry.

Hi Slingle,

It could be a timing issue. There is no delay between the TX and RX in the Perl script. I believe "lookfor" is non-blocking if you don't supply an argument, so it won't wait for a reply. Maybe the Perl script ends before it get the response from the Arduino?

You could try one of these:

Put a delay in the Perl script after the TX.

or

Try lookfor(4), it should wait until 4 characters are available to read.

or

Loop until the response from lookfor() is not "" and then print it.

Hope that helps.

RGB

This code works:

# Arduino Bridge

my $msg = shift;

# use Device::SerialPort;
# I'm using Win32::SerialPort - should work the same
use Win32::SerialPort;
use strict;
use warnings;

my $result;

# Set up the serial port
# 19200, 81N on the USB ftdi driver
# my $port = Device::SerialPort->new("/dev/tty.usbserial-A6008nhG");

# COM4 on my machine
my $port = Win32::SerialPort->new("COM4");

$port->databits(8);
$port->baudrate(9600);
$port->parity("none");
$port->stopbits(1);

# Opening serial port causes Arduino to boot - allow time

sleep(2) ;

$port->write("~" . "$msg" . "~");

print "TX: ~$msg~ \n";

$result = "";

until ("" ne $result) {
      $result = $port->lookfor;    # poll until data rcvd
#      sleep 1;                    # uncomment to save CPU
}

print "RX: $result\n";

$port->close();

RGB

Thanks Argeebee. I should have some time to test this tonight.

Was anyone able to successfully run this code? I copied the code exactly as it was posted. It seems to hang after responding TX: ~~. I’ve tried many different variations of the same script and get intermittent results. Should this be a no brainer? I should be able to send a character from a perl script to the Arduino and expect a character reply back. Any help would be appreciated.