#include <Wire.h> // Include the Wire library for I2C communication
// Define a dummy slave address for the Arduino.
// When acting as a 'snooper', the Arduino will mostly ignore its own address
// and listen to all traffic passing through the bus. However, Wire.begin()
// for slave mode typically requires an address. We'll use a common unused one.
const byte ARDUINO_SLAVE_ADDRESS = 0x7F; // A high, generally unused address
// This function is called automatically whenever the Arduino receives a write
// (data from master to this slave address) on the I2C bus.
// For snooping, it will be called for any data sent by the master, even if not
// explicitly addressed to ARDUINO_SLAVE_ADDRESS (depending on Wire library implementation).
void receiveEvent(int howMany) {
Serial.print("Received ");
Serial.print(howMany);
Serial.print(" byte(s) from Master: ");
while (Wire.available()) { // loop through all but the last byte
byte receivedByte = Wire.read(); // receive byte as an int
Serial.print("0x");
if (receivedByte < 16) Serial.print("0");
Serial.print(receivedByte, HEX);
Serial.print(" (Bits: ");
for (int i = 7; i >= 0; i--) {
Serial.print((receivedByte >> i) & 0x01);
if (i == 4) Serial.print(" ");
}
Serial.print(") ");
}
Serial.println(); // end of message
}
// This function is called automatically whenever the Master requests data from
// this slave address. We won't be sending data for snooping, but it's good practice.
void requestEvent() {
// If the master requests data from this Arduino's address, you could respond here.
// For snooping, we typically don't need to send anything.
// Wire.write("hello"); // example: respond with "hello"
Serial.println("Master requested data from Arduino (ignored for snooping).");
}
void setup() {
Serial.begin(9600); // Start serial communication
Serial.println("\n--- Arduino I2C Snooper (Slave Mode) ---");
Serial.println("Listening for I2C traffic...");
// Initialize the Wire library in slave mode with a dummy address.
// The crucial part for snooping is that Wire.onReceive will trigger for all traffic.
Wire.begin(ARDUINO_SLAVE_ADDRESS);
// Register event handlers
Wire.onReceive(receiveEvent); // Register receiveEvent to fire when master writes to bus
Wire.onRequest(requestEvent); // Register requestEvent to fire when master requests from us
}
void loop() {
// Nothing to do in the main loop, as communication is handled by event functions.
// The Arduino is just listening in the background.
delay(100); // Small delay to prevent busy-waiting, but still responsive.
}