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