to have time to check some GPIO input every few micro seconds.
How long is "a few micro seconds" ?
If it is in the ball park of under 10, (which is what I think of when the word "few" is used), THAT is going to be very difficult if not impossible to always meet.
Polling is not the answer as there is no way to always meet that type of timing requirement even on a very fast processor as eventually something that takes longer will likely need to be done.
Depending on the processor even something as simple as a single digitalRead() can take longer than a few microseconds.
I think at this point to provide any sort of guidance, a better understanding of the actual project needs to be disclosed.
thank you for your thought, I appreciate.
As explained (but I realize that the title of the thread was not exact), my intent was to find a solution to print data on LCD without disturbing the collect of data (from Hall sensors and encoders) ,their computation and the release of results.
I was expecting to find an "on the shelf" solution, and I finally found one solution by proceeding stuff in parallel. See my sketch above.
This may not be the best solution, and it is for sure not the most sexy sketch, but at least that works .
However, if some other solutions can be considered "at low cost" (time for me), then I am ready to investigate.
thank you
The I2C bus is too slow to meet your requirements. At 100000 speed it takes 90 usec to send a byte and 4-5 bytes per character on the screen. Speeding up to 400000 BPS helps but not nearly enough. After that, most Liquidcrystal versions for I2C still throw away half the bandwidth. And BTW, I know for a fact that I2C on the pico does NOT use interrupts.
PCF8574 used in most backpacks has a maximum SCL frequency of 100kHz. i.e. the standard I2C bus speed.
Yes, you might find that the PCF8574 "works" at 400kHz.
But this is 400% overclocking.
You still have the same number of I2C interrupts which take the same number of CPU cycles to service.
i.e. the LCD library might block the foreground code but your other interrupt services will continue as normal.
I have never met a human that can read LCD text at I2C speed.
Graphic animations are limited. The display is smeary if you write too fast.
What part of the I²C code uses interrupts? If it is by nature blocking code, then it has no reason whatsoever to use interrupts! The foreground code should be able to use them freely for encoders and such.
Go on. If you want to use Wire.h non-blocking you can extend the class with a "done" flag.
Use a "startTransaction()" and startRequest() that check the "done" flag e.g. with an "isDone()" member.
In practice it seldom matters.
Let's face it. No one complains about analogRead() blocking. Very few people bother to "start" a conversion, get on with life, come back when the conversion has completed. i.e. use the hardware as Nature intended.
Yes, I find it irritating that Wire fills a small buffer before it does anything. Then it waits for the whole buffer to drain. But it all "works ok" for moderate amounts of I2C traffic.
Go spend some time looking at the Wire library code.
In the AVR, most of the i2c state protocol is handle in s/w.
i.e. the h/w really doesn't do that much to off load the data transfer primarily only handles some of the very low level h/w signalling like for arbitration.
Interrupts are used to trigger the s/w to track and move through the various states and load up the registers for the transfers.
Combine that with, IMO, whoever originally did the Arduino Wire library (which sits on top of some low level C code) , didn't appear to understand how the low level C code and h/w worked before they came up with their intended design.
IMO, it looks like they had assumed it worked or could work like the Serial port and that they could use ISRs to run in the back ground to push out the bytes.
Just look at the goofy uneeded double buffering that does on between the Wire.cpp code and the utility/twi.c code.
IMO, it was fairly braindead from the beginning as it wastes quite a bit of statically allocated memory given the way it works, particularly on the transmit side given the multiple output buffers.
The reason the Wire library can hang is because the low level s/w state machine is/was incomplete so there are a few cases where a foreground loop is waiting for an ISR to set to a flag that will never happen under certain situations.
Some of those are when there are multiple masters, a misbehaving slave, or noise on the bus signals.
Well, for the present I will pass on that , but I am pleased that you confirm what I believe should be self-evident that there was never any reason for it to use interrupts and the fact that it does simply indicates gross incompetence, and particularly insofar as it may or does block other use of interrupts.
Like Bill, I guess that they intended to make I2C traffic seamless. i.e. like Serial quietly drains a small buffer as reasonably fast as you fill it.
So you seldom have to wait for space in the buffer.
Either they concluded that users would cause grief or they simply never implemented the plan.
That isn't what I said or meant to say.
The low level twi code is interrupt driven and it has to be since it has to transition between various i2c bus states and there timing requirements that could not be met any other way.
In terms of blocking interrupts, the use of interrupts by the low level twi code doesn't block other interrupts.
What I was trying to say, is that the Arduino Wire library on the AVR started with some C code that implemented I2C and then added a C++ wrapper around that code. (Wire.cpp and Wire.h)
The low level C code supports some amount of deferred / background writes, it is the Wire library wrapper that does not support this.
The Wire library wrapper also added another layer of buffering for both directions, that was not needed as the twi code already support buffering on output prior to starting the actual transmission and had its own rx buffer.
So IMO, it is the Wire library Wire.cpp code wrapper that could and should have been done differently/better.