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.




Hi todbot,
I’m using your code and everything seems to work fine except when reading back a response. It seems to only echo back the input as a response.
I type-
$arduino-serial -b 9600 -p /dev/ttyUSB0 -s ra -d 2000 -r
where ra should read back a pin value and does through serial monitor and cutecom. I’ve tried the delay in various places and no delay at all. Any idea why it would only echo back the input?
Hi Tyler,
Try putting the delay before the send. You need to wait for the Arduino to start up before sending it data. Like this:
arduino-serial -b 9600 -p /dev/ttyUSB0 -d 5000 -s ra -r
I increased the delay in case you have an older Arduino.
If that doesn’t work, then I’d need to know what the sketch is like you’re running on the Arduino before being able to help more. For instance, depending on how your sketch is set up, you might need to add a delay between sending and receiving because your PC is often faster with serial than the Arduino:
arduino-serial -b 9600 -p /dev/ttyUSB0 -d 5000 -s ra -d 200 -r
That inserts a 200msec delay between sending and receiving.
[...] Arduino-serial: C code to talk to Arduino — http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/ [...]
[...] original arduino-serial.c – by Tod E. Kurt. [...]
[...] http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/ [...]
any way to set DTR to off (in order to avoid arduino autoreset?
high duty of CPU is due to the reason that this program never close serial previously opened
FTDI & teensy++ are both much faster than the arduino usb interfaces the teensy site shows in its usb serial exaple a high speed serial interface that the virtual com port goes as fast as it can in the benchmark example. Has anyone documented virtual serial port speed?
How can i progem my arduino using a c lenguage environment, it would be great because of being more experienced in c. apreciate feedback.
Hi Sergio,
Turns out every Arduino sketch you write is actually C code too! If you want, you can write more complex C functions within your Arduino sketch and use them with no trouble. This is one of the nice things about the Arduino environment.
Hi,
I know this isn’t really the place to ask this, but I have looked everywhere and tried for days, to no avail. My task is to have the arduino(s) taking readings of it’s environment (temp, light, humidity etc), which is sent back to a computer via USB/ethernet. The computer has a program which decides the appropriate reponse and tells the arduino to switch on the hot water, take the washing in etc.
When I attempted to compile your program (using code blocks, MinGW), I found termios.h, ioctl.h, and getopt.h were missing. I tried to include these, but was only returned more errors. I am sorry, I don’t know much about programming, but you seemed to cheerfully answer querys, so, yeah… Once I have a program that communicates, I am sure I will be fine.
Hi Nathan,
I suspect Windows’ approach to serial ports is fundamentally different than that of unix-like OSes. So I’m unsure you’d be able to get arduino-serial to work without a substantial rewrite.
You might have much better luck getting arduino_serial.py, a Python implementation of arduino-serial. The nice thing about arduino_serial.py is that it uses the pyserial Python library, which does work on Windows.
The python one seems to be working (to some degree haha). Thank you for your time.
hi~
i really new in pic and C programming..
but i need to study of how detecting the sensor and counting it..
canu give some basic code for sensor that i can study first before i build a new code..
hi,
@jack (February 11):
I had problems with the auto-reset on the Arduino Duemilanove as well. And I don’t really want to do any hardware modifications.
I added the following to the source (around line 225):
// turn off HUPCL to avoid reset
toptions.c_cflag &= ~HUPCL;
This isn’t perfect. The first call to arduino-serial still resets the device and whatever had been send is lost.
Any calls to arduino-serial after that work perfectly. It seems the setting is remembered until the next reboot.
Even something like:
echo “H” > /dev/ttyUSB0
work after the first call to arduino-serial (no reset).
Hola estoy usadon el archivo arduino_serial.py, y escribo la siguiente linea para ejecutar:
python arduino_serial.py -b 9600 -p /dev/ttyUSB0 -r
pero me da el siguiente error.:
—-
Traceback (most recent call last):
File “arduino_serial.py”, line 173, in
main(sys.argv)
File “arduino_serial.py”, line 146, in main
print “Read %s” % (port.read_until(‘\n’),)
File “arduino_serial.py”, line 107, in read_until
n = os.read(self.fd, 1)
OSError: [Errno 11] Resource temporarily unavailable
—-
espero me puedan ayudar. porque no se como escribir un programa para arduino en python o que arduino pueda entender python.