Resources tied up by the I2C protocol

I am curious... when using I2C to communicate between an Arduino and a slave or multiple slaves or another Arduino, whatever the case, what other functions of the Arduino (if any) are unavailable for use or cannot be properly used, while I2C communication is going on?

What I mean by this is, I know for example that some features utilize certain hardware, like how the timers sometimes use interrupts or how evoking certain software commands like delay can use the timer hardware. In such cases, trying to use that hardware could screw up the first activity that was set up. My concern is that enabling 1 activity that uses a certain piece of hardware makes it impossible to simultaneously utilize a different piece of hardware that depends on the first.

So does using I2C communication mean you can't use something else at the same time? For that matter, if you've got a program that's using hardware interrupts, SPI, I2C and timers all at the same time, what is the bottleneck (what's the weak link that's going to break first) and is there a proper way to utilize multiple hardware features of the 328 without having them conflict with each other? Is there a guide on this anywhere to say what any given hardware feature will disable or screw up when you turn it on? Thanks.

Seems to me little bit "academic" question. Generally, ATmega MCUs include the 328 cannot do more than just 1 thing at time. There are some rules how the program is processed, probably better is to study the datasheet yourself.
To simplify somehow, the MCU performs an instructions from program/sketch one by one. If the interrupt occur, the MCU goes to interrupt routine (ISR). All interrupts have priority order and internal register with flags of occurance which allow to remember one interrupt from each kind if the MCU is busy e.g. with interrupt with higher priority. After the ISR ends, the MCU can go to normal program processing.
Even the MCU cen perform only one thing at time, it is able do "several" things at time seemingly from user view, if the MCU is fast enough. It is question question of balanced load.
I2C uses interrupts, timers also, etc. You can use these features at once.

For an example, I made a device for heating system based on the Arduino and ATmega1284P. Only one MCU service the I2C LCD for displaying (LCD is slow device in compare with MCU). It has RTC for precise time (seconds have to be updated just once in second - very slow in compare with MCU). There is measurement like temperature (once in 0.75s - slow), several logic inputs and of course it drives the relays. In addition, it has the serial console with command line (serial line is not very fast) and second serial for communication with superior system. All things controlled by one ATmega.

So does using I2C communication mean you can't use something else at the same time?

No, definitely no.

For that matter, if you've got a program that's using hardware interrupts, SPI, I2C and timers all at the same time, what is the bottleneck (what's the weak link that's going to break first) and is there a proper way to utilize multiple hardware features of the 328 without having them conflict with each other?

I thing, there is no simple answer. General rules about the ISRs (ATmega) is: make the ISR as short as possible and do not call interrupt dependant functions from ISR.
If the ISR requires more complicated algorithm then just set some flag and perform it in the loop() later. The MCU is fast enough to do it seemingly in real time, if your program do not waste all that power (like with delay(3000) statement).

s there a guide on this anywhere to say what any given hardware feature will disable or screw up when you turn it on?

No HW feature is enabled by default in sense of your question. It have to be programmed some service routine.

It may depend on the Arduino that you have. On an Uno, I believe that the only thing that I2C causes you to lose is the expected couple of digital I/O pins.

Right, my question wasn't so much about multi-tasking or parallel instruction execution as it was about hardware elements being tied up by 1 activity so that they cannot be used for another.

As vaj pointed out, you lose a couple of analog inputs (you said digital but I think you mean A4 and A5) but you also need a clock pulse to synchronize the activity and I don't know if this involves the timers in any way. Furthermore, I don't know if the ADC MUX is affected by the constant use of the A4/5 pins so that A/D conversions would be impaired in any way... If I'm using all 8 channels (2 for communication and 6 for actual inputs), I wonder if the I2C can cause any anomalies or noise?

I have read the manual a couple of times so I'm familiar with all the feature sets and roughly how they work but it's the interplay and how to code them properly that eludes me. Something as simple as calling cli or sei for 1 reason can butcher something that was already set up and working, like some timing or counting that was going on in the background. Therefore, to avoid using high level library functions whos low level code may or may not conflict with another function, I need to understand the low level commands that conflict and avoid calling them in an overlapping fashion... to learn "time management" if you will, for the MCU's hardware.

Case in point: I want to have several arduinos talk to each other over I2C. At the same time I want to run an SPI 2.8" display off the master AND measure several analog channels, and monitor a hardware interrupt which will measure RPM and use the Talkie library to drive a speaker, which I understand makes use of one of the timers.... so there's a lot going on and because of the application-driven nature of what I'm doing, I don't necessarily know when things are going to happen. It all depends on the environmental circumstances and what inputs occur when. Therefore I don't want certain pieces of hardware in the MCU tied up when some other activity needs to occur, which uses those same pieces of hardware. I don't know how to properly plan ahead for these contingencies.

Read the datasheet(s) of the processor(s) involved in your project :wink:

That's part of the fun of using Arduinos.

I've read it over a couple of times actually. Perhaps it's too technical for my current computer science understanding... I grasp the individual concepts behind the operation of any given hardware element, like how the timer works, but holistically, when it comes to strategizing about how to use them all in harmony with each other, I get lost. I feel like some software command I issue is going to interrupt something important that was going on because of the interplay between systems that I'm not consciously aware of.

Gahhhrrrlic:
(you said digital but I think you mean A4 and A5)

remember, all those pins with the A's in their names are digital pins first and foremost. The fact that they can be used to read analog voltages is their additional function. Many pins on the board have more than one function, like on an UNO 10, 11, 12, and 13 are also the SPI bus and 0 and 1 are hooked to the UART. But first and foremost they are digital pins.

To get to the heart of your question, the I2C functions are driven by their own hardware. The only thing you lose is the two pins.

I wonder if playing with the build tools would help the systems interplay to be less mysterious.

Arduino likes to keep that stuff out of view but I like it front and center. I'm going to link to a C program that uses a Makefile.

A Makefile is a set of rules that tells the compiler, linker and in this case avrdude what I want it to do (I am no expert at this, so everything should be taken with a grain of salt).

The most painful part of a makefile is finding an editor that knows about the tab character that starts each line of the rules actions (Visual Studio Code seems to know... OMG I recommended a Microsft program... it may be the end).

For myself, I like to know what objects are built (and sent to the linker), and where they are from. The blinkLED makefile builds three objects (main, uart, and timers) and feeds them to the linker that produces blinkLED.elf, which is then given to a program called avr-objcopy to build a hex file. That last step is pointless since I can send the elf to avrdude nowadays, but I am old and set in my ways. Actually, if I kept the elf and if the 328p had JTAG I could learn how to debug with gdb perhaps (not today I guess).

The timer object was built with the code I hacked from various places including the Wiring files in Arduino. The important thing is that it is a small file and I know where to add the 328pb timers which I want to work on.

The mystery of how the timers got setup vanished because I can see the call to initTimers() in the main function (I totally forgot how that is hidden by the Arduino IDE, but for about a week I knew).

Ron, you lost me in the sophistication of your computing prowess but I like your style. Make the software spill its secrets!

Delta I'm relieved that I2C isn't as invasive as some of the other hardware. Unfortunately I'm using just about everything the Arduino is capable of, pretty much at the same time (not in the technical sense but close enough) so I think there's a good chance something will malfunction because it'll be disabled or interrupted by something else. I just hope my car doesn't implode as a result.

It can't be worse than a Microsoft Windows based control system that tells you during an ABS failure to close all your windows and restart :smiley:

If you post up what you've done we could look and see if we notice any conflicts.