I made a simple sketch to enable communication between two Arduinos. Initially, Arduino 1 (Master) was unable to detect Arduino 2 (Slave) on the line. On each attempt to send data, I received a NACK on address (Wire.endTransmission = 2). I confirmed this when I ran an I2C scanner on Arduino 1 and the address of Arduino 2 was not appearing. I was really confused because I was sure that I had the correct addresses in place. After some troubleshooting and research, I realized that the two Arduinos had to share a common ground. This solved my problem!
Can someone please explain to me why a common ground is necessary here? (Perhaps in general). Why is it that if each Arduino uses its own GND, Arduino 1 cannot even detect Arduino 2?
We need to recall few basic electrical principles as information (between two Arduinos) are being exchanged using electrical signals (voltage and current).
1. Electrical energy is carried from source to load (the destination) by so called 'electrical current'.
2. Electrical current always returns (sinks) at the lower potential point of source.
3. The above 2 steps indicate that there are 2 wires in an electrical circuit -- the delivery path and the return path.
4. For your source Arduino, the I2C address delivery point/path is the SDA point/line and the lower potential point is the GND point/pin.
5. The I2C address of Slave goes from the Master in the form of voltage and current; the Slave accepts the address; the current must return to Master. Therefore, the lower potential point (GND-pin ) of Slave should e connected with the Master GND-pin to provide the return path for the current.
6. The above events could be represented by the following simplified diagram.
The simple explanation is: the data on the I2C bus is transmitted by the use of different voltage levels. To know what voltage level a signal wire has you need a reference level representing no voltage (0V) which is GND. But if you have two separate systems without the GNDs connected at least one of the systems doesn't know what reference level the signals it receives have. So it doesn't know if the signal received is a 0 or a 1 because it doesn't know the base level that was used to send the signal.