pigpio (from V57) now supports the Raspberry Pi acting as a I2C slave device.
The core function is the C bsc_xfer.
The Python wrapper bsc_i2c provides an I2C slave interface.
As a test between a Pi3 and an Arduino Pro Mini I used the following code.
On the Pi3.
#!/usr/bin/env python
import time
import pigpio
I2C_ADDR=9
def i2c(id, tick):
global pi
s, b, d = pi.bsc_i2c(I2C_ADDR)
if b:
print(d[:-1])
pi = pigpio.pi()
if not pi.connected:
exit()
# Respond to BSC slave activity
e = pi.event_callback(pigpio.EVENT_BSC, i2c)
pi.bsc_i2c(I2C_ADDR) # Configure BSC as I2C slave
time.sleep(600)
e.cancel()
pi.bsc_i2c(0) # Disable BSC peripheral
pi.stop()
On the Arduino Pro Mini.
// This example code is in the public domain.
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus as master
}
char str[17];
int x = 0;
void loop()
{
sprintf(str, "Message %7d\n", x);
if (++x > 9999999) x=0;
Wire.beginTransmission(9); // transmit to device #9
Wire.write(str); // sends 16 bytes
Wire.endTransmission(); // stop transmitting
delay(50);
}
So the Arduino is sending 20 16-byte messages per second (16 is the slave receive FIFO size so it is a sensible maximum message size).
The Python was executing on a Linux laptop networked with the Pi.
Over a 600 second period the Arduino sent 11526 messages. The Python saw 11018 (95.6%).
The missing messages could detected by the gap between successive message numbers which should always be 1. The actual gap counts were
count gap
10855 1
9 2
20 3
95 4
32 5
1 6
3 7
1 8
2 9
The performance seems perfectly reasonable to me for a userland solution. Occasionally there will be inconvenient reschedules. I'd expect better figures if the Python was running on the local Pi.