Here's a practical example of interfacing a [Raspberry Pi](https://www.ampheo.com/c/raspberry-pi/raspberry-pi-boards) with an [Arduino](https://www.ampheo.com/c/development-board-arduino) using I²C, one of the simplest and most flexible methods for communication between a Pi and a [microcontroller](https://www.ampheo.com/c/microcontrollers).

**Project: Raspberry Pi (Master) ↔ Arduino (Slave) over I²C**
**Goal:**
* Raspberry Pi sends a command to Arduino
* Arduino replies with a sensor value or a message
**1. Wiring**

Optional: Add 4.7kΩ pull-up resistors from SDA and SCL to 3.3V
**2. Arduino Code (I²C Slave)**
```
cpp
#include <Wire.h>
void setup() {
Wire.begin(0x08); // I2C address
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
Serial.begin(9600);
}
volatile byte x = 0;
void loop() {
delay(100);
}
void receiveEvent(int howMany) {
while (Wire.available()) {
x = Wire.read();
Serial.print("Received: ");
Serial.println(x);
}
}
void requestEvent() {
Wire.write("Hi Pi!"); // Respond with this string
}
```
Upload this code to your Arduino using the Arduino IDE.
**3. Raspberry Pi Code (Python I²C Master)**
**Setup:**
```
bash
sudo raspi-config # Enable I2C under "Interface Options"
sudo apt install python3-smbus i2c-tools
```
**Python Script:**
```
python
import smbus
import time
bus = smbus.SMBus(1)
address = 0x08
def writeByte(val):
bus.write_byte(address, val)
def readResponse():
data = bus.read_i2c_block_data(address, 0, 8)
response = ''.join([chr(b) for b in data if b != 255])
print("Arduino says:", response)
while True:
writeByte(42) # Send a command to Arduino
time.sleep(0.1) # Wait for Arduino to respond
readResponse()
time.sleep(1)
```
**Expected Output on Raspberry Pi:**
```
yaml
Arduino says: Hi Pi!
```
And on the Arduino Serial Monitor:
```
makefile
Received: 42
```
**Extend It!**
You can:
* Modify [Arduino](https://www.ampheoelec.de/c/development-board-arduino) to return [sensor](https://www.ampheo.com/c/sensors) readings (e.g., temperature)
* Send structured commands (e.g., control a motor)
* Use SPI or UART for higher speed or bi-directional streaming