I'm having trouble trying to get my two Arduino Unos to communicate with each other over i2c. I'm trying to have the master request for analog values from the slave by sending a request to the slave device for one of the six ADC pin values.

Master Code

#include <Wire.h>

void setup() 

void loop() 
  Wire.beginTransmission(0x22); // Start communication with Arduino slave at address 0x22

  for(byte i=0;i<4;i++)
    Wire.write(i);              // Request data from analog pin 'i'
    delay(5);                   // Give the slave a moment to sample ADC and respond
      byte c = Wire.read();
      Serial.println(c);        // Print returned value to serial window

  Wire.endTransmission();       // End communication with Arduino slave

Slave Code

#include <Wire.h>

void setup() {

void loop() {

void receivedHandler() {
  byte data = Wire.read();
  byte analogValue;

  if(data == 0) analogValue = analogRead(A0)>>2;
  else if(data == 1) analogValue = analogRead(A1)>>2;
  else if(data == 2) analogValue = analogRead(A2)>>2;
  else if(data == 3) analogValue = analogRead(A3)>>2;
  else analogValue = 0;


I can see that the data is being received by the slave, but the slave is not sending any data back, so I'm a bit confused how to send data back to the master. For the master there is "Wire.requestFrom(address, num of bytes)" to request a specific number of bytes, and for the slave "Wire.onRequest()" which will call a handler function to send back the number of bytes requested by the master, but for my application I won't be able to return more than 1 byte at a time.

  • 1
    I found this page berryjam.eu/2014/07/advanced-arduino-i2c-communication the most complete one about I2C comms between Arduino. I tested it and works.
    – user31481
    Commented Jun 14, 2017 at 21:40
  • If all you have to do is send 1 byte value for each of the 6 pins and your response from slave may be 32 bytes long, why not return ALL values, comma separated, and parse the answer on your master? Thats what I do in these cases. Treating multiple requests can make for lots of coding to get things right.
    – tony gil
    Commented Aug 9, 2019 at 11:30

1 Answer 1


Bidirectional communication in I2C is a two stage thing.

First you have to tell the slave which pin (or register) you want to read. Then you have to read it.

A typical master sequence would be:

Wire.requestFrom(0x22, 2);
byte b1 = Wire.read();
byte b2 = Wire.read();

And of course your slave has to respond to the write() and remember which pin is being selected, then separately respond to the requestFrom() and return the data corresponding to the pin that was selected earlier.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.