100+ encoders

Hello, I'm new here and hope to find some help with a problem I've been trying to solve for quite some time now.

I have a project that consists mainly of a huge control interface, roughly 100 encoders and a bunch of buttons.
The buttons are no problem, I don't expect more than 1 to be pressed at a time so a matrix will do, however how could I read 100+ encoders without having to use an insane amount of shift registers (200+ inputs)?
I do expect more than 1 encoder to be turned at a time so just setting them up in a matrix doesn't seem feasible. The arduino might know which encoders I'm turning but when two share a signal line it has no way of knowing which way I'm turning them.
I'm not all too versed when it comes to IO expansion so maybe I'm just missing something really simple, but some help would be much appreciated!

Post a link to the encoder data sheet or product page.

This will never be "really simple".

jremington:
Post a link to the encoder data sheet or product page.

This will never be "really simple".

Well that only means I'm not all that dumb :slight_smile: . It doesn't need to be simple as long as it can be done.
The datasheet is here http://www.mouser.com/ds/2/15/EC12E-587908.pdf
To be precise it's a EC12E24204A8: http://www.alps.com/prod/info/E/HTML/Encoder/Incremental/EC12E/EC12E24204A8.html

That is a standard quadrature encoder and requires two input lines. If any encoder can be turned by any amount, at any time, your options would be about 100+/8 Arduino Unos or some Arduino Megas, or about 100+/8 16 bit port expanders with interrupt on change outputs, connected to one or more Arduinos.

jremington:
or 100/8 16 bit port expanders with interrupt on change outputs, connected to one or more Arduinos.

Thats what I wanted to try and avoid but perhaps there's no way around it. I take it there are no non-SMD ones with more bits per chip?

I don't see how more bits/chip would help.

Any way you look at it, it is a big problem to wire a device that will detect random transitions on 2x100+ independent inputs.

jremington:
I don't see how more bits/chip would help.

Just convenience, plus some less PCB traces for the i2c and supply voltage, it's bound to get pretty stuffed with so many devices on the board as it is.

You need a scanning matrix .

200 buttons implies > SQRT(200) lines - the nearest convenient number is 16.

So you need 2xHC595's to drive one side of this matrix, , and 2xHC165's to read them

Libraries are available.

Allan.

allanhurst:
You need a scanning matrix .

Interesting. I will have to read up on how those work.
Thanks.

Maybe you may use only one encoder and a switch to choose what function it should have?
If you NEED to have so many encoders for some reason I think you need a lot MCUs to read only a few of them and send results to main MCU. For example I would use bunch of ATMega48 (because they are cheap on eBay in DIP package) and let one to read about 5 of encoders and send data to main Arduino/standalone ATMega328.

How many people will operate this panel? How many hands do they have each? This tells you how many transitions the MCU might have to deal with per second.

Hi,
Welcome to the forum.

What is the application that needs 100+ encoders?
What precision do you need?

Would 100+ potentiometers do the same job, I gather you will have people turning them for some reason.
What do you need the Arduino to do with encoder results.
What is its output?

Thanks.. Tom.... :slight_smile:

Let's say you have 128 encoders. Each has 2 outputs. You connect 4 encoders to 1 pcf8574. So you need 32 pcf chips. That gives rise to 2 problems: max 8 pcf chips on an i2c bus; 32 interrupt lines.

For the interrupt lines, you could use another 4 pcf chips to reduce 32 down to 4 interrupt lines. That's probably still too many. One more pcf chip reduces that to 1 interrupt line. That's now 37 pcf chips!

A TCA9548A i2c multiplexer would overcome the problem of the number of pcf chips. You can buy these on breakout boards from AdaFruit or eBay. You could put the 5 pcf chips that deal with the interrupt lines on one bus. Then put the remaining 32 pcf chips on 4 more busses in groups of 8 chips.

So... an interrupt happens. You switch the multiplexer to bus 0. You read the first pcf chip. This tells you which of the other 4 pcf chips received the interrupt. You then read that chip. That tells you which of the remaining 32 chips sent the interrupt. You then set the multiplexer the appropriate bus so that you can then read the pcf chip who's data has changed.

This is 2 writes and 3 reads of the i2c bus to get the data. I2c is not that fast, so I'm not certain this would work. But it's an idea...

At least go for the PCF8575 which has 16 outputs and can handle 400 kHz I2C instead of just 100 kHz. Two advantages over the PCF8574.

Or better even the MCP23017. It has two interrupt lines (one for each group of 8 ports) and can handle much higher I2C speeds.

128 encoders need 16 MCP23017 chips (so you need two I2C buses for that), plus two for the interrupts (bringing it down to four - too many for an Arduino? No problem for the ESP8266) and another 8-port MCP23008 to reduce that to 1 interrupt.

In this case the ESP8266 may come in handy. Only 11 total I/O but you can use any two pins as I2C bus, allowing for total 5x I2C buses (controlling up to 40 MCP23017 chips) and one spare line to handle the incoming interrupts. It also has more speed than Arduino which will be helpful.

No matter what it's not going to be a simple project in any sense of the word.

Good suggestions, wvmarle. But the more I think about this, the more I favour 32 x 74hc165 in a daisy-chain. With SPI at max speed, the Arduino could read this pretty fast. It would be easy and quick for the Arduino to compare the data to the previous read and spot the differences. It's simple & cheap.

SPI should be fast indeed.

But 32 SPI slaves requires a total of 35 pins to control! (MOSI, MISO, CLK and a dedicated SS for each).

No, just 3 pins if you daisy-chain. Then it becomes one slave with 256 bits of data to send. You don't need MOSI for input, and you don't need SS if it's the only slave on the bus. So just MISO, CLK & LATCH.

You would probably need to buffer the clock & latch lines, with such a large fan-out.

EDIT: actually, the '165 doesn't have an output enable pin, so it would have to the the only slave.

PaulRB:
How many people will operate this panel? How many hands do they have each? This tells you how many transitions the MCU might have to deal with per second.

Only one person with hopefully no more than 2 hands.

TomGeorge:
Hi,
Welcome to the forum.

What is the application that needs 100+ encoders?
What precision do you need?

Would 100+ potentiometers do the same job, I gather you will have people turning them for some reason.
What do you need the Arduino to do with encoder results.
What is its output?

Thanks.. Tom.... :slight_smile:

I want to make a programmer for synthesizers that can store several patches. The problem with potentiometers is that if you switch patches they're pointing the wrong way and once you turn them the current stored value may jump by quite a large amount, so I'd like to use encoders to only ever increment or decrement existing values but never set a definite value. Precision isn't that important.
The arduino will output midi cc data.

wvmarle:
128 encoders need 16 MCP23017 chips (so you need two I2C buses for that), plus two for the interrupts (bringing it down to four - too many for an Arduino? No problem for the ESP8266) and another 8-port MCP23008 to reduce that to 1 interrupt.

In this case the ESP8266 may come in handy. Only 11 total I/O but you can use any two pins as I2C bus, allowing for total 5x I2C buses (controlling up to 40 MCP23017 chips) and one spare line to handle the incoming interrupts. It also has more speed than Arduino which will be helpful.

No matter what it's not going to be a simple project in any sense of the word.

I'm happy to learn and I'm in no rush to finish this project. And actually I have a NodeMCU with the ESP8266 lying around. I'll keep this in mind, thanks. Haven't worked with interrupts in combination with i2c yet, but I guess it will just be something as "hey, drop everything you do and read the incoming data right now"?

Smajdalf:
Maybe you may use only one encoder and a switch to choose what function it should have?
If you NEED to have so many encoders for some reason I think you need a lot MCUs to read only a few of them and send results to main MCU. For example I would use bunch of ATMega48 (because they are cheap on eBay in DIP package) and let one to read about 5 of encoders and send data to main Arduino/standalone ATMega328.

I hope this won't be necessary as I only expect 1 or 2 inputs at a time. Using a switch is the very thing I try to avoid, because it implies menu diving that you have on most synthesizers and it can be very annoying.

Mivae:
keep this in mind, thanks. Haven't worked with interrupts in combination with i2c yet, but I guess it will just be something as "hey, drop everything you do and read the incoming data right now"?

That is the normal use of interrupts indeed.

In this case it saves you scanning the complete matrix looking for inputs over and over again (the normal way of trying to read a large number of buttons). That would keep your MCU quite busy, and if you have something else to do there is a fair chance of missing button presses.

So instead you wait for an interrupt to come in telling you something has happened, scan which of the 8 ports has the interrupt, work your way up until you find which group of 8 ports has a button pressed, and then scan those 8 ports to find the activated input. This process shouldn't take more than 1 ms depending on the speed of the I2C bus.

A neat trick to save you a lot of work. Won't work too well if you have many buttons pressed all over the time, or more than one button press at the exact same time.

wvmarle:
Won't work too well if you have many buttons pressed all over the time, or more than one button press at the exact same time.

No this won't be an issue, however I will also have a display the MCU needs to feed. I should probably use a second µc for that purpose or do you think the main one can handle that ontop of scanning such a huge matrix?

wvmarle:
So instead you wait for an interrupt to come in telling you something has happened, scan which of the 8 ports has the interrupt, work your way up until you find which group of 8 ports has a button pressed, and then scan those 8 ports to find the activated input. This process shouldn't take more than 1 ms depending on the speed of the I2C bus.

What frequency can I expect from encoder outputs? It has 24 positions and perhaps I turn it half way round in one go thats 12*2 positions in I guess something like 200 ms, perhaps I'll have this input on two encoders at once so I'll probably want to make sure I do indeed have a rather fast I2C bus that can scan the matrix in 4ms at the very least, what do I need to look for to make sure this happens?

Also come to think of it, this amounts in 4 inputs at a time, can I even scan for 2 interrupts at the same time?