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 descriptorint 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.




I wrote up a quick diff to clean up how nonstandard Bxxxxx macros are used — with this diff you can compile on any platform without having to edit the source, and all the baudrates supported by your platform will be supported by arduino-serial.
htttp://web.hexapodia.org/~adi/arduino/fix-arduino-serial-baudrates.diff
Thanks Andy! That really cleans up that section. I’ve patched the arduino-serial.c file so others can easily use it.
[...] the VonHippel module, a simple c program compiled for the arm, BUG can talk to the Arduino (in the picture, the USB cable and USB to serial [...]
Awesome! Thanks for this, will prove very useful.
I’m having trouble with it though. Using your example, I upload serial_read_blink.pde to the board and then use the command “./arduino-serial -b 9600 -p dev/tty.usbserial-A9003ZlI -d 1100 -s 6″
This is just the command you gave with an added pause as I have an Arduino Diecimila. The LED blinks as soon as I send the command, and then again at the end of the command (after 1.1 seconds I assume). There are no 6 blinks.
Any idea what the problem might be?
Hi Chris,
What you’re seeing is that when
arduino-serialopens the port, it resets the Arduino, which causes a small flash on the pin13 LED, thenarduino-serialsends the string (“6″ in this case), and then before the Arduino can fully response,arduino-serialexits, closing the port which causes the Arduino to reset again.The solution to this is to add another “-d” delay after you send the string, so you can watch the Arduino do its thing:
./arduino-serial -b 9600 -p /dev/tty.usbserial -d 1100 -s 6 -d 2000The auto-reset feature of the Diecimila is great, but on Mac OS X & Linux, opening & closing the port always resets it.
Thanks for the reply, but that doesn’t help. It just takes longer between the opening and closing flash of the LED.
Any other ideas?
hmm, that’s odd because the addition of the trailing delay does work for me. I assume you can get it to blink as you would expect when using the Arduino Serial Monitor?
The other thing to try is to increase the first delay a bit, say to 2000.
Ahh great, thanks alot. Seems the minimum pause I can get mine to respond after is 1500, a bit more than the Arduino site’s recomended one second, oh well not too bad.
Thanks very much!
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!
The easiest is probably to get an Arduino. Its “language” is really C for AVR.
Hi Todbot,
I am not new to Arduino, though I have some cobwebs to sjake off as it’s been over a year since we made a self-playing LP record player together. (sampled portions of record using 2 servos and simple pulley system, VERY COOL!)
Anyways, I am a senior engineering student and for my senior design project I want to communicate data from a C++ program into Arduino and use the data to have Arduino control some hardware. Have you done anything like this? Any ideas how I could do this?
Thanks in advance!
:)
p.s. keep up the great site!!
Hi Nick,
You can use C code from within C++, so you should be able to take any C serial port code (like the arduino-serial stuff above) and use it in your C++ program that talks to Arduino.
How would implement this in Visual Studio .NET 2005 ?
The POSIX libraries are not supported.
I am confused how to use the code at the top. Such as sending Furby or 6 to Arduino.
to send 6 it gave this (code?)
laptop% ./arduino-serial -b 9600 -p /dev/tty.usbserial -s 6
Would I want to write that into my C++ program word for word? I did this and was thrown errors, so not sure how to modify or use it. Thanks again for the help!
You would copy the functions in the arduino-serial source code into your C++ source file and call them from within the C++ file. But really what you should probably do, since you’re writing your own C++ code, is to Google around for “C++ serial port communication” for more native examples on how to communicate with serial ports with C++.
Hello again todbot,
So I was making progress, or so I thought, because I was using windows xp installed on a Mac. This allowed me to use the termios.h etc. that was unavailable for windows. I tried to go back on my windows machine and it threw the same erorr:
termios.h: No such file or directory.
with a couple others(related). Any idea how (if?) I can somehow import this or get around it? thanks again very much
Hi Nick,
Oh, you’re on Windows? Low-level things like serial ports are dealt with in very different ways than Unix-based OSs like Linux & Mac OS X. Most people doing serial port stuff on Windows use either Visual Basic (or .NET) or Java with the RXTX serial library. You’d likely be better off not using any of my ‘arduino-serial’ code above, as it assumes a Unix-like environment. Do a Google search for “windows serial port library” and you’ll find lots of tips.
There are ways of getting full POSIX library support in Windows, but I think it’s complex to do if you’re not used to it.
Just so people know, I was able to get this working under windows with just a little bit of playing around. The only real catch is you have to get the full POSIX support from somewhere. Cygwin is free and what I used, and in the end all you have to do is throw a single dll into the folder that your program is in, and it works just fine. I don’t have the source file that compiles fine as I ended up merging it with another program (very messy) but it works fine. Do NOT give up, keep trying and it should fall into place.
Can i use the –send-data to load an arduino sketch into the device without using the arduino GUI?
hello, I have a problem with the sensor sht. My question is worth the program sht75 applied to sht15?
thanks