Master/Slave code for multiple Arduino i2c

Hello All,

I have been trying to build a small sensor network but have had trouble getting the Arduino's to speak to each other over i2c.

Today I had a breakthrough with the help of the folks at Bot Thoughts Bot Thoughts: Arduino to Arduino I2C

Here is the code for the master and slave. The slave will respond to multiple commands and send data back or set values accordingly. The master continually loops through the commands and prints out the results. There is minimal delay with the polling as the i2c protocol speaks very quickly.

Master Code

/* 

Thanks to the work at http://www.bot-thoughts.com/2010/06/arduino-to-arduino-i2c.html I was able to create this demo.

*/

#include <Wire.h>
#define device 1

byte dataIn[3] = {
};
int command = 0;


void setup()
{
  Wire.begin();
  Serial.begin(9600);
}

void loop()
{
  sendCommand(); 
  delay(1);
  command ++;
  if(command > 2)
  {
    command = 0; 
  }
}

void sendCommand()
{
  Serial.print("Sending command ");
  Serial.println(command);
  dataIn[0] = 0;
  dataIn[1] = 0;
  dataIn[2] = 0;
  switch(command)
  {
  case 0:
    readDataA();
    break;

  case 1:
    readDataB();
    break;

  case 2:
    sendData();
    break;

  default:
    break;
  } 
  printDataIn();
}

void readDataA()
{
  Wire.beginTransmission(device);
  Wire.send(0);
  Wire.endTransmission();
  int i = 0;
  delay(1);
  Wire.requestFrom(device, 3);
  while(Wire.available())    // slave may send less than requested
  { 
    byte c = Wire.receive();
    dataIn[i] = c; 
    i ++;
  }

}


void readDataB()
{
  Wire.beginTransmission(device);
  Wire.send(1);
  Wire.endTransmission();
  int i = 0;
  delay(1);
  Wire.requestFrom(device, 3);
  while(Wire.available())
  { 
    byte b = Wire.receive();
    dataIn[i] = b; 
    i ++;
  }

}

void sendData()
{
  Wire.beginTransmission(device);
  Wire.send(2);
  byte dataOut[3] = {
    200, 150, 100      };
  Wire.send(dataOut, 3);
  int result = Wire.endTransmission();
  if(result > 0)
 {
    Serial.print("Error in transmission");
  }
  else
  {
  int i = 0;
  delay(1);
  Wire.requestFrom(device, 3);
  while(Wire.available())    // slave may send less than requested
  { 
    byte b = Wire.receive();
    dataIn[i] = b; 
    i ++;
  }
}
  
}

void printDataIn()
{
  Serial.println("Data in values are as follows:");
  Serial.print("[0] = ");
  Serial.println(int(dataIn[0]));
  Serial.print("[1] = ");
  Serial.println(int(dataIn[1])); 
  Serial.print("[2] = ");
  Serial.println(int(dataIn[2])); 
  Serial.println();
}

Slave Code

#include <Wire.h>

byte dataOut[3] = {};
byte dataIn[6] = {};
boolean dataReady;
boolean requestIn;
boolean receiveIn;
unsigned char reg;

void setup()
{
  Wire.begin(1);
  dataReady = false;
  Wire.onRequest(handleRequest);
  Wire.onReceive(handleReceive);
  digitalWrite(13, HIGH);
}

void loop()
{
  if(dataReady)
  {
    checkCommand(); 
    dataReady = false;
  }
}

void checkCommand()
{
  switch(dataIn[0])
  {
  case 0:
    dataOut[0] = 1;
    dataOut[1] = 2;
    dataOut[2] = 3;
    break;

  case 1:
    dataOut[0] = random(0, 255);
    dataOut[1] = random(0, 255);
    dataOut[2] = random(0, 255);
    break;

  case 2:
    dataOut[0] = dataIn[1];
    dataOut[1] = dataIn[2];
    dataOut[2] = dataIn[3];

  default:
    break;
  }
}

void handleReceive(int howMany)
{
  int i = 0;
  while(Wire.available())
  {
    byte b = Wire.receive();
    dataIn[i] = b; 
    i ++;
  }
  dataReady = true;
}

void handleRequest()
{
  Wire.send(dataOut, 3);
}

Let me know if you have any questions or comments! I hope this helps someone :slight_smile:

-Miles