DS3231/AT24C32 causing I2C problems

Oops... Rats!
I just discovered that that didn't fix the Problem. In my haste (and after a Long work day), there was something wrong in the code and I wasn't turning the switched 5V back off afterwards. Now that I turn it back off, the problem is still there. So, it's back to the drawing board...

I'll download the library now...

I did notice one thing though... It always works the first time until the peripheral 5V is switched off. It gets switched back on again before the next scan and the I2C scanner locks up. It seems that this only happens if the 5V is switched of for an Extended period.

I'll investigate that further too...

NOTE: it is possible to read the RTC without VCC. There is a setting to tell it to work when operating off battery.
I can't remember off hand what it is, but I've definitely done it (by accident).

I'm not exactly sure what you are doing and what you mean by "lock up".
Can you provide a detailed description of what you are doing that causes a "lock up" and what that means?
It might also be helpful for us to look at the code you are using and the schematic of your circuit.

If you are using an existing DS3231 module, many have power LEDs and pullups on them.
The LEDs typically have cathode wired to ground and anode wired to a 1k resistor which goes to vcc.
The SDA and SCL signals often have 4.7k pullups on them wired from the signal to VCC.

If you simply yank vcc, then there can be some problems.

If there is no power going to the VCC signal on the module, then the VCC signal on the module will likely be pulled low by current flowing through the 1k resistor through the LED going to ground. This might be strong enough to pull the SDA and SCL signals down low as well as they connect to on board pullup resistors that connect to the same VCC signal that feeds the resistor going to the LED.

Also, without any voltage on the VCC module signal, VCC going to the DS3231 and the AT chip will also likely be very close to ground. So if SDA and SCL were pulled up, then this might be an issue for the chips since the active VCC voltage being held up by the AVR internal pullups on the SDA and SCL pins of the i2c chips would exceed the maximum ViH and ViL for the chips since the VCC going to the chips would effectively be zero.

BUT.... If there are no other pullups on the signals other than the internal AVR pullups, then the actual SDA and SCL signals may actually be pulled down by the LED circuit. If so, it creates a broken I2C bus that will not function.
The good news would be if this is the case, then the ViH and ViL of the I2C chip on the RTC module is not being violated.

I'd be curious if the I2CexpDiag code detects the SDA and SCL pins as being stuck low when you remove VCC.
You probably should measure the voltage on the pins with a meter as well.

In the larger picture, I think you will need to do some modifications to your circuitry to make sure that the pullups are working correctly and that things are properly isolated when power is removed.

--- bill

Yep.
I hooked up a DS3231 RTC module that I think is like the one you have and sure enough, the led circuit will yank the SDA and SCL lines down because the LED is trying to get power from the SDA and SCL lines when the VCC signal to the module is not connected.
The pullups in the AVR are so weak that they can't supply enough power so the signals droop down as the LED is basically acting like a pressed button or a short to ground.
You can't fix this by simply adding external pullups as then the voltage on the SDA and SCL pins of the i2c chips on the RTC module would be beyond what is allowed.

You will need to rethink your approach.

But why are you attempting to use the I2C bus when the devices are powered down anyway?

--- bill

bperrybap, first off, a Million thanks for the effort you are putting into trying to help me! I do appreciate it!

I am not attempting to use the I2C bus when the devices are powered down. I have a MOSFET attached to digital pin 4 so that pin 4 turns power on/off. On my custom PCB I have multiple I2C connectors and each connector has a Jumper so that the I2C VCC can be set to either constant 5V or switched 5V. The final Project must use as Little power as possible, thus turning peripherals off. The main Project will sleep for multiple Counts of 8 seconds and at some Point wake everything up. My intent is to turn the peripherals off before going to sleep and turn them back on when waking, taking some sensor readings, turn the heat on/off, log the data to the EEPROM, turn the peripherals back off, go to sleep... repeat indefinitely.

First step is of course to test all the Hardware. The custom PCB has an Arduino Pro Mini on it with the on board voltage Regulator and LED removed (unsoldered the blob in my case). It also is physically attached piggyback onto an I2C 20x4 Display and has all the other Connections required. The custom PCB seems to be working fine, the 5V switching works as predicted, the Display works, no smoke.

If I run the PCB board in that configuration, Nick Gammons I2C scanner sees the LCD and everything works.

Then I plugged the RTC/EEPROM Module in, set the I2C connector to constant 5V and the I2C Scanner worked fine. I set the I2C connector to switched 5V, temporarily modified Nick Gammons I2C scanner to turn Switch the 5V on before the scan and off after the scan and the scanner works ONCE.

By locking up, I mean that the I2C scanner sends "Scanning..." to the Serial Monitor, I see the LED on the RTC go on... The I2C scanner never says either "Done" or "No devices found" and the LED never goes off.

I am using the Standard Wire.h and I have read about it sometimes locking up.

More Research last night and I "discovered" that lots of People have had Trouble with These RTC/EEPROM modules if they try to turn VCC on/off. They don't seem to work as engineered. I found one really good article from a guy that made several power saving mods to that module and that also solved his locking up Problems. Once testing were completed, I don't Need that LED on the RTC and would remove it (during testing it's nice to have unless its causing the Problems). I don't usw the onboard RTC Interrupt so those pullups can also be removed. I don't care if the EEPROM address is 0x57 or 0x50 so those pullups can also come out.

I figured it was better to test as you go but may Need to rethink that. I bought several of the RTC/EEPROM modules anyway so I think I'll mod one and continue testing with the modified one. I can Switch modules with an unmodified if Need be to see if my mods have introduced Problems.

I'll post some Pictures tonight and maybe you can provide your thoughts on the proposed mods.

Hey Jaba,

First an explanation: my patch sets the control register of the DS3231 to the factory default start-up condition. The first 0 (bit 7) means that the device's oscillator is on when powered by the battery only. This is what I thought might be relevant to your issue.

Now a question - is it possible that the DS3231 board you are using is defective? I do use boards, but I like the ones without LEDs or other tangential components. My favorite is the Chronodot™, which merely translates the chip's pins to a cute, round, blue pcb. It's got holes and solder pads so you can install onboard pull-up resistors, and a 1632 battery holder is already hooked up. Oh - the chip has a decoupling cap on the board as well. It's kinda pricey. You can get cheap DS3231 boards, which are rectangular, that also include 4K7ish pullups and a 1220 battery holder. For (often less than) the price of the Chronodot™, these boards are functionally identical*, and take up half the space. (* they do not allow you to choose or skip the i2c pull-up resistors.)

I love how accessible they have made the DS3231 chip. I guess the next step would be a chip-sized rubidium oscillator.

Anyways. try another DS3231 device, and be sure it's not just a bad part. These chips are shock sensitive. And see if using the AVR's internal EEPROM might not be the way to go.

Maybe of interest: Bug on WIRE.H library from Arduino - Programming Questions - Arduino Forum

People have had Trouble with These RTC/EEPROM modules if they try to turn VCC on/off

Take a look at http://www.maximintegrated.com/en/app-notes/index.mvp/id/504 which has information on how power glitches can affect the RTC. It is quite possible that power spikes , particularly negative voltages during disconnect can corrupt the RTC. See the trouble shooting new designs section.

They recommend the use of a Schottky diode and other solutions.

JaBa:
I am not attempting to use the I2C bus when the devices are powered down.

I understand your intent but we can't verify that as you have not posted the code you are using.
Please post the code you are using.

From a h/w perspective, powering down and re-activating i2c slave devices that are still connected to a live i2c bus isn't as simple as just yanking and re-applying power to the slave.
You will also likely need to isolate the bus signals as well to avoid violating ViH of the slave device's i2c pins and to keep from corrupting the masters i2c signals and it may also involve having to do a few extra things in s/w during the power re-activation.

And also, complicating things is that it sounds like you have multiple pullup resistors being used in your circuit and the internal AVR pullups are very weak.
Without isolation of the i2c signals from your slaves when they are powered down, you are going to have issues.

I don't think this is really an issue of the slave or the i2c slave module not working as engineered but more of an issue of creating i2c signal issues by powering down slaves that are not isolated from the i2c signals and using slaves that also have their own pullups.
But that is just a guess since we don't know the exact h/w circuitry you are using.

--- bill

Chris, I tried another RTC/EEPROM module (which is probably from the same batch?) and had the same problem.

sterretje, Nick Gammons I2CScanner checks the return code and only reacts when receiving the proper code. Nonetheless, I modified the code and looked at the return codes. For scans that work, unoccupied I2C addresses return code 2, occupied addresses return code 0. Once the code locks up it obviously returns nothing because it seems to stop. I get the "Scanning..." line and nothing else so either Wire.beginTransmission(address) or error = Wire.endTransmission() seems to lock everything up and never complete.

By adding Serial.print() and Serial.flush() it seems that the lockup occurs because the error = Wire.endTransmission(); never returns.

I read SCL and SDA prior to both of those two lines and neither are LOW.

cattledog, I do not see any data corruption on the RTC. I can set the clock, run the code that causes the crash multiple times, read the time and everything is still ok.

bperrybap, it's not that easy to post the code, I've done a hundred mods with various debugging code. OK, I will do a code reset and post it. The wire.h turns the internal pullups on, the RTC module has 47K pullups. The LCD is unknown but I get no reading between SDA/SCL and VCC there. An Analog Read of SDA and SCL just before doing any I2C work returns a value of 1021. Can't get much higher than that.

Ok, this is Nick Gammons I2C Scanner which I have been using to test the Hardware. I have made a few mods to turn the peripheral 5V on/off at the correct times.

// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// Version 6, November 27, 2015.
//    Added waiting for the Leonardo serial communication.
// 
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//
 
#include <Wire.h>
 
 
void setup()
{
  Wire.begin();
  Serial.begin(115200);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
  
  // JaBa mods - Peripheral 5V is controlled by pin 4
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW); // LOW = on!
}
 
 
void loop()
{
  byte error, address;
  int nDevices;
 
  // JaBa mode - Turn Peripheral 5V on
  digitalWrite(4, LOW); // Low = on!
  delay(500); // Give power time to stabilize. I've tried up to 5000...
  Wire.begin(); // I've tried it with this line commented out as well...

  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);

// Using Serial.print with Serial.flush, I have determined that
// the second time through, it stops right here!

    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknow error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }

  // Jaba Mods - Turn peripheral 5V back off
  digitalWrite(4, HIGH); // High = OFF!

  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}

It runs fine the first time (since the peripheral hasn't been turned off yet) and locks up the second time through. I have commented the Point that locks up within the scanning Loop.

This is the Output in the Serial Monitor.

I2C Scanner
Scanning...
I2C device found at address 0x27  !
I2C device found at address 0x57  !
I2C device found at address 0x68  !
done

Scanning...

And this is a Picture of the DS3131/AT24C32 module I am using.

From the Pro Mini, digital pin 4 goes to a 320 Ohm resistor and then to gate of the MOSFET. The MOSFET Gate is usually Held high. When Digital 4 pulls it low, 5V is passed from Source to Drain.

The switched 5V from the MOSFET goes to a bus which supplies various connectors. The connectors are for I2C devices and other peripherals. All of the I2C connectors have a Jumper to be configured to use either constant 5V or the switched 5V from the MOSFET. At the Moment, only the DS3231/AT24C32 is attached to one of those connectors.

5V to the Arduino, LCD (through a separate momentary normally open Switch), and the MOSFET for the peripherals is all supplied by a 7W OKI switched Regulator (pin compatible drop in replacement for 7805).

All your i2c devices are all sharing the same i2c bus right?
It sounds like you have isolated VCC from the i2c modules (when you jumper it to be switched VCC) but not the SDA and SCL signals from the powered down devices.

I'm not sure which LCD you are using but given the address of 0x27 I'm guessing it is an hd44780 with a PCF8574 based backpack on it.
Some of those have pullups on the i2c signals but some don't.

The backpack is likely to have pullups on it at least for the address jumpers.
Particularly, since you have an address of 0x27.
So it may have issues when powered down when connected to live i2c signals.

There are likely to be issues when the ic2 signals are not isolated from powered down devices especially when there are still active pullups driving the i2c signals.

When the the VCC going to the RTC module is yanked, the VCC level of the VCC signal on the module going to DS3231 and the EEPROM will be pulled down to ground by the on board I2C pullups, the EEPROM address pullups, and LED circuit.
But the i2c signals will still be at 5v since there are active pullups holding it up - especially if you are still powering another i2c device that has pullups on it.
This will violate the ViH for the parts on the powered down devices.
Even if the RTC module I2C pullups, the LED circuit is removed, and the EEPROM address pullups are removed to try keep the VCC from droping down, the VCC voltage then becomes undefined which still violates ViH.

Trying to use parts outside the manufacturer recommendations in the datasheet is always risky.

You might want to try isolating the i2c signals as well.
If you google around you can find information about how to handle/isolate i2c slaves that are powered down, but basically you can use a voltage level shifter and just have the same voltages on each side. That will provide isolation. Just make sure it isn't one that allows you to feed in both voltages vs having a 3v voltage regulator on it.

--- bill

bperrybap, I was able to solve the Problem. I posted that but in my haste, something went wrong and it didn't Show up. Probably my fault as I was excited as a teenage Girl on her first date with the quarterback.

You are correct, the MOSFET cuts the VCC to the peripherals, including I2c (of which only one device is currently connected).

What solved the Problem was adding this line before turning the MOSFET off.

TWCR = 0; // reset TwoWire Control Register to default, inactive state

This came from forum.arduino.cc/index.php?topic=425303.0, a contribution from ChuckTodd at Sep 22, 2016, 04:20 am.

The I2C no longer locks up. I will want to further Research exactly what is being done with that one line. Actually, I suspect that you have been right all along that turning off the power with all those alternate paths on the RTC (through the pullups, etc.) was causing the Problem. This line of code seems to prepare the I2C bus for a shutdown. I already had the Wire.begin in there to try to reinitiate it, but without the shutdown preparation it wasn't enough.

This line of code is beautiful because it requires no Hardware mods, no library mods, etc as I have seen other suggestions do. Actually, I already had the scalpel on the table to start cutting traces on the RTC when I found the contribution from ChuckTodd. Bless that man!

You are probably being burned by glitches on the i2c signals due to the way you powering down/up your slaves since they are not properly isolated from the SDA and SCL signals.

The i2c implementation on the AVR is pretty ugly under the hood.
It is even uglier on Arduino given the way the Wire library code was written.
For example there is no reason to double buffer master transmissions since the underlying twi C code is synchronous.
i.e. they could have doubled the maximum transmission size without using any more RAM by simply writing the master code better/smarter.

But the main ugliness is the complexity of the code since the i2c implementation is mostly in s/w.
The h/w only handles a very minimal portion of the protocol - the very low level timing and transmission.
All the other portions of the i2c protocol and all its states are handled in s/w.

In this case I'm guessing that the s/w state machine has become confused and is stuck waiting for an event that will never happen.
I have seen an issue like this.
In my case I have an text i2c LCD, not a LCD backpack but an LCD that actually talks directly to the i2c bus.
It does not support reads. If you attempt to read from it, it treats it as a write, and generates a ACK at the end of the data byte, (which is wrong). This causes the Master to think that there is another master on the bus and so it jumps off the bus to allow the other master to do its transaction.
The problem is that there is no other master, and the s/w state machine is in such a state that it is waiting to see a STOP from that other master, and no STOP is ever going to occur. The s/w will wait forever.
(This state is part in h/w and part in s/w, but the s/w is polling the h/w waiting for a STOP)
IMO, the s/w should recover from this as there is a well defined amount of time that a transaction must complete.
If the STOP was not seen in that amount of time, the s/w should reset back to the idle state and recover, possibly returning an error.
So in my view this is a bug in the low level TWI s/w.
Others may argue that this was all triggered by a misbehaving slave and it isn't always possible to handle every possible conditions from misbehaving slaves.
However, on the other hand, this can also be triggered by hot plugging devices while transactions are in going AND if you trigger the state without locking the s/w (which is possible to do) a call to begin() before attempting to use the bus again will not clear this state and the lockup will occur., so I would still say that is a bug.

I'm guessing that you are likely seeing this same issue since the way you are powering down your slaves is going to corrupt the i2c signals.
And this is likely confusing the i2c implementation that there is another master trying to do something.

The slam of that TWCR register is resetting the h/w state machine. Which i'm guessing was likely indicating a state of waiting for a STOP. And if so, clearing it will ensure that the s/w doesn't get stuck waiting for an even that will never occur.

You need a logic analyzer to be able to see the signals to see what is really happening.
I'm guessing that not properly isolating the slaves from the live i2c signals when you power them down, is creating the same problem that I ran into.

But even if you do this reset of the i2c h/w state, it doesn't fix the real issue.
And keep in mind that driving the i2c pins of the chips with voltage above their VCC input voltage (which is what can happen when some slaves are still powered up) is violating the chips specifications so it may eventually cause problems. (damage to to the chip)

--- bill

Bill, you commented in that post, twice, to the effect of "not properly isolated from the SDA and SCL". I will admit that I butchered this circuit together with absolutely no prior knowledge of I2C. What I basically did was to use tricks from Nick Gammons articles about saving power. The circuit to power the peripherals off was from his site. I did my best to Isolate SCL/SDA from Spikes by putting the ground line between them, which is weak at best. I am trying to stay as close to accepted standards as I can. I am full bore open to any Suggestion you may have as to how to better "Isolate SDA and SCL" when powering I2C devices off. If that means I have to redesign the PCB, so be it (there are a couple things I would do better the second time around anyway).

The problem you are having is because you have isolated VCC going to the slaves from the real VCC to turn off the power (you use a FET to disconnect the slaves VCC signal from the actual VCC power signal when you turn off the power.)
However, you do not do any isolation for the SDA and SCL signals.
You have left the SDA and SCL lines still connected to the slaves even when you turn off the power.
This means that SDA and SCL could have voltage on them when VCC to the part does not.
The devices/chips are not designed to work this way and is violating the i2c chips specifications.

This is compounded by the modules you are using having their own pullups and additional circuitry that are connected to the module VCC signal.
With the modules you have, when the real VCC is isolated from the module VCC (disconnected) there is no voltage on the modules VCC input (The module VCC is essentially floating), the circuitry on the module will allow current to flow to ground through various module components to pull the VCC voltage level the chips sees down to ground.
This will cause the VCC signal going to the i2c chips on the modules to be at or near zero.
This back current will also over power the internal AVR pullups on the SDA and SCL signals push them down to ground.
So the circuitry you have is corrupting the I2C bus signals as well as violating ViH for the i2c chips.

That is the basic problem.

I'm not sure which page of Nick's you are looking at but I'm assume this one:
https://www.gammon.com.au/power

Your circuit is very different from the simple circuity that Nick showed as yours involves multiple modules and i2c chips with multiple ways of powering them vs his just powering a single chip with no other components.

Even in Nicks DS1307 real-time clock power circuit, ViH (which is VCC+0.3v) will be violated.
However, in his simple circuit, there are no other external components so the SDA and SCL signals will not be corrupted when the power is removed to the DS1307.
I'm guessing violating ViH doesn't damage the DS1307 chip, but the datasheet says not to do that.

If you google around you can find information about how to isolate powered down i2c devices from the i2c bus signals. One easy way like I mentioned in post #32 would be use a voltage level shifter.
In this case the voltage level shifter wouldn't be actually shifting the voltages but rather simply isolating the signals between the "real" bus (the AVR SCL & SDA pins), and the powered down bus.

--- bill

Bill, you're looking at the correct reference to Nick Gammons page that I used. I am not powering the clock directly from a digital pin. That sample from Nick was for powering single low power devices and just happened to be a RTC. The sample I am using is from a Little further down that page where he turns unnecessary peripherals off using a MOSFET. Again, the peripheral I am currently using also just happens to be a module containing a RTC. I Chose the MOSFET method because the end Project will also have other sensors which I want to turn off (and which also happen to be I2C, MCP9808 temperature INA219 Volt/amp,...) I will be turning them all off at once using digital pin 4 and the MOSFET.

I am being overly optimistic and simplistic. My (naive) design on my PCB was to have multiple I2C connectors and each has a Jumper to configure it for constant 5V or switched 5V. If I use voltage Level shifters, it isn't as easy as moving the Jumper. I'll have to Research and see if I would Need a shifter for each connector or not. Possibly I could provide "constant I2C" connectors as well as "switched I2C" connectors.

Again, being overly optimistic, simplistic, and naive, I hadn't considered all those alternate paths. After "solving" the Problem with TWCR = 0, I assumed that the I2C but was no longer powered. Further testing Shows that this is not true. After TWCR = 0, the SDA/SCL Pins have about 1.5V on them. I also added digitalWrite(A4,0) and digitalWrite(A5,0) after the TWCR = 0 and both Pins now fall to 0.0V when I turn the peripherals off. Have I successfully "isolated", through Software, the I2C bus if I always follow this sequence?

Here is a sketch which does nothing but read the time every couple of seconds but it demonstrates the current program and how I am attempting to power off/on the peripherals.

#include <Wire.h>

byte second, minute, hour, dayOfMonth, month, year;

void setup()
{ pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);
}

void loop()
{  digitalWrite(4, LOW); // Turn 5V Peripherals on
   delay(100);           // Allow power to settle
   Wire.begin();         // Initialize I2C bus
   readDS3231Time();     // Read time from RTC
   //Waste some time... as if we were doing other things
   //And allow time to read the multimeter
   delay(2000);
   TWCR = 0; // reset TwoWire Control Register to default, inactive state
   digitalWrite(A4,0);  // Without these two lines, SCL & SDA
   digitalWrite(A5,0);  // Remain at about 1.5V. With these 2 writes, both go to 0.0V
   digitalWrite(4, HIGH); // Turn 5V Peripherals off
   delay(2000);
}


// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{ return( (val/16*10) + (val%16) ); }

void readDS3231Time()
{ Wire.beginTransmission(0x68);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  second = bcdToDec(Wire.read() & 0x7f);
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read() & 0x3f);
  Wire.read();  // Ignore day of week
  dayOfMonth = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read());
}

JaBa:
The sample I am using is from a Little further down that page where he turns unnecessary peripherals off using a MOSFET. Again, the peripheral I am currently using also just happens to be a module containing a RTC. I Chose the MOSFET method because the end Project will also have other sensors which I want to turn off (and which also happen to be I2C, MCP9808 temperature INA219 Volt/amp,...) I will be turning them all off at once using digital pin 4 and the MOSFET.

I knew all that already. You previously described your h/w.
The simplicity I was pointing out was not the simplicity between directly powering the slaves using an Arduino pin vs using a more complex circuit like an FET, but rather the simplicity of the i2c bus in Nicks sample circuit. In Nicks example, nothing is on the bus other than a single chip.
You have multiple things connected to the bus(s) and they are not just the chips.

I am being overly optimistic and simplistic. My (naive) design on my PCB was to have multiple I2C connectors and each has a Jumper to configure it for constant 5V or switched 5V. If I use voltage Level shifters, it isn't as easy as moving the Jumper. I'll have to Research and see if I would Need a shifter for each connector or not. Possibly I could provide "constant I2C" connectors as well as "switched I2C" connectors.

By having the option for "always on" vs switched power for your slaves, you have essentially created two i2c busses that will need to be isolated from each other.
You will need to isolate the powered bus with live pullups on it from bus signals that are connected to the powered down slaves.
You are likely going to have problems if you attempt to have some devices powered and others not powered when they are all directly connected to the same bus signals.
So if you really want to do that, you will need to isolate the powered bus signals and powered slaves from the non powered bus signals and non powered slaves.

You will also have issues (as you have seen), if you use many of the readily available i2c modules that contain additional circuitry when the modules SDA and SCL signals are not isolated from the active i2c bus.

Again, being overly optimistic, simplistic, and naive, I hadn't considered all those alternate paths. After "solving" the Problem with TWCR = 0, I assumed that the I2C but was no longer powered. Further testing Shows that this is not true. After TWCR = 0, the SDA/SCL Pins have about 1.5V on them.

The Arduino Wire library low level twi code on AVR based parts turns on the pullups when you call begin().
The pullups are not part of the dedicated AVR I2C h/w.
The Arduino code turns them on to try to make things simpler for newbies. - These pullups don't exist on other platforms such as the ARM, PIC32, or ESP platforms.
As I've said before while those internal AVR pullups will work for certain configurations, they are way out of spec and in many configurations they are simply to weak to function reliably.
i.e. You may start to have i2c issues when you start to hook more devices to your bus.

The voltage on those pins after begin() is called will be VCC (5v) as the AVR pullups are explicitly enabled.
The reason you measured 1.5v is likely due to the way you measured it which likely influenced the voltage reading.
I'm guessing you used some sort of voltmeter to measure the voltage and the volt meter's internal impedance will act as a voltage divider on the AVR pullup.
The AVR pullups are very weak about 30k or so, and if you had a volt meter with a 10k impedance, then the voltage reading would be about 1.5v instead of the actual 5v when the meter wasn't connected.
10k impedance is pretty low, as many meters now have impedances in the mega ohms, but I'm guessing that is what is happening.
Here is more on this: http://www.allaboutcircuits.com/textbook/direct-current/chpt-8/voltmeter-impact-measured-circuit/

I also added digitalWrite(A4,0) and digitalWrite(A5,0) after the TWCR = 0 and both Pins now fall to 0.0V when I turn the peripherals off. Have I successfully "isolated", through Software, the I2C bus if I always follow this sequence?

No, you have not created any isolation. All the modules/chips are still connected to bus since you only have 1 bus. This won't work since you seem to be wanting to have an always on set of i2c devices and some that are switched on/off (you have two sets of i2c connectors). If you want to turn off some devices but leave others always on, you will need to isolate the powered down devices SDA and SCL signals from the live bus SDA and SCL signals.
Essentially, you seem to want to have two i2c busses, one that is always on, and the other uses slaves that can be powered down, that share the same i2c address space, but the h/w you have does not support this as it is just a single bus with no isolation of the signals between the powered devices and powered down devices.

In terms of disabling the TWI h/w inside the AVR,
the Wire library now contains a end() function.
This will disable the TWI hardware and turn off the AVR pullups on the SDA and SCL signals.
I would suggest that you use that function rather than muck with the AVR h/w directly.
You will need to do that before you yank power to the slaves.

While that will cleanly shutdown the TWI h/w and that may solve the lockup you were seeing, it won't solve the issue of wanting to power some devices and power down others on the same bus.
In order to have some devices that are still powered and others powered down, means:

  • the SDA and SCL signals are still live with pullups on them pulling the signals up to VCC.
  • the powered down devices can potentially corrupt the SDA and SCL signals
  • the powered SDA and SCL signals can potentially fry the powered down i2c slave chips since the voltage on the SDA and SCL signal is exceeding the chips ViH maximum allowed voltage value.

You are either going to have to abandon the idea of having some devices powered while others are not, or are going to have to properly isolate the SDA and SCL signals of the powered down devices.

And even if you abandon the idea of supporting the always on bus, and decide to connect all the devices to the switchable power, depending on how you handle the i2c pullups, you may still have the issue of pullups as the internal pullups are simply too weak and may not work once you start to load up the bus with all your devices.

I think at this point you have all the information about the issue, and will need to make some decisions as to how you want to proceed.

--- bill