Interrupt Pin Change Resources

My take on the various libraries available is that resources used by libraries in general are not well documented. My interest is nano & I realise other platforms may differ.

I believe I have got this correct. The Wire library uses D18 & D19 for the Data & Clock lines, and it uses Pin Change Interrupt 1 - so it “owns” those resources. SPI uses D11, D12 & D13 for MOSI, MISO and clock (plus another for device select), and it uses Pin Change Interrupt 0 - so it “owns” those resources. Coming to the software serial library, the only use cases I have seen thus far have assigned Port B lines for TXD & RXD & seem to need to “own” Pin Change Interrupt 0.

Is that a clash with SPI? Can it be installed on Port D ( say D6 & D7) allowing it to be connected to Pin Change Interrupt 2? “Under the hood” can both Software Serial & SPI both actually grab the same PCI_0. I realise Software Serial ISR would actually fire on an SPI change & vice versa.

I haven’t even looked at the implications on timers yet. They too I see as resources that might or might not be claimed by these software libraries.

A rotary selector is another popular device that might clash with TWI, SPI, Software Serial, etc.

I do have in mind some sort of table that documents the resources claimed by the various libraries, but, to me, this is important information that should appear in the key points summary published with any library.

If I’ve got it right, it would appear that I can’t easily build a widget with a TFT display for user interface output via SPI, a rotary selector for user interface input, and a serial device connected through the Software Serial library for the thing that my little Arduino is trying to play with.

Bottom line -
Is there a case for library publishers documenting the resources used?
Is that actually done, I just need to look deeper?
Do I strike a chord with anyone out there?
Does anyone disagree with me ? - I would welcome your reasoning.

Absolutely there is. However, unfortunately a lot of people writing libraries are not doing this. How would you suggest it could be enforced?

The only way to see what resources a library uses is to look at the source code and see.

Only one device can hold a vector, the second that tries will provoke the compiler produce and error message to the effect that this vector is already in use. It does this by comparing the default vector value with the current one before changing it. Simple as that.

I think some of your examples are wrong.

SPI uses the SPI hardware built into the Arduino, it can not be changed to run off any other pins. A software SPI could of course use other resources but not the SPI library as such.

Thank you Mike - whether Grumpy or not. You have saved me time to know that SPI doesn't claim the pin change interrupt vector.

Looks like I will be delving into the Software Serial source code ... or maybe not! Great that conflict is detected a compile time. Not trying to be picky & probably not thinking it through enough, I wonder if it's a link rather than a compile error. Seems to me each cpp is a separate compilation, producing some sort of object file. Each could populate the interrupt vector without that appearing in any shared header file, so each compile unit wouldn't spot the clash. Only when some bit of software tries to put these compile units together can the conflict be spotted. Sorry ... "just thinking out loud". You have given me enough of a steer to figure that one out with a little bit of test coding.

Fascinating one about how to enforce it. Seems like a case for guidelines for making a library module - but who would read that before jumping onto their computer & cutting some code? Then again, with a fair range of processor platforms with potentially different resources delivering particular features I can see the potential minefield that confronts me.

Yes, there are various phases a compiler goes through, it is not a one shot process. And I also agree it is probably at the link stage.

I am not an expert on these matters by any means, but I think it goes something like this:-

  1. Pre compiler - text substitutions are made for things in #define statements.

  2. Compile and optimised ( that is remove any code that does nothing, like an empty 'for' loop.

  3. Linking, when all the code is given absolute addresses to ensure they occupy different areas of memory. I think this is where vectors are checked.

  4. Production of a HEX format file that can be loaded by the boot loader.

Thanks @Delta_G. From what @Grumpy_Mike said earlier, I guessed that might be so, but hadn’t got around to checking that out.

All of this confirms I’ve got enough interrupts to do the job I’m working on right now. I’ve already got I2c & spi devices hooked up but was alerted to the potential clash when I add a rotary selector & software serial device each of which is using pin change interrupts.

The fact that the libraries for wire & spi present me with a pretty clean api has resulted in me not looking into the details of the av328 architecture in this respect.

Only RX needs PCINT, TX can be on any pin.

@Delta_G - good steer. Thanks.

You can dig through Software Serial Problem; the hard work was done for you :wink:

1 Like

This is all shouting to me that there is an argument for a mechanism to share a given interrupt amongst multiple clients. Rather than simply set the interrupt vector at build time, the client could register its void procedure to be called when the interrupt fires. This begs for the complementary de-register capability - even if rarely invoked.

OK, there would be a performance hit, and there’s a case for dual capability client libraries because you don’t want to carry the overhead if you’re the only “customer” of that particular vector. Maybe you just accept the minor hit of a compile time jump in the read only memory vector to a RAM location, the contents of which can be manipulated at run time.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.