Is Wire begin and end Transmission Necessary?

Hi all,

I need to send continuous gps data over I2C, that preferably doesn’t stop when I have a fix. Do I need to use Wire.endTransmission if I don’t want it to stop sending unless the gps loses connection? I need wire.beginTransmission right?


Sounds like right if the I2C device supports that mode of continuous data transmission.

@JackD12, are you sending data from the Photon to a slave device or is the Photon the slave?


I’m sending it from an Electron(master) on the asset tracker to my Arduino(slave).

You can use I2C to stream data to the Arduino. I am doing this for another project and can share my experiences. I2C is really good for sensor/chip access.

I would really suggest setting up a serial line between the two for streaming data. This would overcome the 32 byte buffer for I2C. This is your maximum message size for each transmission.

Now to your question. My answer would be yes. I2C transmission the master will always need to use Wire.begin() (for setup), Wire.beginTransmission() and Wire.endTransmission(). After reading the docs, the write does not necessarily transmit right away… it is more queued until endTransmission() is run. The example comments are a little misleading.

On the Arduino(slave) end, you might be using the onReceive() handler to capture these messages. Because this is event driven, if the Master runs too fast and sends another Wire.beginTransmission() before the last read is complete, this can lead to communications bind up as the prior event onReceive() did not complete its work and possibly corrupting the current transmission in progress.

Every time the Master runs Wire.beginTransmission(), the onReceive() handler will fire. It does not matter if you use Wire.endTransmission(true) to hold the line open. This means you need a sufficient delay() after endTransmission() for the slave to read everything sent.

There is no real way for the Master to detect when the Slave has received all its data. If you really wanted to, you can setup an additional digital line between the master and slave so the slave can signal the master when it is done reading.
IE: a digital pin on the Electron would be set for INPUT. The master would initiate Wire.begin() causing the slave to fire an onReceive(). Within onReceive(), the slave would change the state on the digital line. It would continue to read and at the end change the digital line state back. In the meantime, the master would hold until the digital line returns to the original digital state and send the next transmission.


Thanks a lot for that advice, that is really helpful. I set a delay(1300); after Wire.endTransmission(true);
If the wire doesn’t work(which it probably will now) then I’ll use the serial line with a logic level shifter. If the arduino was reading 1 byte sent from the electron, not the coordinates, would this be because the master was transmitting too fast?

Yes. The I2C does not block at all. That isn’t all true. A read() will block until an error or it is done reading. If Wire.beginTransmission() happens too fast it will interrupt any in progress transmission.

The rule is only one Master can be talking at one time. That includes the current master itself.

I’d experiment with the delay. Start big, but then you can reduce it to get the appropriate timing.

Serial you can just stream away. It will add to the buffer. Stream too fast and you can overrun the output buffer. The serial has some nice functions to check the output stream. See: availableForWrite and blockOnOverrun.

@cermak, I believe when your refer to Wire.begin(), you mean Wire.beginTransmission(), correct? The former is used to initiate the I2C Wire object whereas the latter is used by the Master to begin a data transmission to a receiving Slave.

Correct, let me edit that. Thanks @peekay123

1 Like



In i2c flow control is usually done by holding the clock line low - so if a slave is having trouble keeping up then it should hold the clock low until it is ready for more data. Doing this should prevent issues of your master transmitting too fast, and the slave dropping data.