i2c, sourcing, pullup resistors

I hope I'm in the right spot. I swear I'm the opposite of Rainman when it comes to electronics. I think I got too late of a start.

Ok, so my first question is about the ATMEGA1284:

In the datasheet, it has the following:

"As inputs, Port C pins that are externally pulled low will source current if the pull-up
resistors are activated."

If the pull-up resistors are activated, aren't I telling the uC that I want it to "receive" the signal? Why would it put out a source?
And I guess secondly, why would I want to use the internal pull-ups? I tried searching for this answer, but apparently, my google searches suck, cuz I never find what I'm looking for.

This all brings me to my second question involving pull-ups:

I read in this older forum:
http://forum.arduino.cc/index.php?topic=46963.0

that using i2c, for 3.3V components, I can just use a 4.7k resistor to pull-up to 3.3V and I should be good? For some reason, I think I either read that wrong, or I'm an idiot. That can't be right, can it? I'm trying to hook up an ov5642, but it runs on 3V(everything I've read says I should still be able to get away with the 3.3V. So, if I wanted to hook that up to an Uno or a Mega, without a shift register, I would have to get the SDA and SCL down to 3.3V, Right? But I also read that the return signal from the camera module might not read it properly because of those internal resistors. I know I can comment out those lines, in twi.h, but now with this last thing I read(forum link above), I'm extremely confused.

And with all that, if I were to use a voltage divider and got the signal down to 3.3V, does that have to be on both SDA and SCL? If so, when it sends information back, wouldn't that be divided even smaller? If the Uno or Mega(if memory serves me correctly) needs atleast 3V(3.3V?) on a digital pin to be considered HIGH, then how would that work?

My head is spinning right now. I feel like I'm just running around in circles with all of this, and none of it makes sense. Please help. I feel so stupid, even though I do understand so much of this stuff, I just can't seem to wrap my brain around a lot of it.

If you activate the pull-up resistors in the arduino, that means, the input pin is connected through a resistor, internally, to the +5V.

This means, that instead of having some random floating state, the state of the pin will be high, unless something else is happening.

If you then connect the pin, outside the arduino, to some circuit or device that is trying to pull the pin low ( to ground ), then current will flow from the +5V source, inside the arduino, through the pull-up resistor, then out of the pin, then into the external circuit or device, and then to the ground through whatever process the external device or circuit is using to pull the pin low.

That's what the first part means. There is nothing wrong with it.

If the resistance of the external path is lower than the pull-up resistor, then the voltage at the actual pin will be low, and the state of the input ( if you are using the pin for an input ) will be low ( logical 0 )

You can try to use a 3.3V device on an 5V arduino.

What you have to do, is DISABLE the internal pull-up to 5V, and use an external pull-up to 3.3V. If the SDA and SCL lines are pulled to 3.3V, then the arduino and the external I2C device signal each other by trying to pull the SDA line to zero.

How to disable the internal pull-up, depends which arduino model you have.

It is recommended to use a 5V to 3.3V I2C logic level converter.

michinyon:
If the resistance of the external path is lower than the pull-up resistor, then the voltage at the actual pin will be low, and the state of the input ( if you are using the pin for an input ) will be low ( logical 0 )

I guess I still don't understand. What would be the purpose of using it? Or any pull-up for that matter?

michinyon:
You can try to use a 3.3V device on an 5V arduino.

What you have to do, is DISABLE the internal pull-up to 5V, and use an external pull-up to 3.3V. If the SDA and SCL lines are pulled to 3.3V, then the arduino and the external I2C device signal each other by trying to pull the SDA line to zero.

That's what makes no sense to me. How does a pull-up change a 5V source to a 3.3V source?

How to disable the internal pull-up, depends which arduino model you have.

It is recommended to use a 5V to 3.3V I2C logic level converter.

Yeah, I was looking at a logic level converter, but I couldn't seem to figure out how to connect it. None of that made sense either.

With SCL and SDA, SCL would be an output, correct? And SDA would be both an output and input since it has to transmit the data to the device? So the level shifter would take the 3.3V signal and convert it to 5V, and the vice-versa, correct?

I2C is open drain for CMOS parts - the outputs are set up so they can only pull low, and resistors (internal pullups to 5V, or external to 3.3V or 5V) are needed to bring the signals high.
So turn off the internal pullups, use external 4.7K to 3.3V, and you're good to go.
1284P will pull SCL & SDA low as needed. And when a slave wants to send data back, the 1284P will pull SCL low as needed, and the slave will pull SDA low as needed. The resistors will pull the lines high.

CrossRoads:
I2C is open drain for CMOS parts - the outputs are set up so they can only pull low, and resistors (internal pullups to 5V, or external to 3.3V or 5V) are needed to bring the signals high.
So turn off the internal pullups, use external 4.7K to 3.3V, and you're good to go.
1284P will pull SCL & SDA low as needed. And when a slave wants to send data back, the 1284P will pull SCL low as needed, and the slave will pull SDA low as needed. The resistors will pull the lines high.

So in other words, SCL and SDA are both outputs? BUT, whether SCL is LOW or HIGH is the deciding factor of how the data is sent or received?

Also, if I disable the internal pull-ups, then I can have a 3.3V and a 5V i2c device on the lines as long as the 3.3V is pulled up to 3.3V and the 5V is pulled up to 5V? The components will pull from 3.3V or 5V as they need it?

SCL is always an output for the master. SDA is an output, and then SDA is an input.
SCL is a clock, you will see bursts of 100KHz clock as bytes are sent back & forth.

Turn off the internal pullups. Pullup to 3.3V ONLY. All devices, 3.3V or 5V, will be happy with pullup to 3.3V. That's the nature of open drain. All inputs will see 3.3V from the resistor as a good 1, and ~0V from the individual device open drain MOSFETs as a good 0.

CrossRoads:
SCL is always an output for the master. SDA is an output, and then SDA is an input.
SCL is a clock, you will see bursts of 100KHz clock as bytes are sent back & forth.

I guess I just didn't see it change to an input in the wire library or in the twi.c/h code. I'll have to study up more on open drain and two wire applications. Thank you for the explanation.

Turn off the internal pullups. Pullup to 3.3V ONLY. All devices, 3.3V or 5V, will be happy with pullup to 3.3V. That's the nature of open drain. All inputs will see 3.3V from the resistor as a good 1, and ~0V from the individual device open drain MOSFETs as a good 0.

Ok, now if I don't want to change the wire library by commenting out the pull-ups, would I be able to turn them off in code by directly writing to the port? With the PINB(???) register(on an Uno).

I would think that if you did this after starting the Wire library they would be off:

Wire.begin();
pinMode (A4, INPUT);
digitalWrite (A4, LOW);
pinMode (A5, INPUT);
digitalWrite (A5, LOW);

ok, that would make sense, since in both the wire library and in the twi.c(++, can't remember which it was) neither one of those pins are ever changed to outputs. And knowing that pins are inputs by default, setting, say PORTC4 to a 1, will start the pull-up.

Thanks, much appreciated, as usual. And, thanks for recommending that ATMEGA1284 so long ago. Sorry I won't be buying it from you afterall.

From the datasheet:

22.5.1 SCL and SDA Pins
These pins interface the AVR TWI with the rest of the MCU system. The output drivers contain a
slew-rate limiter in order to conform to the TWI specification. The input stages contain a spike
suppression unit removing spikes shorter than 50 ns. Note that the internal pull-ups in the AVR
pads can be enabled by setting the PORT bits corresponding to the SCL and SDA pins, as
explained in the I/O Port section. The internal pull-ups can in some systems eliminate the need
for external ones.

Which should mean conversely, that with just a slight modification to the wiring library one should be able to disable the internal pull-ups it enables, allowing 5vdc arduino boards to properly work with 3.3 volt I2C devices just using external pull-ups to 3.3vdc.

retrolefty:
Which should mean conversely, that with just a slight modification to the wiring library one should be able to disable the internal pull-ups it enables, allowing 5vdc arduino boards to properly work with 3.3 volt I2C devices just using external pull-ups to 3.3vdc.

Yes, I'm already aware of the two lines that need to be altered(commented out), but as I stated before, I don't want to change the library. My main reason for this is I don't want to forget that I have done so and then destroy something in the future because I forgot about it.

xKoldFuzionx:

retrolefty:
Which should mean conversely, that with just a slight modification to the wiring library one should be able to disable the internal pull-ups it enables, allowing 5vdc arduino boards to properly work with 3.3 volt I2C devices just using external pull-ups to 3.3vdc.

Yes, I'm already aware of the two lines that need to be altered(commented out), but as I stated before, I don't want to change the library. My main reason for this is I don't want to forget that I have done so and then destroy something in the future because I forgot about it.

Suit yourself. But do keep in mind that the present default behavior of the wiring library (to pull up clock and data with 'weak' pull-ups to +5vdc) is contrary to the I2C standard/recommendations to use external pull-ups with much 'stronger' pull-ups dependent on transfer speed and amount of capacitance on the I2C bus lines with 4.7k ohms being a common value to use.

retrolefty:
Suit yourself. But do keep in mind that the present default behavior of the wiring library (to pull up clock and data with 'weak' pull-ups to +5vdc) is contrary to the I2C standard/recommendations to use external pull-ups with much 'stronger' pull-ups dependent on transfer speed and amount of capacitance on the I2C bus lines with 4.7k ohms being a common value to use.

Thanks, I'll keep that in mind.