Perl communication to Arduino over serial USB

I recently switched from using plain Atmel chips to Arduino. Arduino is a development platform that uses an Atmel Atmege168 chip. It simplifies things a lot.

The Arduino board has a USB port. It has a built in FTDI chip for USB to serial conversions.

This HOWTO shows how to communicate between Perl/Linux and the Arduino. Because of the Arduinos FTDI chip, I can use regular serial communication, I just needed to first set up the USB serial adapter drivers. Most modern linux distro should come with them installed.

The perl script will transmit a number, starting at 0, to the Arduino. The Arduino will then echo that number back to your linux/perl computer.

# Sample Perl script to transmit number
# to Arduino then listen for the Arduino
# to echo it back

use Device::SerialPort;

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

my $count = 0;
while (1) {
    # Poll to see if any data is coming in
    my $char = $port->lookfor();

    # If we get data, then print it
    # Send a number to the arduino
    if ($char) {
        print "Recieved character: " . $char . " \n";
    } else {
        sleep(1);
        $count++;
        my $count_out = $port->write("$count\n");
        print "Sent     character: $count \n";
    }
}

Sample C program for Arduino. Listen for input on serial port then echos the input back out.

#include 
#include 

char incomingByte;              // for incoming serial data
char str1[50];
int count = 0;

void
setup ()
{
  beginSerial (19200);
  digitalWrite (13, HIGH);      //turn on debugging LED
}


//  MAIN CODE
void
loop ()
{
  // send data only when you receive data:
  if (Serial.available () > 0)
    {
      // read the incoming byte:
      incomingByte = Serial.read ();

      // Store it in a character array
      str1[count] = incomingByte;
      count++;

      // check if we have over 49 characaters or we recieve a return or line feed
      if (count > 49 || incomingByte == 10 || incomingByte == 13)
        {
          // Send the string back
          Serial.print (str1);
          count = 0;
        }
    }
}

communication between pc and arduino

Just to sure: you are communicating between the arduino and the pc over usb? You are communicating over the usb wire like it's a serial cable?

The arduino has a built in

The arduino has a built in usb to serial converter. Linux, and windows, have drivers to treat usb ports as serial ports. So to Perl, it looks like you are just talking over a normal serial connection. All the conversion from USB to serial is done by the FTDI chip that is built into the arduino.

So to answer your question, yes I am connection over the usb wire like it is a serial cable.

Diecimila, linux, & shell scripts

If you load your Diecimila with Simple Message System,
available from the archives at arduino.cc, you can
communicate with the unit using my package of shell
scripts. Run 'wget http://207.14.167.161/SMS1.tgz'
to get the tarfile. Not 24/7, it only works
when my PC is booted, so keep trying. Or email
rolandl@cavenet.com and ask for a copy.

Full IO and PWM control. AD is scaled to milliVolts
and formatted for import to most spreadsheets. I have
not tried these scripts under Mac OS/X but I see no
reason why they wouldn't work there as well.

Thanks

This is great. I learned a couple things looking over your Ardruino C code. Thanks for putting this on the web.

Error encounterrd

we tried to run ur first program, it gives the following error msg:

Can't locate Device/SerialPort.pm in @INC (@INC contains: c:\PROGRA~1\orient\Asia\PerlEnv C:/Perl/lib C:/Perl/site/lib .) at usb.pl line 5.
BEGIN failed--compilation aborted at usb.pl line 5.

Can you please help us

TIA

Re: Error encounterred

It looks like you don't have Device::SerialPort installed. It looks like you are running windows. Device::SerialPort is a linux only module. Try installed the perl module Win32::SerialPort. Then change all reference of Device::SerialPort to Win32::SerialPort. That should work.

thanks
chad

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is used to make sure you are a human visitor and to prevent spam submissions.
Image CAPTCHA
Copy the characters (respecting upper/lower case) from the image.