This page describes experiments in communicating between a [Raspberry Pi] (as a master) and an [Arduino] (as a slave) over [I²C]. The Raspberry Pi is programmed in [Python], the Arduino using a sketch (the Arduino's own language).

I based this experiment on an article found on ''The Robotics Back-End'' (see References below), but have modified it to use Python rather than C on the Raspberry Pi, since that's the main language I've been using to write the operating system of the [KR01] robot. Some of the ideas I found online tended to lock up the I²C bus or cause other kinds of problems. When I stumbled onto an example using the WiringPi library things seemed to even out. 

__WiringPi__ is a C++ library for communicating with a Raspberry Pi. It's been ported to Python as the
[WiringPi-Python|https://github.com/WiringPi/WiringPi-Python] library. In particular, I tried using the {{wiringPiI2CRead()}} and {{wiringPiI2CWrite()}} methods. For documentation, see [The I²C Reference Library|http://wiringpi.com/reference/i2c-library/].

It should be noted that the I²C read and write methods send a single integer. In order to communicate
strings or other data, you'll need to serialise the data and then deserialise it on the other end.

For an example, see:  [How do I serialize a Python dictionary into a string, and then back to a dictionary?|https://stackoverflow.com/questions/4342176/how-do-i-serialize-a-python-dictionary-into-a-string-and-then-back-to-a-diction] 

In the end I developed a solution called __[pimaster2ardslave|https://github.com/ifurusato/pimaster2ardslave]__ that has been posted as a project on github, which includes a Raspberry Pi Python 3 script 
and an Arduino sketch. 

I found to my consternation that the ''Arduino Nano BLE Sense'' that I bought for the purpose of being used as 
the slave processor __can't be used as a slave__: the Wire library it uses hasn't implemented the I²C slave protocol, though this is not documented anywhere (I found this out on the Arduino forum). One of the benefits of the Nano BLE Sense was that it's a 3.3V device, whereas the regular Nano is 5V. I'm still searching for the right
[Arduino] board now... (😠)   maybe I'll use a Teensy or an Adafruit board.


!! Raspberry Pi Installation

WiringPi for Python can be installed via:
{{{
 sudo pip3 install wiringpi
}}}


!! Arduino Installation

You'll need to install an Arduino sketch on your Arduino using the Arduino IDE. As an example, I modified the original source to blink the Arduino's built-in LEDs when either a transmit (TX) or receive (RX) event occurs.
%%pre-scrollable
{{{
#include <Wire.h>
#define SLAVE_ADDRESS 0x08
byte data_to_echo = 0;

// this slave code is meant to work on I2C address 0x08
// with rpi_arduino_wiringpi_i2c.cpp as described at:
// https://roboticsbackend.com/raspberry-pi-master-arduino-slave-i2c-communication-with-wiringpi/

void setup()
{
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);
  ready_blink();
}

void loop() {

}

void receiveData(int bytecount)
{
  for (int i = 0; i < bytecount; i++) {
    data_to_echo = Wire.read();
  }
  blink_rx();
}

void sendData()
{
  Wire.write(data_to_echo);
  blink_tx();
}

// status displays .....................................................

void ready_blink() {
  int i = 0;
  while ( i < 800 ) {
    blink_builtin();
    delay(i);
    i = i + 50;
  }
}

void blink_builtin() {
  digitalWrite(LED_BUILTIN, HIGH);      // turn the LED on (HIGH is the voltage level)
  delay(100);                           // wait 100ms
  digitalWrite(LED_BUILTIN, LOW);       // turn the LED off by making the voltage LOW
}

void blink_tx() {
  digitalWrite(LED_BUILTIN_TX, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);                           // wait 100ms
  digitalWrite(LED_BUILTIN_TX, LOW);    // turn the LED off by making the voltage LOW
}

void blink_rx() {
  digitalWrite(LED_BUILTIN_RX, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);                           // wait 100ms
  digitalWrite(LED_BUILTIN_RX, LOW);    // turn the LED off by making the voltage LOW
}
}}}
%%



!! References
 
* [WiringPi|http://wiringpi.com/] (C++ library)
* [WiringPi-Python|https://github.com/WiringPi/WiringPi-Python] on github
* [Raspberry Pi (master) Arduino (slave) I2C communication with WiringPi|https://roboticsbackend.com/raspberry-pi-master-arduino-slave-i2c-communication-with-wiringpi/]
* From Raspi.TV an article on __WiringPi2__ (really only the first is relevant here):
** [How to use WiringPi2 for Python on the Raspberry Pi in Raspbian part 1|https://raspi.tv/2013/how-to-use-wiringpi2-for-python-on-the-raspberry-pi-in-raspbian] 
** [How to use WiringPi2 for Python with pull-ups or pull-downs and PWM – pt 2|https://raspi.tv/2013/how-to-use-wiringpi2-for-python-with-pull-ups-or-pull-downs-and-pwm] 
** [Using the MCP23017 port expander with WiringPi2 to give you 16 new GPIO ports – part 3|https://raspi.tv/2013/using-the-mcp23017-port-expander-with-wiringpi2-to-give-you-16-new-gpio-ports-part-3] 
* [Using I2C to connect two Arduino Nanos|https://sandervandevelde.wordpress.com/2015/10/13/using-i2c-to-connect-two-arduino-nanos/], blog post by Sander van de Velde 
* [i2c SLAVE|https://github.com/adafruit/circuitpython/issues/437] on Adafruit's CircuitPython forum
* [Raspberry Pi - Arduino Serial Communication|https://www.instructables.com/id/Raspberry-Pi-Arduino-Serial-Communication/]

! Arduino

* [Master Reader/Slave Sender|https://www.arduino.cc/en/Tutorial/MasterReader]
* [Master Writer/Slave Receiver|https://www.arduino.cc/en/Tutorial/MasterWriter]


----

[{Tag RaspberryPi Arduino}]