Go Down

Topic: I2C doesn't seem to work correctly (Read 997 times) previous topic - next topic

Hi, I have two Arduino nano board connected via an I2C connection on analog pins 4 and 5 with 4.8k pull up resistors connected to the 5V rail. Now i am using some simple code to send a character string between the two Arduinos:

Slave:
Code: [Select]
#include <SPI.h>
#include <SoftwareSerial.h>
#include <Wire.h>

void setup() {
       Serial.begin(4800);
       Wire.begin(2); //Establish the device on the I2C network as slave (Address 2)
}
 
void loop()
{
 Serial.println("Writing Data");
 Wire.write("Hello"); //Write data to the buffer for transmission
}


Master:
Code: [Select]
#include <SPI.h>
#include <SoftwareSerial.h>
#include <Wire.h>                      
                       
void setup()
{
         
Serial.begin(4800);
       Wire.begin(); //Establish the device on the I2C network as master (Slave Address 2)
}
char data[5];
char c;
int j;
void loop()
{
                       Serial.println("Requesting Data");
                       Wire.requestFrom(2, 5); //Request 5 bytes from address 2
                       j = 0;
                       Serial.println("Reading Data");
                       while(Wire.available())
                       {
                         c = Wire.read();
                         Serial.println(c);
                       }
}


The output is as follows:

Requesting Data
Reading Data

ÿ
ÿ
ÿ
ÿ

Nick Gammon

You can't just have Wire.write on its own. You need a Wire.beginTransmission and Wire.endTransmission.

Take a look a this:

http://www.gammon.com.au/i2c

There are examples there of communicating between two devices.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Apparently you only need wire.begin and wire.end if you are sending master->slave messages which I'm not. That's why the wire.begin function takes an address. The master node does not have an address so i can't use the wire.begin function... Can someone confirm this?

CrossRoads

You need Wire.beginTransmission();

an address is not needed for the master but the command is.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Grumpy_Mike

Quote
Can someone confirm this?

I can confirm that it is rubbish if that helps.

Nick Gammon

Did you look at my examples? You are doing this:

Code: [Select]
                        Wire.requestFrom(2, 5); //Request 5 bytes from address 2

If one end does a requestFrom that generates an interrupt at the other end. It needs to have installed a onRequest handler to intercept the request. It doesn't just pump out data.

Code: [Select]
  Wire.onRequest (requestEvent);  // interrupt handler for when data is wanted

Inside the onRequest you don't do a beginTransmission or endTransmission. But you don't have such a handler.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

I did read the examples. And thanks for the help, according to the documentation the beginTransmission takes an address, it was never mentioned that it can be used without, so i assumed it wasn't overloaded to not take an address for the case of a slave->master transfer. I will try the request handler now, i assumed there must be something i'm missing to detect the request of the master. Thanks everyone for the help!

RandallR

It is my understanding that the Master controls everything.  The Slave can not push data to the Master, the Master must request data from the slave.
That is why the Master does not have an address.  The Master knows who he is.
Also one slave can not push data to another slave.  The Master must always be in the middle.

Since the Slave must respond to the Master in the Masters time frame, there are interrupt service routines that the Slave sets up so the Slave can do productive work but still respond to a request from the Master.

Again, these are only my understandings.

Nick Gammon

You can have multiple masters. One of the examples on my linked pages shows two Arduinos, both with addresses and both with requestEvent handlers.

So really the word "master" refers to a period in time when one device "seizes" the bus in an attempt to communicate with another one.

Contrast this to SPI where there really is a MISO (master in, slave out) line, and a MOSI (master out, slave in) line.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

With the wire.onRequest() function defined on the slave, this works fine. Thanks alot :)

RandallR

But Nick,
If you have multiple masters and one master wishes to communicate with another master.  Isn't the second master going into 'slave' mode?  In that case the node is idle as a slave, waiting to respond to a master.  But if it needs something from another node, it can go into master mode to control the dialog.

Randall
BTW: You have probably forgotten more about this stuff than I have learned.  Thank you for you contributions.

Nick Gammon


But Nick,
If you have multiple masters and one master wishes to communicate with another master.  Isn't the second master going into 'slave' mode?


I have an example of multiple masters here:

http://www.gammon.com.au/i2c

See the Atmega328 datasheet page 218:

Quote
21.4 Multi-master Bus Systems, Arbitration and Synchronization

The TWI protocol allows bus systems with several masters. Special concerns have been taken in order to ensure that transmissions will proceed as normal, even if two or more masters initiate a transmission at the same time.


(TWI being the same as I2C more or less).




If multiple devices register a slave address then they can be addressed by any other device. So you might have "slaves" 2, 3 and 4. Now device 3 can "call" 2 or device 2 can "call" 3.

At the moment when you do the Wire.endTransmission() call, the device doing that attempts to initiate a transfer (ie. become the master) and if possible, send the data. When complete, it goes back into "slave" status. So effectively every one can be a master and a slave.

This is made possible electrically because each device has the two wires as high impedance (input) until such time as they attempt to become the master.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up