[SOLVED!] i2c between 2 Arduino Dues is not working

Good evening to all Arduino Geeks at this nice Sunday,

I need help at a very diffucould problem I think.

I’m working on a project, where I want to let to communicate an Arduino Due with an Arduino Mega about i2c.

I bought this Logic Level Converter to make it possible between the 5V level of the MEGA and the 3,3V level of the Due.

But it doesen’t works. I testet it with the Test Sketches from the example Sketch folder of the Arduino IDE:

  1. Sketch:
// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

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

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

  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(500);
}

2nd Sketch:

// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

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

void loop()
{
  delay(100);
}

// 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
}

I have tried some variantes of Arduino Board constellations:

  1. Mega to Uno → works (without Logic Level Converter, it’s just in 5V level)

  2. Mega to Mega → works (without Logic Level Converter, it’s just in 5V level)

  3. Mega to Due-> not works (with Logic Level Converter)

  4. Uno to Due → not works (with Logic Level Converter)

  5. Uno to Uno → works (without Logic Level Converter, it’s just in 5V level)

  6. Due to Due → not works (without Logic Level Converter, it’s just in 3.3V level)

Due to Due shows like this:

Goto Picture on Skydrive

every constallation with Due not works.

The possibility, that my Logic Level Converter is not running is excluded, becuase 2 Due without them are also not communicating.

Is there are somthing else to do on Due to make i2c running?

I will be very pleased for getting any help!

I2C uses bi-directional open-collector/tri-state signalling, which probably won't work with level shifters. Due-to-Due I2C should work fine, with no level converter, and with proper software.

Regards, Ray L.

Hi Ray,

Thank you for your reply!

i looked up to the discription of the level shifter an see this picture:

why it won’t work?

and i made a second test with Due to Due connection and this Test Sketches:

// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

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

byte x = 0;

void loop()
{
  Wire.beginTransmission(4); // transmit to device #4
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte  
  Wire.endTransmission();    // stop transmitting

  x++;
  delay(500);
}

2nd:

// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#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
}

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
}

result in Serial monitor alter 5 minutes:

124
120
is48

there is somthing not runnig very well.

What you have there looks like a bi-directional which should work. Maybe it's your wiring. Follow the instructions here

https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide

also try to make the wiring as short as possible. I2C isn't meant to communicate over long wires. More than 2 feet is too much.

Well..... It apparently is NOT working. Without a schematic for the converter, its impossible for anyone here to say what the problem is. I suggest you contact the seller.

Regards, Ray L.

That's the solution:

click for picture

The Mistake which I made was the GND connection. The only contact of the GNDs of th two 2 Arduinos was the shield of the USB cables around the computer USB module.

I connected this both GNDs directly with a wiring bridge and it works!

At the "Due to Due connection" the solution was a little bit more difficult! The connection of the GNDs was clearly not enugh. After I conduct them, there are still was no stable i2c communication running. It was only working after i made an additional wiring connection between the both 3V3 Pins of the both Dues.

Apperantly it's required to take them on the same potential...of GND and 3V3...to work.

I hope it's some help for everyone, who have this problems too :)

At the "Due to Due connection" the solution was a little bit more difficult! The connection of the GNDs was clearly not enugh. After I conduct them, there are still was no stable i2c communication running. It was only working after i made an additional wiring connection between the both 3V3 Pins of the both Dues.

The connection between both 3V3 pins should not be required.

What I think is happening is that the pullup resistors on the Due boards is 1K (not the 1.5K as labelled). After your connections are made, you now have equivalent 500Ω pullup which is too strong. Technically, one of the boards should have the pullups removed if you are required to keep the same pins, however a practical solution would be to use the TWCK0 (pin 71) and TWD0 (pin 70) on the second Due board as these pins do not have pullup resistors.

FYI shields are not used as logic signal ground typically, as this injects RFI directly into signal ground path.