ArduiPi Protocol Specification

This post present the protocol specification between Raspberry Pi and Arduino of the ArduiPi board.

The protocol will be the same and independant of the communication channel used. If you are on this page, this means that you probably already know the goal of the ArduiPi project. If not please refer on the post that present this project on this blog.

The communication could be done by three ways

  • Using Serial Port, this is not my favorite one because I like to use the serial for doing something else.
  • Using SPI, better but once again not my favorite because you need 4 wires and need a “chip select”, so another Rasbperry I/O. Also it is synchronous, so you can’t send back results immediatly, but it is cool and fast.
  • Using I2C, really simple to implement, lot of devices can take place on i2c and just need 2 wires.

This is beta API documentation the accorded driver on Raspberry Pi and Arduino Firmware are working but may not be stable yet 

Arduino Port Mapping

At this step, you need to know that Arduino pins that you can see on the arduino board are mapped to physical Arduino ports that may not have the same name into the Arduino chip. Here below the port mapping definition :

Arduino 328 ports Mappings

Remember, Arduino has 3 main ports named PORTB, PORTC, PORTD where

  • PORTD is digital pin 0 (PD0) to 7 (PD7), PD0 and PD1 are used by serial communication
  • PORTB is digital pin 8 (PB0) to 13 (PB5), PB6 and PB7 are reserved for external crystal
  • PORTC is analog pin A0 (PC0) to A6 (PC5), PC6 is reserved for reset pin

Protocol Communication

The communication is done by sending one or more byte to Arduino, then Arduino can immediatly do the action such of controlling a port and if needed return data such as analog value for example.

The communication is done as follow

  • A command byte : what we wand to control (port, port pin, pwm, ….)
  • Data Value, what value we want to set on action. This value can be :
    • Data byte Or
    • Data word

Somme overhead could be added depending on protocol used. For example to communicate with i2c we need to add before the device address (which is part of the i2c protocol)

On ArduiPi the arduino i2c slave address is defined to 0x2a and it is connected to i2c bus 0 of the Raspberry Pi or i2c bus 1 for the Raspberry Pi Revision 2. So we can issue the linux i2c command i2cset and i2cget to set or get information.

Each i2cset or i2cget commmand should begin with the following parameters :
-y 0 0x2a
-y to avoid prompt from the command line tool i2cset ot i2cget
0 refers to i2c bus 0 (so 1 for Raspberry Revision 2)
0x2a refers to i2c slave address (here the arduino)

If i2cget or i2cset command use a word instead of a byte for the last parameter, the command should end by w to indicate the value is a word value.

To simplify the project, I’m writing a program to replace i2cget and i2cset command that could also be used to communicate with spi. The program is called ardupi and this is the preliminary command line syntax

You can communicate with i2c communication with classic i2c program and/or arduipi program. The sample that are in the following table can be run on Raspberry Pi Revision 2. If you are using Revision 1 change all i2cget and i2cset command -y 1 to -y 0 (Revision 1 use i2c bus 0, not 1). arduipi program autodetect revision and adjust correct i2c bus if not specified.

Protocol Definition

Command Byte

The command will always refers to the port where we want to make action. You have the possibily to talk to the Arduino using either the AVR name or Arduino name depending on what is your preference.

The following present the command list used by ArduiPi

Command Byte ValueRefers toNotation
0x00 to 0x12
or in decimal
0 to 18
Digital Pin 0 to 18
Note that Digital Pin 14 to 18 refers to analog pin A0 to A5 when used as digital
0xa0 to 0xa5Analog Pin 0 to 5Arduino
0x1bPort BAVR
0x1cPort CAVR
0x1dPort DAVR
0x2bPort B DDRAVR
0x2cPort C DDRAVR
0x2dPort D DDRAVR
0xe0Ping Command-

Basic Command

Return the ping value.
Examples :
arduipi -g -d 0xe0
i2cget -y 1 0x2a 0xe0
0xe0Any byte value
ex : 33 or 0xAA
Set Ping Value
Set the value to be returned by the above ping command.
The value can be decimal or hexadecimal (prefixed by 0x)
Examples :
arduipi -s -d 0xe0aa
i2cset -y 1 0x2a 0xe0 0xaa

Command for Port Manipulation

0x01b or
0x01c or
Get Port - Get the given Port value.
Examples (Get Port C Value) :
arduipi -g -d 0x1c
i2cget -y 1 0x2a 0x1c
0x01b or
0x01c or
[00-FF]Set Port - Set the given Port to the following given hex value.
Examples (Set Port B Value to 0xa5) :
arduipi -s -d 0x1ba5
i2cset -y 1 0x2a 0x1b 0xa5
0x02b or
0x02c or
Get Port Direction - Get all pins direction of given Port in one shot. Each bit in the data value determine the pin mode as :
0 = Input
1 = Output
Examples (Get Port B DDR Value) :
arduipi -g -d 0x2b
i2cget -y 1 0x2a 0x2b
0x02b or
0x02c or
[00-FF]Set Port Direction - Configure all pins of given Port in one shot as input and/or output. Each bit in the data value determine the pin mode as :
0 = Input
1 = Output
Examples (Set Port D DDR Value to 0xf0) :
arduipi -s -d 0x2df0
i2cset -y 1 0x2a 0x2d 0xf0
0x01b or
0x01c or
0[0-7]Get Port Pin - Get the given port pin. Each bit in the data value determine the pin mode as :
0 = Low
1 = High
Examples (Get Port B pin 2 Value) :
arduipi -g -d 0x1c02
i2cget -y 1 0x1c 0x1c 0x02
0x01b or
0x01c or
[0-7][0-1]Set Port Pin - Set or clear the given Port pin. Each bit in the data value determine the pin mode as :
0 = Low
1 = High
Examples (Set Port D pin 4 Value to 1) :
arduipi -s -d 0x1d41
i2cset -y 1 0x1c 0x1d 0x41
0x00 to 0x12Get Digital Pin - Get the given digital pin value.
0 = Low
1 = High
Examples (Get digital pin 5 value) :
arduipi -g -d 0x05
i2cget -y 1 0x1c 0x05
0x00 to 0x12[0-1]Set Digital Pin - Set or clear the given digital pin given by item byte.
0 = Low
1 = High
Examples (Set digital pin 8 to High) :
arduipi -s -d 0x0801
i2cset -y 1 0x1c 0x08 0x01
0x00 to 0x120xDDGet Digital Pin Mode - Get the given digital pin mode. Return is as :
0 = Input
1 = Output
2 = Input with pullup
Examples (Get digital pin 3 mode) :
arduipi -g -d 0x03dd
not possible with i2cget
0x00 to 0x120xD[0-2]Set Digital Pin Mode - Set the given digital pin mode.
0 = Input
1 = Output
2 = Input with pullup
Examples (Set digital pin 4 to Input Pullup) :
arduipi -s -d 0x04d2
i2cset -y 1 0x2a 0x04 0xd2

Command for Analog Pins/Ports

In this group the command are used to control analog Pins/Ports

0xa[0-5]Get Analog Value
Get analog value for the analog arduino pin given by command byte (A0 to A5).
Examples :
arduipi -G -d 0xa5
i2cget -y 1 0x2a 0xa5 w

Command for PWM Duty Cycle Pins/Ports

In this group the command are used to control PWM Pins/Ports

3,5,6,9,10 or 110xEE[00-FF]Set PWM Duty Cycle
Set PWM value for the arduino pin given by command byte.
Examples (Set PWM duty cycle of pin 9 to 50%) :
arduipi -s -d 0xa5
i2cget -y 1 0x2a 0xa5 w
  • PWM frequencies are tied together in pairs of pins. If one in a pair is changed, the other is also changed to match:
    • Pins 5 and 6 are paired on timer0
    • Pins 9 and 10 are paired on timer1
    • Pins 3 and 11 are paired on timer2

Note that theese functions will have side effects on anything else that uses timers:

  • Changes on pins 3, 5, 6, or 11 may cause the delay() and millis() functions to stop working. Other timing-related functions may also be affected.
  • Changes on pins 9 or 10 will cause the Servo library to function incorrectly.

Thanks to macegr of the Arduino forums for his documentation of the PWM frequency divisors. His post can be viewed here




  1. Hi
    I got a copy of your board for testing for possible use in a class, but am running into a small problem. I would like to make using your board as easy as possible, and think the best way would be to use the Nanpy program (https://pypi.python.org/pypi/nanpy), which works great with Arduino Boards. The problem I am having is trying to upload the program on your board. Since the ArduiPi doesn’t have a USB port, the normal means of loading is out. I have tried to use an FTDI cable without success and tried to load all the libraries for Nanpy into the Arduino environment and upload using another Arduino as an ISP, but no success, as can’t compile. I have ordered a ISP programmer, and waiting for the snails to drag it ot Vietnam, but not sure that will work.Any ideas? I would prefer to use your board over external Arduino Unos, as more compact and less chance of damage, but I can’t seem to load the program.

    • Hi Richard,
      You’re right, the boards can be used as standard Arduino Boards, that was not the first goal but I’m happy you like them for doing this.
      For this to work, of course the board need to be powered, you have 2 choices to use them as standalone boards.
      1) Power them using power from FTDI cable, but for this you need to put a jumper on JVDD and close it (power coming from usb cable is not wired by default for board protection). But if you power the board like this, do not power it with external power at the same time.
      2) power with external power connected to power barrel and setting switch PI_VCC_EXT to ext position.

      Did you try one of these solution ?

      Now about programming, It seems some boards are also missing bootloaders, I’ve got some boards fresh out from factory and I need to verify this point. I keep you informed on this, if no bootloaders are on them, I will give you the right one so you can program it with a programmer or Arduino as ISP sketch.

      When the board is plugged on Pi, another solution exists to program the Arduino using the serial port of the Raspberry. There is then some more configuration to do but I succeded to do it and it works. If you’re interested I can do a post detail on this.

      Thank you for using ArduiPi product.


  2. Hi Charles
    Below are my notes from testing your board
    I have had several problems, many related to lack of clear documentation.
    If there is a way to program the ArduiPi directly from a Raspbery, using the Arduino environment, please let me know.
    It would also be helpful if you made a sample programs to use a standard shield, such as an LCD, so can display results of programs running on the Raspbery Pi on a screen shield connected to the ArduiPi, or can use the analog inputs on the ArduiPi to read temperature and humidity and the Raspberry Pi could plot them.

    I would really like to use your board with the Nanpy program as is a real easy environment for using an Arduino with the Raspberry Pi. If not, I will look at using serial connection to pass messages, but I am dealing with students who, mostly never programmed before, have just learned about the Arudino, and are now getting an introduction to the Raspbery. I can’t use the the standard AVR commands, as would be too much for them. I would like to include a real-life interface, but am afraid if they use the GPIO directly on the Raspberry Pi, I will soon have a collection of destroyed boards.

    Testing the ArduiPi Board
    Summary of tests of ArduiPi board for possible use in clas
    First tests
    Pluged the ArduiPi into a Raspberry Pi, Power on ArduiPi set to PI (internal) at 3.3v
    Raspberry pi refused to boot
    Set to power to 5V
    Raspberry Pi still wouldn’t boot
    Disconnected ArduiPi, tried as standalone
    Nothing – doesn’t seem to have an LED on board and an LED connected to pin 13 does nothing
    Got another board from Vendor, repeated prior tests. Same results
    Tried disconnecting the monitor, keyboard and mouse,
    as Charles-Henri Hallard, the creator of the board, had used the board headless while using it. Success, The Raspberry booted
    Validate error
    I then tried reconnecting the monitor, I am using the composite video connection, keyboard and mouse,to confirm the problems, and strangely, the raspberry boots. Exact same configuration as before, but now works. Unusual

    Testing the board
    In comments section on Charles-Henri Hallard’s website (http://hallard.me/category/arduipi/) was information that ArduiPi comes preloaded with the bootloader for the Arduino Duemilanove w/ ATMega328.
    Using an Arduino UNO as an ISP I was able to load a test program that checks output on all Analog and Digitial pins (expect Rx & TX)  and connected it to a test board. All pins work.
    It can draw 3.3V from Raspberry, but 5V causes the Raspberry to shut down.

    Testing to see if can load nanpy software
    The ArduiPi doesn’t have a USB connection, so first tried to see if could use Arduino environment and load libraries for Nanpy program. Wouldn’t compile

    Testing FTDI
    Tried using FTDI cable with FTDI socket, power on ArduiPI set to 5V external, and power by FTDI cable, failure, programmer not responding, seems draws too much power
    Tried again with AC/DC converter to supply external power, failure, programmer not responding
    Tried connecting DTR to reset pin, failure programmer not responding
    Tried pressing reset just as uploading, failure programmer not in sync
    Tried using 100nb capacitor between DRT & reset failure, programmer not in sync
    Conclusion: FTDI doesn’t work

    Future possible testing
    1. Try using Arduino programmer for board and program through ICSP
    2. Remove CPU and load Nanpy by external programmer.

    Conclusion so far
    ArduiPi is not suitable for use in classroom

    • Richard,
      thank you for your comments. I appreciate and I’m sorry for the lack of documentation.
      I just started to write a post on Getting started with Arduipi that should describe what you are looking for the begining, just take a look to
      this post
      ArduiPi board is very versatile (may be too much) and that permit you to do almost anything you want, but the drawback is that this invoke a lot of knowledge on several sides (PI coding, Arduino Coding, Hardware, Soldering, Protocol communication, I2C, Driving LCD,…) As you can see, depending really on what you need to do.
      I will be happy to help you and work with you to prepare teaching classes if you want. If you need to have a value on Raspberry displayed on a display there is also lot of possibilities depending if the LCD should be driven by the Pi or by the Arduino. If it should be driven by Arduino, we need to define a dedicated protocol between Pi and Arduino so the are be able to communicate.
      If you take a look on this post, you will see that basic sample code exists to get Analog Value from Arduino to Raspberry using I2C protocol and ArduiPi command line executed from PI, all sketches and code is on my github under folder Arduino and Raspberry.
      Concerning the problem you encoutered, I’m pretty sure it is related to the Power of The Raspberry PI as I described in my new post.
      No led Are conencted by default, this is why you can’t see one lighted, you need to choose the function you want of your led by soldering LED PAD as described in my Getting Started post.
      I think with this new post it will be more clear, I’m using FTDI day by day without any problem, the Board in Arduino IDE should be set as Arduino Uno (and not the Duemilanove as I said previoulsy, sorry about that) .
      By the way, when you programmed ArduiPi board with another Arduino with As ISP, you programmed a sketch, this type of programming (as ISP) just erased the Arduino bootloader and you are no more able to program it with FTDI because the Arduino does not have bootloader anymore and this is needed to use FTDI. So that is why your FTDI is not working Anymore. You need to get back bootloader into Arduino to be able to program it again. You can do that using Arduino As ISP but choosing after in Arduino IDE the “Burn Bootloader” after choosing Arduino Uno for the board type. This will program again your Arduino with Uno bootloader.

      Once again, if you need any help do not hesitate to ask, I will take a look to Nampy program to see what you can do with it.


  3. Hi Charles
    Ok, the starting guide helps
    I would suggest, if version 2 isn’t locked down yet, you have default LEDs for pin 13 & power activated and users can cut trace if they don’t want the defaults, or use jumpers. You could use diodes so power LED will indiciate if connected to either power source. The lack of any indicator has confused at least a few people, based on posts I have seen, including me and if we buy 30 boards I wouldn’t want to have to end up soldering 90 connections.

    Nanpy is just one possibility. The students will know how to program the Arudino, so running a program on the Arudipi and having it communicate with a program on the Raspberry is also possible. What I would really would want to have is a simple way of using Python to interface with your board (read sensors, turn on lights and display messages). Something like the set of APIs used with Minecraft Pi.

    Another item.
    I burned the Uno bootloader for UNO, but FTDI still not working. Maybe I need to use another adapter or another PC (I am running Linux). Did you just connect up an FTDI adapter to the pins or do I need to route DTR to reset? If so, is it direct or do I need to use a capacitor like on the mini? In any case, the sooner you can provide instructions for programing the Arduipi from the Raspberry the better, since if I have to issue students an UNO to use as a programmer, I might as well have them use the UNO as a slave board.

    Also a bit strange.
    Prior to buring the bootloader, while running i2cdetect program with nothing plugged into the Arudipi, it would return 18, now returns nothing.
    I assume I now need to run a sketch on the ArduiPi to configure i2c like with a normal board, as this is what it supposed to do.

    • Richard,

      That was exactly my concern about default PAD configuration when I created the board, I always have in mind “should I setup PAD with default and if user want to change it, cut a trace, or leave user select it”. I think now I’ve got my answer, I should have done a default configuration. I will check for V2 board if it’s not too late.

      For programming, just connect the FTDI connector (and power the ArduiPi board of course), there is already the reset capacitor going to reset line using DTR pin. I encourage you to get a look to the schematic of the board here

      I took a look on nanpy, well, this a excellent product that could perfectly fit on ArduiPi board, without any problem since it communicate using serial port. I will try it as soon as I can, I’m very interessted.

      About I2C, when you run i2cdetect on Raspberry, the device 18 is not the Arduino but the I2C to 1-Wire controller DS2401 populated on ArduiPi board. By default I2C of Arduino is not connected to Raspberry Pi I2C bus, so Raspberry can’t talk I2C to Arduino. If you want to connect Arduino I2C to Raspberry Pi I2C bus, you need to solder the appropriate 2 PADs
      But you must know that when doing this, the Arduino should be a I2C Slave and the firmware on it need to be configured to be I2C slave. Especially, the SDA/SCL ports of the Arduino must be programmed as input, if not this will conflict with Raspberry I2C bus and Raspberry I2C bus will not work.
      If you want a example, please see the test firmware used to test board. With this file, Arduino act as I2C slave to respond to I2C command issued from PI (even with i2cget or arduipi program).
      With this firmware (and SCL/SDA pad soldered), Arduino should be seen as device number 0x2A from i2cdetect command issued from Raspberry PI. You can find a post describing the test processus with more details here

      Let me know if you have any question


  4. Hi Charles
    FTDI still isn’t working, but may be due to Linux as had problems with programming home-made arduinos.

    The pads probably explain the odd results I am now getting now,(i2cdetect not showing either 18 or the ArduiPi running as a i2c slave, even when wired directly if connected, and the ArduiPi CPU getting very hot) but doesn’t explain why it detected 18 before I loaded the UNO bootloader. If I run the ArduiPi not attached, i2cdetect shows 04 as expected (I am running the sketch from http://blog.oscarliang.net/raspberry-pi-arduino-connected-i2c/ and followed those instructions for setting up the Raspbery and Arudino, which are much the same as yours)
    I think I will put things aside for a while until have time to print out the schematic, blow them up a bit and trace out the connections to see what effect soldering the pads will have, as don’t want to destroy the Arduipi or the Raspberry or have to unsolder in the future if causes a problem. I also would really rather not to have to have a solution that requires either our lab assistant or me soldering a large number of boards.

    • Richard,
      If I understand correctly your problem, it could be because before you loaded the bootloader, the ArduiPi board comes from factory with test program inside. The test program put he Arduino into I2C Slave device and so let the I2C bus working fine (if you soldered the SDA/SCL pads to connected PI I2C to Arduino I2C of course) you saw then I2C device 18 (1 wire I2C) and 2A (Arduino). Once you programed the board with new bootloader, it erased the test program. Then SDA/SCL of arduino were still connected to PI I2C but the I/O port where the default ATMEL configuration and then may be interfered the I2C bus.


  5. Hi Charles
    I downloaded the schematic by following the link from Seedstudio, the link you sent me was for the template for printing the pcb, not easy to trace, and am looking at the connections. Is there any reason why in your updated getting started guide you have people connecting to IO18 on J12, which means soldering in another set of pins, instead of connecting directly to the GPIO of the Raspberry via the extended pins on the ArduiPI?
    Also soldering the jumpers for the i2c pads cleared up the problems. i2cdetect sees the i2C to 1-Wire controller DS2401 (18) and 04, which is what I set the ArudiPi to as a slave and the CPU is not hot anymore. Unless there is a good reason, it would be nice if these were enabled by default.
    It would also be nice if you would put out a description of what all the little pads do and if any conflict with anything else.
    I hope your version 2 has more defaults enabled and some more pins soldered on as if we buy 30 boards it means soldering 4 pins for serial, 2 pins for FTDI power(maybe), 3 connections for LEDs and 2 for i2c and possibly a header for J12 times 30, which with testing, would be a lot of work.
    The library for i2c with python seems fairly simple, so I think it could be used in class. I’ll have to play with it a bit now that i2c is working.

    • Richard,

      Connecting GPIO18 on J12 DTR is for allowing to program Arduino from PI without the need to have one USB FTDI cable or interface (using PI Serial interface). You won’t have to do it on new ArduiPi boards (V1.1).

      I will add more documentation on all PADs soon, but in all case the PADs for I2C SCA/SCL will not be closed out from factory, because depending on program flashed to Arduino, it can set the Raspberry I2C bus in trouble if the Arduino flashed program does not contain I2C slave code.

      But as your excellent remark, I asked factory to setup default PADs for LED1, LED2, LED3, Autoreset (GPIO18) and PI Shutdown switch (GPIO17) to be enabled by default.


  6. Hi Charles
    I guess I wasn’t clear. My question wasn’t about why you connected DTR to GPIO18, I understand that well, my question was why J12 and not directly to the extension pin that is connected to the Raspberry. From your schematic, it seems that there is a direct connection between the extension pins connected to the Raspberry and the pin holes in J12.

    • Richard,
      Sorry about this, I think it was not clear in my head the time I have read your message.
      You’re absolutly right, in the Started Guide I draw the connection between J1 DTR (not J12) and GPIO18 but in real world I just put a female/female dupont wire between them because on my I/O connector of my ArduiPi board (The 8 pins connector going from IO4 to IO25) I’ve soldered same connector as J1 (FTDI), so a Male one.
      But Yes you can grab the signal from extension pin on top of Raspberry PI connector but with several cares :
      1) this signal is not level shifted from 3.3V to 5V so it will be 3.3V output only but it does not mater, it will work even if your Arduino is 5V powered
      2) if you do this (not using level shifting stage), do not plug FTDI Cable because it could then bring 5V from his DTR pin to direct GPIO18 (which is 3V3 tolerant because you won’t go trougth level shifting), this can burn you IO.

      By the way, version 1.1 (next batch available on seeedstudio) will have this connection onboard, default connected, as the 3 LEDs;-)


  7. Hi Charles
    I guess it doesn’t matter to me any more, since you will fix it in the next version, and there won’t be any need to solder an 8 pin connector onto 30 boards, but my question was “Why did you run a cable from DTR on J1 to GPIO18 on J12 instead of directly from DTR on J1 to GPIO18 on J13?”)
    If, as I understand, there is no problem with connecting directly from DTR on J1 to GPIO18 on J13 maybe you should change your guide, as the production boards have male pins on J1 and J13, but only holes for J12, meaning people will be doing unneeded soldering.
    Thanks for your answer

Comments on this topic in community Forums.