Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accelerate reading/writing to I/O's #239

Open
elral opened this issue Mar 30, 2023 · 4 comments · May be fixed by #240
Open

Accelerate reading/writing to I/O's #239

elral opened this issue Mar 30, 2023 · 4 comments · May be fixed by #240

Comments

@elral
Copy link
Collaborator

elral commented Mar 30, 2023

In preparation for implemeting encoders on multiplexer the access to I/O's should be increased.

The required time for each device was measured and is listed under Tme consumption. Encoders should be read in every 1ms like implemented in the firmware, but tests showed that this could be increased to 2ms.

According the above mentioned link you can see that with the actual status of the firmware a 4 multiplexer with 16 bit needs 2.4ms to read in all I/O's. To increase the number of available multiplexer e.g. for keymatrixes with more than 4 rows but still to have multiplexer with encoders connected it would be required to fasten up the access to the I/O's.

This could be accomplished by using a direct access to the port registers for "critical" devices instead of using the digitalRead()/digitalWrite() function of the Arduino library.

The drawback would be an increased RAM consumption, mainly from the deviceBuffer. Therefore a precondition is to free up RAM by merging PR #219 .

The FastIO will not fit into the flash for the ProMicro (Memory consumption w/o further flash reduction (not checked if possible). On the other hand there it is very likely that not enough flash is available for the required changes to connect encoders to multiplexers.

The Uno/Nano is very limited in RAM, even with eliminating the nameBuffer max. 16(14) encoders could be defined. 6 encoders can be connected directly to the I/O's (18 pins - 5 pins from MUX device) and the remaining 10(8) can be connected to a multiplexer. So I see no reason to increase the max. number of multiplexer (currently 3). That means the FastIO is not really required but could be beneficial.
*) numbers in brackets are for FastIO

The Mega has enough flash and memory, so the max. number of multiplexer could be increased with implementing the FastIO (required to read in encoders on multiplexers).

The Pico is already much faster and has much more flash and RAM. With the FastIO for the AVR architecure they come nearly to the same access time as the Pico.

@elral elral linked a pull request Mar 30, 2023 that will close this issue
@GioCC
Copy link
Contributor

GioCC commented Mar 31, 2023

Only about increasing the max number of multiplexers on the uno/nano (the rest of the comments are under the PR):
that's where the increase probably makes more sense. You seem to imply that a user always wants to define many encoders, but that's probably not the case; if mostly ordinary inputs are desired (think e.g. of a switch panel or overhead), adding some more multiplexers could allow a more efficient use of smaller boards instead of using a Mega just because of the imposed lack of support.

@elral
Copy link
Collaborator Author

elral commented Mar 31, 2023

Yes, that's true, it's focussed on encoders. But still shows where the limitation is.

After some more testing I can confirm again, that reading of encoder inputs every 2ms OK, going to 3 or 4ms becomes to be on the edge.
But to make it clear, this does not mean that the max. numbers of multiplexer (or other output devices) can not be increased even without the "FastIO" access, unless encoders are connected. For now these input devices are read in every 10ms, and a longer read in time for e.g. 8 multiplexer (~4,8ms) does not affect the encoders. But if encoders would be connected to multiplexer, we had to read them every 2ms. As the time to read them in is ~4.8ms they get read in every loop(). This results in a not always propper identification of the direction of the encoders.

So having an own device type for "encoders on multiplexer" might be a good way as Sebastian has alreday proposed before.

For a lot of inputs we have also the input shifter. For 128 inputs they need the same number of pins on the Arduino, less memory from the device buffer and they are faster. Up to 96 inputs the even need less number of pins on the Arduino.

@GioCC
Copy link
Contributor

GioCC commented Mar 31, 2023

As I already mentioned, encoders can already be attached to multiplexers, not using the multiplexer values read during the normal polling loop, but reading their own inputs directly without interference with other multiplexer operations (i.e. regular inputs), and totally with their own independent timing.
Using a dedicated multiplexer for encoders has no technical reason whatsoever for timing, it is just a personal preference because it is arguably more comprehensible for a novice user from a configuration or wiring standpoint.
And while it is true that there are other ways to expand "regular" inputs, it's not necessarily a good thing to limit the user's choice (which often is not arbitrary, e.g. existing installations).
I could also argue that multiplexers can also be slightly faster than shift register chains, besides being much more flexible in not creating processing latency. However, this would require some (quite feasible) changes in how the polling loop is currently managed, so I'm not interested in making a point of it; maybe a matter for a future modification.

@GioCC
Copy link
Contributor

GioCC commented Mar 31, 2023

In preparation for implemeting encoders on multiplexer the access to I/O's should be increased.

This should not really be necessary.

But if encoders would be connected to multiplexer, we had to read them every 2ms. As the time to read them in is ~4.8ms they get read in every loop().

If I understand correctly what you mean, this issue would not arise.
As I already mentioned, encoders can already be attached to multiplexers, not using the multiplexer values read during the normal polling loop, but reading their own inputs directly without interference with other multiplexer operations (i.e. regular inputs), and totally with their own timing.

Using a dedicated multiplexer for encoders has no technical reason whatsoever for timing, it is just a personal preference because it is arguably more comprehensible for a novice user from a configuration or wiring standpoint.
And while it is true that there are other ways to expand "regular" inputs, it's not necessarily a good thing to limit the user's choice (which often is not arbitrary, e.g. existing installations).

It might even be argued that multiplexers can be slightly faster that shift register chains, besides being more flexible in avoiding processing latency (and not requiring as many resistors to be additionally wired); but this would require some changes to the current input polling management, so I'm not interested of making a point of it in the scope of this discussion (maybe a topic for a different modification).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants