Uno to Uno I2C basics

I am trying to get one Uno to send a char to another one over I2C. It's not working :-( I have tried several code samples on the internet and wiring diagrams.

If some one can give me a schematic and maybe client & server sketches I would apreciate it very much. Just some thing basic so I can get the darn thing to work. Thank you.

You need to watch this excellent HumanHardDrive tutorial on YouTube for communicating between two Arduino using I2C

I did and he does not give the schematic, His is one of the vids I looked at. I tried to wire it the way i think he did but still no success :frowning:

SDA to SDA
SCL to SCL
GND to GND

Master code

#include <Wire.h>

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

byte x = 0;
int failCount = 0;

void loop() {
  Wire.beginTransmission(13); // transmit to device #13
  Wire.write(x);              // sends one byte
  if(Wire.endTransmission() != 0)
    Serial.println("Write failed");

  delayMicroseconds(10);

  if(Wire.requestFrom(13, 2) == 2) {    // request 2 bytes from slave device #13
    while(Wire.available())    // slave may send less than requested
    { 
      char c = Wire.read(); // receive a byte as character
      Serial.print(c,DEC);         // print the character
      Serial.print(" ");
    }
    Serial.print(failCount);
    Serial.println();
  }
  else {
    Serial.println(F("Fail"));
    failCount++;
  }

  x++;

  if(x > 3) x = 0;

  delay(500);
}

Slave code. Serial is commented out.

#include <Wire.h>
byte array[8] = {2,4,6,8,10,12,14,16};
volatile byte regReq = 0;
volatile byte* rtnPtr;
 
void setup()
{
//  Serial.begin(115200);
  Wire.begin(13);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
}

void loop()
{

}

void receiveEvent(int byteCount)
{
  regReq = Wire.read();
//  Serial.print("* ");
}

void requestEvent()
{
  rtnPtr = &array[regReq*2];    
//  Serial.print(regReq);
//  Serial.print(" ");

  Wire.write((byte*)rtnPtr,2);
//  Serial.print(rtnPtr[0]);
//  Serial.print(" ");
//  Serial.println(rtnPtr[1]);
  rtnPtr += 2;
}

Does I2C need pull-up resistors on SCL and SDA?

Thank you SurferTim and everyone else for the help :-) The Uno does not have a SLC or SDA pin from what i see... what ports should I use then? She I modify the client and server sketches any place to reflect this? Thank you again.

Depending on the version of Uno, A4 or SDA pin and A5 or SCL pin.

Uno R3...

or

Thank you! I will try it today. I was using the A4 and A5 pins on my two Uno R3s... but will now try with SCL SDA per the diagram you just sent.

A4/A5 = SDA/SCL, the A4/A5 pins are the source of the signal and are connected via traces on the board. Do you have GND connected as well, and 4.7K pullup resistors?

No... I will try with the resistors tonight. So should I be using the SDA /SCL pins as seen on the diagram above, or the A5 / A4 pins?

SurferTim:

The client and server codes crash on my two Unos for some reason. I have edited them so they don’t crash. At this point I will be happy with a simple one way char / byte sent from a client to a server. I have tried A4/A5 AND SDA/SCL pins with and without pull up resistors… nothing works… here is my code for the client and server. Any help is much appreciated at this point!!! Please keep in mind I am learning Arduino alone, after work on my spare time. I do not have an electronics / IT degree or background. Thank you in advance!!

CLIENT: (HAS A GOOD, VERIFIED, LCD SCREEN)

#include <Wire.h>
#include <LiquidCrystal.h>

byte array[8] = {2,4,6,8,10,12,14,16};
volatile byte regReq = 0;
volatile byte* rtnPtr;

void setup()
{
//Serial.begin(115200);
Serial.begin(9600);
Wire.begin(13);
Wire.onReceive(receiveEvent);
//Wire.onRequest(requestEvent);
Serial.print(" setup done ");
}

void loop()
{
Serial.print(" In the loop ");
receiveEvent(1); // force it to occur to debug
delay(100);
// requestEvent();
}

void receiveEvent(int byteCount)
{
Serial.print( " receiveEvent() called “);
regReq = Wire.read();
Serial.print(” wire has been read, value is ");
Serial.println(regReq);

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print( “Uno-Uno: I2C”);
lcd.setCursor(3, 1);
lcd.print( regReq );

}

/*

void requestEvent()
{
rtnPtr = &array[regReq*2];
Serial.print( " register is “);
Serial.print(regReq);
Serial.print(” done. Now rtnPrt ");

Wire.write((byte*)rtnPtr,2);
Serial.print(rtnPtr[0]);
Serial.print(" and the second one ");
Serial.println(rtnPtr[1]);
rtnPtr += 2;
}
*/

SERVER

#include <Wire.h>

void setup()
{
//Serial.begin(115200);
Serial.begin(9600);
Wire.begin(); // join i2c bus (address optional for master)
//Serial.print(" I2C joined, ");
}

// byte x = 0;

void loop()
{
int x = 9;
int failCount = 0;

Wire.beginTransmission(13); // transmit to device #13
Wire.write(x); // sends one byte

// THIS CRASHES, THUS TAKEN OUT if( Wire.endTransmission() != 0 ) { Serial.println(“Write failed”); }

delayMicroseconds(10);

// WHICH DEVICE IF MORE THAN ONE ON THE BUS?? Serial.print( Wire.available() );

/*
if( Wire.requestFrom(13, 2) == 2 )
{ // request 2 bytes from slave device #13
Serial.print(" code line 31 “);
while(Wire.available()) // slave may send less than requested
{
char c = Wire.read(); // receive a byte as character
Serial.print(c,DEC); // print the character
Serial.print(” ");
}
Serial.print(failCount);
Serial.println();
}
else
{
Serial.println(F(“Fail”));
failCount++;
}
x++;

if(x > 3) { x = 0; }

*/

delay(50);
Serial.println(" End Loop ");
}

Galvanic isolator for I2C : moderator, please move to new thread if you see fit.

I2C with the Wire library is very convenient way of interconnecting two or more Arduinos and other devices. However the basic wiring scheme as given by SurferTim can be a source of worry, unreliability and component or module failure. Trouble-shooting this sort of thing can be difficult for Arduino users who don't know too much about electronics.

The main difficulty is that the zero volt return wire has to run close to the signal and clock wires. With all the different ways of powering devices, earth (ground) loops are inevitable and a source and cause of interference (or worse).

Other things we need to be able to handle are different operating voltages and being able to drive long connections of uncertain electrical characteristics.

The standard way of handling all this is to use isolators that can also manage voltage level differences and buffering/line driving. A big advantage is that then only a single pair of wires is needed between devices.

Components are very cheap as they are used in automotive electronics for example. I could just buy some, though through-hole items don't seem to be available.

Perhaps an expert in this field could advise us on the best choice among the many designs available, ideally a single one that would cover most of our likely uses. A ready-to-use circuit board we can buy would be very nice.