Apr 292013
 

In late 2006 I wrote “arduino-serial“, mostly for myself, to help with stuff I was working on at the time. It was a very simple & small, cross-platform tool written in basic C for reading/writing serial ports.

Now nearly seven years later I still get regular questions and frustrations about it. Part of this is due to how Arduinos have changed over time. You used to have to hand-reset an Arduino board, now the act of opening the serial port resets it. This has its plusses and minuses, but it really made my original use-case of arduino-serial fail. Then there were just all the minor deficiencies of the program.

To address some of these issues, but still keep things small & light, I’ve done a bit of fix-up of arduino-serial. It’s now hosted on Github at:
https://github.com/todbot/arduino-serial/

Changes & Improvements

Some changes that I recently made to arduino-serial:

  • Separation of the application (arduino-serial.c) from the library (arduino-serial-lib.{c,h})
  • Fixed probable --read bug
  • Fixed --port open to allow re-opens
  • Added --sendline command to send a string followed by a newline
  • Added --flush command to clear out receive buffer
  • Added --eolchar option to let you specify your own end-of-line character if ‘\n’ isn’t appropriate
  • Added --timeout option to specify a read timeout (reads no longer block infinitely)
  • Added --quiet flag to make output more terse/machine-readable

Here’s what the new usage help screen looks like:

laptop% ./arduino-serial
Usage: arduino-serial -b <bps> -p <serialport> [OPTIONS]

Options:
  -h, --help                 Print this help message
  -b, --baud=baudrate        Baudrate (bps) of Arduino (default 9600)
  -p, --port=serialport      Serial port Arduino is connected to
  -s, --send=string          Send string to Arduino
  -S, --sendline=string      Send string with newline to Arduino
  -r, --receive              Receive string from Arduino & print it out
  -n  --num=num              Send a number as a single byte
  -F  --flush                Flush serial port buffers for fresh reading
  -d  --delay=millis         Delay for specified milliseconds
  -e  --eolchar=char         Specify EOL char for reads (default '\n')
  -t  --timeout=millis       Timeout for reads in millisecs (default 5000)
  -q  --quiet                Don't print out as much info

Note: Order is important. Set '-b' baudrate before opening port'-p'.
      Used to make series of actions: '-d 2000 -s hello -d 100 -r'
      means 'wait 2secs, send 'hello', wait 100msec, get reply'

Using arduino-serial

arduino-serial has always been designed so you can “pipeline” commands/options, but it wasn’t implemented very consistently. It’s a bit better now. You can do multiple send/read pairs, even use multiple serial ports, all from a single command-line invocation.

For example, if you have the “SerialCallResponseASCII” sketch from the Communications examples loaded onto your Arduino, you can run commands to take multiple data readings. In the example below, the order of operations are:

  1. serial port is opened (at 9600)
  2. the string “A” is sent (a single-byte)
  3. the first line is read
  4. sleep for 1000 milliseconds
  5. send “A” again
  6. read second data line
  7. flush read buffer (just to show we can)
  8. send “A” a third time
  9. and take a final reading
laptop% ./arduino-serial -b 9600 -p /dev/tty.usbmodemfd131 \
            -s "A" -r  -d 1000  -s "A" -r  -F  -s "A" -r
send string:A
read string:465,396,0

sleep 1000 millisecs
send string:A
read string:358,352,0

flushing receive buffer
send string:A
read string:307,305,0

The flush was put in there to demonstrate that you could flush the receive buffer mid-command if you wanted. It’s not required, but might help some situations.

To use multiple serial ports, you can do something like the below, which opens up one serial port at 9600 bps, does a send & receive, then opens another at 57600 bps and does a send & receive on it:

laptop% ./arduino-serial -b 9600 -p /dev/tty.usbmodemfd131 \
        -s "A" -r \
        -b 57600 -p /dev/tty.usbserial-A800f8ib \
        -s "hello" -r 
 Posted by at 5:43 pm

  6 Responses to “Arduino-serial: updated!”

  1. [...] arduino-serial has been greatly updated. See the "Arduino-serial: updated!" post for [...]

  2. I’ve poked around your code a bit and I was wondering if you’d be able to either make the change or discuss with me how to deal with the DTR/HUPCL “auto-reset Arduino every damn time you wanna use serial” issue. I love your code, it’s very simple and clean, does what it needs to. I just couldn’t get the commented-out

    Line 39: ioctl(fd, TIOCMBIC, &iflags); // turn off DTR

    to work in arduino-serial-lib.c. I also uncommented the

    Line 37: int iflags = TIOCM_DTR;

    line above it.

    Any help would be greatly appreciated as I am banging my head over trying to get serial to work without resetting the Arduino.

    Much thanks!

  3. Hi Goatboy,
    Yeah the reason why it’s commented out was because it can’t work. On Mac OS X & Linux (I think), the act of opening the port toggles DTR, regardless of the settings.

  4. Thanks, i use it for my meterN project
    cheers

  5. Hello,

    I am very new to all of this but I got an arduino starter kit and I am trying to use voice recognition with it. I have downloaded the files: arduino-serial.c, arduino-serial0lib.c, and arduino-serial.lib.h and put them on the root of my system. I also downloaded Xcode for my computer and enabled the command line tools.

    I am now trying to compile arduino-serial so I can communicate with my little toy and I get a bunch of warnings and 2 errors that prevent me from using arduino-serial.

    Here I copy what my terminal tells me. Any idea what I am doing wrong? Thank you very much,
    Bene

    error: expected identifier or ‘(‘
    {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf400
    ^
    ./arduino-serial-lib.h:55:2: warning: missing terminating ‘ character
    [-Winvalid-pp-token]
    \’a0\’a0
    ^
    ./arduino-serial-lib.h:64:2: warning: missing terminating ‘ character
    [-Winvalid-pp-token]
    \’a0\’a0
    ^
    ./arduino-serial-lib.h:71:2: warning: missing terminating ‘ character
    [-Winvalid-pp-token]
    \’a0\’a0
    ^
    ./arduino-serial-lib.h:80:2: warning: missing terminating ‘ character
    [-Winvalid-pp-token]
    \’a0\’a0
    ^
    ./arduino-serial-lib.h:91:2: warning: missing terminating ‘ character
    [-Winvalid-pp-token]
    \’a0\’a0
    ^
    ./arduino-serial-lib.h:106:2: warning: missing terminating ‘ character
    [-Winvalid-pp-token]
    \’a0\’a0
    ^
    arduino-serial.c:156:21: warning: implicit declaration of function
    ‘serialport_close’ is invalid in C99 [-Wimplicit-function-declaration]
    serialport_close(fd);
    ^
    arduino-serial.c:160:22: warning: implicit declaration of function
    ‘serialport_init’ is invalid in C99 [-Wimplicit-function-declaration]
    fd = serialport_init(optarg, baudrate);
    ^
    arduino-serial.c:163:17: warning: implicit declaration of function
    ‘serialport_flush’ is invalid in C99 [-Wimplicit-function-declaration]
    serialport_flush(fd);
    ^
    arduino-serial.c:168:22: warning: implicit declaration of function
    ‘serialport_writebyte’ is invalid in C99 [-Wimplicit-function-declaration]
    rc = serialport_writebyte(fd, (uint8_t)n);
    ^
    arduino-serial.c:168:48: error: use of undeclared identifier ‘uint8_t’
    rc = serialport_writebyte(fd, (uint8_t)n);
    ^
    arduino-serial.c:177:22: warning: implicit declaration of function
    ‘serialport_write’ is invalid in C99 [-Wimplicit-function-declaration]
    rc = serialport_write(fd, buf);
    ^
    arduino-serial.c:183:17: warning: implicit declaration of function
    ‘serialport_read_until’ is invalid in C99
    [-Wimplicit-function-declaration]
    serialport_read_until(fd, buf, eolchar, buf_max, timeout);
    ^

  6. […] to worry about, we do need to get commands to the Arduino using AppleScript. To do that, we use Tod Kurt’s Arduino-Serial package. Download and install […]

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>