Skip to main content
1 of 3
joan
  • 71.7k
  • 5
  • 74
  • 107

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.

joan
  • 71.7k
  • 5
  • 74
  • 107