Mega (Master Writer)/ UNO (Slave Receiver) I2C Problem

I'm having issues getting the Master Writer/Slave Receiver example to work using an Arduino Mega 2560 and an Arduino UNO.

Here's a pic of my wiring:

Here's my Master Sketch:

#include <Wire.h>

void setup()
{
  //Serial.begin(9600); 
  Wire.begin(); // join i2c bus (address optional for master)
  //Serial.println("master setup");
}

byte x = 0;

void loop()
{
  Wire.beginTransmission(21); // transmit to device #4
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte  
  Wire.endTransmission();    // stop transmitting
  //Serial.println(x);
  x++;
  delay(500);
}

Here's my Slave Sketch:

#include <Wire.h>

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
  Serial.println("slave setup");
}

void loop()
{
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

My UNO is connected to my computer via USB. My Mega is powered via a 12V 2.5 DC adapter. I'm using the pins 20 and 21 on the MEGA for data and clock signals respectfully.

I test in this sequence...Upload master sketch to MEGA, then upload slave sketch to UNO. I've also tried resetting both boards.

Any ideas why I wouldn't be getting any traces from my UNO? Is there something I'm missing?

You appear to have A$ and A5 of the Arduino connected to TX1 and RX1of the Mega, and expecting to do I2C communication between them.

I don't see how you expect that to work. The TX1 and RX1 pins on the Mega are not the I2C pins.

A5 of UNO is connected to SDA pin 20 on Mega.
A4 of UNO is connect to SCL pin 21 on Mega.

Is this not correct? Maybe my picture is not clear?

Is this not correct? Maybe my picture is not clear?

It's not your picture. It's my eyes.

A5 is SCL. A4 is SDA on the UNO.

Now, it appears that you are swapping the pins from one board to the other. Double check my reading/assumptions for yourself, though.

According to this tutorial:

Pin 4 is SCL and Pin 5 is SDN on UNO.

http://arduino.cc/en/Tutorial/MasterWriter

Connect pin 4 (the clock, or SCL, pin) and pin 5 (the data, or SDA, pin) on the master Arduino to their counterparts on the slave board. Make sure that both boards share a common ground. In order to enable serial communication, the slave Arduino must be connected to your computer via USB.

Is this wrong?

Is this wrong?

I looked at:
http://arduino.cc/en/Main/ArduinoBoardUno

TWI: A4 or SDA pin and A5 or SCL pin. Support TWI communication using the Wire library.

So, it appears that one of the links is wrong.

It's an incredibly easy thing to test...

Ok...I swapped pins on the UNO:

A4 of UNO is connected to SDA pin 20 on Mega.
A5 of UNO is connect to SCL pin 21 on Mega.

I also updated my skeches.

Here's my Master Sketch:

#include <Wire.h>

void setup()
{
  //Serial.begin(9600); 
  Wire.begin(); // join i2c bus (address optional for master)
  //Serial.println("master setup");
}

byte x = 0;

void loop()
{
  Wire.beginTransmission(20); // transmit to device #4
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte  
  Wire.endTransmission();    // stop transmitting
  //Serial.println(x);
  x++;
  delay(500);
}

Here's my Slave Sketch:

#include <Wire.h>

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
  Serial.println("slave setup");
}

void loop()
{
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

I'm still not seeing traces from my UNO. Is there anything else that's incorrect with my setup?

  Wire.beginTransmission(20); // transmit to device #4

Try as I might, I can't make 20 equal 4.

Paul,

Eureka! It's working now..I can see my traces!

Thanks for following this thread and helping me out! Really appreciate it. I thought I had to use the MEGA's SDA (20) pin as the transmission param for the Wire library...

I guess the pin you pass in as a param for transmission is the pin you're targeting on the slave board?

PaulS:
Try as I might, I can't make 20 equal 4.

Divide by 5, Paul. :wink:

insultcomicdog:
I guess the pin you pass in as a param for transmission is the pin you're targeting on the slave board?

Absolutely not. The parameter is the address of the slave device. The pin is irrelevant (and can't be changed).

If you declare the slave to have address 42 (in Wire.begin), then you have to do Wire.beginTransmission (42) on the master. It's nothing to do with pins.

void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

I advise you against doing Serial.print inside what amounts to an interrupt service routine.

Thanks for clearing things up Nick. I think I'm understanding how the Wire library works now. Printing to serial was just for debuging purposes....I'll be commenting those lines out.

Hey guys, I have the same problem too. MY addresses are equal though. I have made a PCB, but it doesnt seem to work. I have used 1k pull ups. In the PCB, 1 arduino mounts directly, while other is a bare atmega328 at 16MHz. What do your guys suggest for the problem? coz arduinos directly connected worked, but not in the PCB.

I'm also USED ARDUINO MEGA AND UNO COMMINCATION USING I2C PROTOCOL

Using THIS CODE

BUT it's basically UNO to MEGA then PC COM

// UNO CODE
#include <Keypad.h>
#include <Wire.h>
#define SLAVE 0x60

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{'1','2','4','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 11, 10}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {
Wire.begin();
pinMode(5,OUTPUT);
digitalWrite(5,HIGH);
Serial.begin(9600);
}
void loop()
{

char customKey = customKeypad.getKey();

if(customKey)
{
Wire.beginTransmission(0x60);
Wire.write(customKey);
Wire.endTransmission();
delay(500);
}
}

// ARDUINO MEGA
#include <Wire.h>
#define SLAVE 0x60
char x;
void setup() {
Wire.begin(SLAVE);
Wire.onReceive(Event);
Serial.begin(9600);
}
void Event(int bytes)
{
x = Wire.read();
}
void loop()
{
Serial.print("Recived ");
Serial.print(x);
Serial.print("\n");
delay(500);
}