• about

    Random experiments, circuits, code, rapid prototyping examples, sometimes things to buy, and occasionally tunes by Tod E. Kurt.
    Reach me at tod [at] todbot.com
  • Yay BlinkMs!

    spacer BlinkM is a smart LED. Imagine an LED with a tiny computer inside, one that can be any color and have a life of its own. You can buy them now from one of our global distributors.
  • Hack your Roomba

    Get the Book
    spacer spacer
    Visit the official website: HackingRoomba.com
  • ThingM

    spacer
    A device studio that lives at the intersections of ubiquitous computing, ambient intelligence, industrial design, and materials science.
  • Popular pages

    • Bionic Arduino!
      – Arduino w/ motors & wii nunchucks
    • Spooky Arduino!
      – Intro class to Arduino
  • Recent Comments

    • todbot on Minimal Arduino with ATmega8
    • Miles on Minimal Arduino with ATmega8
    • todbot on Minimal Arduino with ATmega8
    • Miles on Minimal Arduino with ATmega8
    • todbot on Get on the BlinkM Bus with a BlinkM Cylon
  • categories

    • arduino (30)
    • blinkm (11)
    • general (20)
    • hardware-hacking (54)
    • ideas (18)
    • lasercut (5)
    • macosx (19)
    • misc (6)
    • music (6)
    • musicprog (2)
    • programming (9)
    • ramblings (13)
    • roomba (23)
    • sketching (6)
    • thingm (10)
    • toys (7)
    • ubicomp (9)
    • unixgeek (3)
    • video (5)
  • calendar

    December 2006
    M T W T F S S
    « Nov   Jan »
     123
    45678910
    11121314151617
    18192021222324
    25262728293031
  • Links

    • etech
    • freedictionary
    • gaping void
    • hackaday
    • hackedgadgets
    • hacknmod
    • make blog
    • metafilter
    • mikek
    • my yahoo
    • slashdot
    • waxy links
    • Wikipedia
  • todbot

    • del.icio.us tod
    • flickr todbot
    • todbot home
    • todbot twitter
  • Archives

    • October 2009
    • September 2009
    • July 2009
    • June 2009
    • May 2009
    • April 2009
    • March 2009
    • February 2009
    • September 2008
    • July 2008
    • June 2008
    • May 2008
    • April 2008
    • February 2008
    • January 2008
    • November 2007
    • October 2007
    • September 2007
    • August 2007
    • July 2007
    • May 2007
    • March 2007
    • February 2007
    • January 2007
    • December 2006
    • November 2006
    • October 2006
    • September 2006
    • July 2006
    • June 2006
    • May 2006
    • March 2006
    • February 2006
    • January 2006
    • November 2005
    • October 2005
    • September 2005
    • August 2005
    • July 2005
    • June 2005
    • May 2005
    • March 2005
    • February 2005
    • January 2005
    • December 2004
    • August 2004
    • June 2004
    • May 2004
    • April 2004
    • March 2004
    • February 2004
    • January 2004
  • Meta

    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.org
« Cylon Roomba – they do exist
Roomba Tilt Control and Holiday Buying Guide »

Arduino-serial: C code to talk to Arduino

The Arduino’s USB port is actually a serial port in disguise. To your computer it appears as a ‘virtual’ serial port. This is good news if you want to write custom code on your computer to talk with the Arduino, as talking to serial ports is a well-solved problem. (Unfortunately, so well-solved that there’s many ways of solving it.)

On the Arduino forum there’s been a few requests for some example C code of how to talk to Arduino. The nice thing about standard POSIX C code is that it works on every computer (Mac/Linux/PC) and doesn’t require any extra libraries (like what Java and Python need). The bad thing about C is that it can be pretty incomprehensible.

Here is arduino-serial.c, a command-line C program that shows how to send data to and receive data from an Arduino board. It attempts to be as simple as possible while being complete enough in the port configuration to let you send and receive arbitrary binary data, not just ASCII. It’s not a great example of C coding, but from it you should be able to glean enough tricks to write your own stuff.

Usage


laptop% gcc -o arduino-serial arduino-serial.c
laptop% ./arduino-serial
Usage: arduino-serial -p <serialport> [OPTIONS]

Options:
-h, --help Print this help message
-p, --port=serialport Serial port Arduino is on
-b, --baud=baudrate Baudrate (bps) of Arduino
-s, --send=data Send data to Arduino
-r, --receive Receive data from Arduino & print it out
-n --num=num Send a number as a single byte
-d --delay=millis Delay for specified milliseconds

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

Example Use

Send the single ASCII character “6″ to Arduino

laptop% ./arduino-serial -b 9600 -p /dev/tty.usbserial -s 6

This would cause the Arduino to blink 6 times if you’re using the serial_read_blink.pde sketch from Spooky Arduino.

Send the string “furby” to Arduino

laptop% ./arduino-serial -b 9600 -p /dev/cu.usbserial -s furby

Receive data from Arduino

laptop% ./arduino-serial -b 9600 -p /dev/cu.usbserial -r
read: 15 Hello world!

The output is what you would expect if you were running the serial_hello_world.pde sketch from Spooky Arduino.

Send ASCII string “get” to Arduino and receive result

laptop% ./arduino-serial -b 9600 -p /dev/cu.usbserial -s get -r
read: d=0

Internals

There are three interesting functions that show how to implement talking to serial ports in C:

  • int serialport_init(const char* serialport, int baud)
    — given a serial port name and a speed, return a file descriptor to the open serial port.
  • int serialport_write(int fd, const char* str)
    – write out a string on the given a serial port file descriptor
  • int serialport_read_until(int fd, char* buf, char until)
    – read from serial port into a buffer until a given character is received

You can and should write improved versions of the read and write functions that better match your application.

Update 8 Dec 2006:
Justin McBride sent in a patch because it turns out Linux’s termios.h doesn’t define B14400 & B28800. I’ve updated arduino-serial.c to include the patch, but commented out for now. No one uses those baudrates much anyway. :) If you need them, uncomment the additions out, or better yet, download Justin’s tarball that includes the changes and a Makefile to auto-detect your platform.

Update 26 Dec 2007:
Added ability to sent binary bytes with the ‘-n’ flag.
Added a delay option so you can open a port, wait a bit, then send data. This is useful when using an Arduino Diecimila which resets on serial port open.

Posted by todbot on Wednesday, December 6th, 2006 at 8:13 pm.

103 Responses to “Arduino-serial: C code to talk to Arduino”

Obviously you could also use “screen” to communicate with the Arduino (or any serial device) using the following command:

screen /dev/cu.usbserial 9600

screen is bidirectional, so you can send and receive data.

Left by xSmurf on December 7th, 2006

Yup, totally.

I’ve only ever used screen in interactive sessions. I’m not sure how one would go about routing screen to a proram or sending binary (non-ASCII) data that is present in many Arduino designs.

Left by todbot on December 7th, 2006

I haven’t tried it, but there’s probably some way to have the “expect” command interact with screen as a simple way to get data back and forth from the Arduino in a semi-automated way. However, this is going down the territory of “many ways to solve the same problem” territory Tod mentioned.

Left by Mike on December 7th, 2006

If you do want to do this using a dynamic language, the ruby/serialport library makes it really easy in Ruby. I just put up some video and instructions for a hello world.

Todbot — Thanks for all your great posts on Arduino (especially the Spooky Arduino series), I’m in the process of learning this stuff with a little study group of other absolute beginners and they’re been totally indespensible. Keep up the great work!

Left by Greg on December 9th, 2006

Thanks, I’m glad people are finding the Spooky Arduino stuff useful. It was a blast to work on.

And, wow, Ruby can do serial ports now? That’s awesome. Okay I gotta try this out….[follows your link, watches the rad movie, looks a bit more, then 2 minutes later] Yup, works like a charm. I did:

% wget rubyforge.org/frs/download.php/72/ruby-serialport-0.6.tar.gz
% tar xvzf ruby-serialport-0.6.tar.gz
% cd ruby-serialport-0.6
% ruby extconf.rb
% make
% sudo make install
% emacs light.rb
% ruby light.rb

With Ruby and its friendliness towards Ajax websites and the ability to do serial ports, I can imagine some really interesting “Web2.0″-type websites that interact with the real world via Arduino.

Left by todbot on December 9th, 2006

Very useful code, thanks!

However, I’ve found that -under FC6-, sometimes the seriaport_read_until returns a error 11 (resource temporarilly unavailable) in the read() call. I think it is not a problem with the software -obviously- since a “cat

Left by Jose on January 8th, 2007

I’m trying to get the hello world program to work I’ve downloaded the modifed Justin Mcbride file (I’m using linux) compiled and ran
./arduino-serial -b 9600 -p /dev/ttyUSB0 -r

the output is then read
read:

My port is on ttyUSB0 any clues?

Left by Peter on January 11th, 2007

After some experimentation it does return hello world I just need to catch it at the right time.

Left by Peter on January 11th, 2007

Hi Todbot,

Great site, I’m loving all the Arduino content. I’m new to Arduino and I’m trying to understand a few things. In the ruby example at ComputerKraft, they have 2 files – the sketch that’s written in Processing and the light.rb file. Do you need to write a sketch in Processing when you want to use ruby? Is it possible to write a ruby script that does what the Processing sketch does? I would like to be able to just write the code once in Ruby. And last, but not least, can you do an Arduino – Ruby example as you did with C?

Thanks for all the great content!

Jose

Left by Jose on January 30th, 2007

Hi Jose,
I’m not familiar with the Ruby example at ComputerKraft so I can’t speak to it. However, you don’t need Processing for Arduino or Ruby. Processing is just one way of writing programs (in this case, Java programs) that can talk to serial ports and thus Arduino. Because Processing is so easy to use and it shares the same style GUI as the Arduino programmer, it is a common tool for showing how you can interface Arduino with a computer.

Perhaps what the ComputerKraft example is doing is creating a Processing sketch that receives network requests then forwards them on to Arduino. The Ruby program then just connects to a network socket and doesn’t need to have serial port drivers.

Left by todbot on January 30th, 2007

In the example at ComputerKraft there’s an Arduino sketch, not Processing – sorry… that receives serial requests. In essence, it is nothing more than a case function that when selected turns on the corresponding LED. The Ruby program basically takes input from the user, parses it and forwards it over to the Arduino sketch via serial.

What I’m trying to understand is this: In order to use Ruby or any other language to speak to Arduino via serial, do I need to have an Arduino sketch already running in Arduino expecting serial requests?

Left by Jose on February 2nd, 2007

minicom is another great way to read/write to the arduino. I have the USB model and just set my minicom serial port to /dev/ttyUSB0. Works great in Fedora Core 6.

Left by Void Main on February 13th, 2007

[...] Here is arduino-serial.c, a command-line C program that shows how to send data to and receive data from an Arduino board. It attempts to be as simple as possible while being complete enough in the port configuration to let you send and receive arbitrary binary data, not just ASCII. It’s not a great example of C coding, but from it you should be able to glean enough tricks to write your own stuff.” – Link. [...]

Left by Daily Clerks on February 18th, 2007

Hi everybody,

I am introducing in this new world called Arduino, here is my problem:

I have my arduino working and I can receive data from it using:

tail -f /dev/ttyUSB0 >> “file.txt”

After trying with the arduino_serial.c, I was not sucesfull, I guess I have the same problem that Peter had.

Using “tail” would be enough for me since I only want to receive data from it. But when I say to arduino to work at baudrates higher than 9600. “tail” is not giving the right data (Strange symbols).

My question is do you know how to set the baudrate in order to use “tail” with higher baudrates?

Anyidea will be wellcome!

Left by Javi on March 2nd, 2007

Hi Javi,

To change the baudrate of serial ports, you use the “stty” command before your tail.

If you see the “roomba-tilt.pl” program on the Roomba Tilt project, you’ll see a complete invocation of stty that allows full bidirectional binary transmission.

But if all you need to do is change the speed, then:

% stty -F /dev/ttyUSB0 57600

is all you need to change the baudrate to 57600 bps.

Left by todbot on March 2nd, 2007

hi there,
i’m sorry if you cover this elsewhere, but i am just getting started in trying to program in C for the avr… do you have any recommendations on resources? just looking start with a simple blinkie code so i can figure it all out. i would really appreciate it. thank you!

Left by leah on March 17th, 2007

Hi Leah,
One of the easiest ways to get into C AVR programming is the Arduino site itself: the Tutorials, Reference, Hacking, and Playground sections are chock full of good intro material.

If you’re interested in plain vanilla AVR programming without the thin veneer of Arduino, one of the best books out there to get started is the “C Programming for Microcontrollers” available from SmileyMicros.com. It’s based around the Atmel AVR Butterly board, a tiny $20 demo board that’s a lot of fun to play with.

Once you get a bit familiar with AVR C, you’ll want to bookmark the AVR Libc page. Libc is the collection of C libraries that is the “standard” set of libraries containing all the functions you’re used to in C. In the case of AVR Libc, it’s also the libraries that help you interact with the on-chip hardware.

Left by todbot on March 20th, 2007

I can’t get open() to work, it keeps telling me the file does not exist. I can open the serial stream just fine with ’screen’ from the terminal, but this damn open() just returns an error. Any ideas?

Left by Ian on April 28th, 2007

That

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.