Search code examples
pythonarduinoraspberry-pii2c

How do I read a byte from a Slave I2C Device while handling a request from the Master?


I have a Raspberry Pi Zero W acting as a Master in communication with an Arduino Pro Mini acting as a Slave. I would like for the Master to send commands to the Slave. However, when I try using commands such as bus.write_byte_data or bus.write_byte from the Master, the Slave only ever seems to receive the value 255. Here's the code:

Master (in Python):

import time
import smbus

i2c_ch = 1
bus = smbus.SMBus(i2c_ch)

i2c_address = 20
bus.write_byte_data(i2c_address, 113,111)
val = bus.read_i2c_block_data(i2c_address,12)
bus.write_byte(i2c_address, 123)
print(val)

And here's the Slave's requestEvent() (in Arduino C):

void requestEvent()
{
  byte command = Wire.read();
  Serial.println(command);
  command = Wire.read();
  Serial.println(command);
  command = Wire.read();
  Serial.println(command);
...
}

What would be an approach whereby the Slave could receive bytes when being commanded by the Master?


Solution

  • You're probably trying to use a handler created by Wire.onRequest instead of one created by Wire.onReceive. An onReceive handler will do what you want:

    Wire.onReceive(receieveEvent);
    Wire.onRequest(requestEvent);
    ...
    void receieveEvent()
    {
      Serial.println("received some data");
      while(0 < Wire.available()) // loop through all but the last
      {
        byte command = Wire.read();
        Serial.println(command);
      }
    } 
    

    PS: LOL you have the same name as me!