Tests of I2C communication on Arduino (and DIY Arduino-style) boards

Experiment 1: Connecting 2 Arduino boards

I used a commercial Arduino Uno and Arduino Pro Miny board together with demo files from the Arduino Wire library for I2C. I connected my 2 boards as per the schematic on the example code page:

The serial clock pin (SCL, 5) and serial data pin (SDA, 4) are connected between each board, as are GND, but because the Pro Mny runs at 3.3V, I used the 3.3V VCC on the Arduino Uno to connect VCC.

I was able to get these two boards to communicate sending serial data (characters) back and forth (using the same code as experiment 2, below).

Experiment 2: Connecting an Arduino to my Input Devices board

The board I made for the Input Devices assignment is essentially an Arduino Leonardo, so I was able to replicate the first experiment with these two boards using the same code. I just had to figure out how to access the pins on my board. Some of these are exposed on the ISP header.

  • VCC: ISP header bottom right
  • GND: ISP header botom left

The I2C pins themselves are exposed on my 5-pin header

Using the same code as before (attached below), I was able to send data back and forth again.

Experiment 3: Trying another way to control my Input Devices board

While these experiments showed I was able to communicate between the boards, I wanted to try one more test, to see if I could use a physical input on one, to control an output on another. So I wired up a buton to my Arduino Uno, and adapted some of the demo code so I could use it to control an LED on my Input Devices board.

My previous code used Wire.requestFrom() and Wire.onRequest() to request and listen for data:

Master:

void loop() {
  Wire.requestFrom(7, 6);       // request 6 bytes from slave device #7

  while (Wire.available()) {    // slave may send less than requested
    char c = Wire.read();       // receive a byte as character
    Serial.print(c);            // print the character
  }

  delay(1000);
}

Slave:

void setup() {
  Wire.begin(7);                // join i2c bus with address #7
  Wire.onRequest(requestEvent); // register event
}

void loop() {
  delay(3000);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  Wire.write("hello ");         // respond with message of 6 bytes as expected by master
}

My new code uses Wire.beginTransmission() and Wire.endTransmission() on the master to send the commands to the slave:

Master:

void loop() {

  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  if (buttonState == 1) {
    
    // turn LED on:
    Wire.beginTransmission(7); // address of slave is 7 
    Wire.write(1);             // sends value byte  
    Wire.endTransmission();    // stop transmitting

    } else {

    // turn LED off:
    Wire.beginTransmission(7); // address of slave is 7 
    Wire.write(0);             // sends value byte  
    Wire.endTransmission();    // stop transmitting
   }
}

Slave:


void setup() {
  
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  Wire.begin(7);                   // join i2c bus with address #7

  // Attach a function to trigger when something is received.
  // From http://www.instructables.com/id/I2C-between-Arduinos/
  Wire.onReceive(receiveEvent);
  
}

void receiveEvent(int bytes) {
   x = Wire.read();                // read one character from the I2C
}

void loop() {
  if (x == 0) {
      digitalWrite(ledPin, LOW);   // received an OFF command 
  } 

  if (x == 1) {
      digitalWrite(ledPin, HIGH);  // received an ON command 
  } 
}

Files

Experiments 1 and 2: sending serial data back and forth:

Experiment 3: sending a command from master to slave: