Incremental rotary encoder with 128 PPR? For MIDI CC

I'm looking for a suitable rotary encoder for a MIDI controller. I can't seem to find any incremental models with >=128 pulse per rotation. I've found an absolute model by bournes with 128 pulses but I don't really want to use that many pins on the arduino. Plus at £7 - 8 each they are a little bit pricey. Could anybody please recommend something?
A push button would be nice but not essential.
Thanks

Something like this?
https://www.ebay.co.uk/itm/184156642652

Nah that's way too big. Sorry I should've stated before. I want it to be PCB mounted. Thanks anyway though.

Do you also want 128 detents per revolution? Or could you use one with no detents at all? I don't know what a midi controller requires, but if you can do without detents, then a regular 24-pulse encoder like the PEC12R would give you 96 transitions. A "pulse" in the data sheets usually means a complete cycle of both switches, so there are four transitions per pulse. Then you could consider each transition to be an increment or decrement. I don't know of a 32-pulse regular encoder.

I also should have said that you can use a PEC12R with 24 detents, which gives you precise control when turning the knob at slow speed, but it can cover proportionately more ground when you turn it faster. Or you could even use the push button to shift into and out of high gain mode. I think these options might work better in practice than actually having 128 positions in one revolution, which is only 2.8 degrees per position.

MIDI control change parameters range from 0 - 127 (128) and a standard analogue potentiometer will read this value range in one complete rotation. You would just take the 0 - 1023 from an analogue pin and divide the value by 8. If i were to use a 24PPR rotary encoder would it not result in more than one full turn of the encoder being required to read the full (128) range?

... and it has to added that with a rotary decoder one need to distinguish between incremental and absolute decoders. From the intended application it seems that absolute position of the decoder is needed (otherwise you can add to, e.g., a position of 128 (could be maximum volume), an other 128 - which wouldn't make sense and software then has to take care for. Potentiometer as proposed by @liamobsolete might be the better solution.
Besides, mechanical inkremental decoders are cheaper than optical ones, but bring the problem of bouncing. Reading those decoders is a little tricky - the internet is full with proper treatment.

If you don't have detents, then you would get 96 positions in a full turn of the knob. With detents, it would nominally take 5.3 turns to cover 128 positions if one detent equals one position. But if you were turning the knob fast, it could shift into counting one detent as two positions, or three, or five, or 20, or whatever.

If you use an incremental encoder, the position of the knob would no longer have any direct connection to where you are, and if you want to know the current setting you would have to display it. If that isn't good for what you need to accomplish, then an absolute encoder might work, or it might be best to just use a pot.

128 ticks on one revolution means 360 / 128 = 2,8 degree per tick.
This is a very small angle and would require a big knob or a lot of motoric sensitivity in your hands.

Most of the 12 to 24 ppr rotary-encoders have a button which could be used to switch between a fast-mode (count up/down 4 to 10 digits per pulse and a slow-mode count up/down 1 digit per pulse. Entering could be done by a long-press or a double-press.

There is a rotary-encoder that works with a radial magnet

which is programmable how many pulses should be outputted on one rotation

It is very important to use a radial magnet. Standard magnets have their north and south-pole axial oriented

EDIT: I did a search on ebay
and found this one
https://www.ebay.de/itm/281135090460

best regards Stefan

All the cheap encoders are mechanical switches, you need optical for more resolution and the price jumps a lot. Fact of life. Everyone just uses multiple turns to get more points with mechanical encoders, or the speed trick that ShermanP pointed out (computer mice often use this trick too).

If you need an absolute encoder then the Bournes style or AS5600 type magnetic encoder are the only options I know of.

hm using some kind of acceleration-mode is an interesting idea.
I asked user @gfvalvo this as a feature-request. Though I'm unsure if this could be easily implemented because the time since last pulse of the inrushing pulses must be measured and must be distinguished from bouncing.

best regards Stefan

If you are using interrupts to service an encoder, I've worked out a way to virtually eliminate interrupts generated by bouncing. The result is that for a typical encoder you have just four interrupts per detent - one for each real transition of a switch.

The idea is to enable the interrupt on only one pin at a time. When that interrupt occurs, in the ISR you disable that interrupt and enable the interrupt on the other pin. So any bouncing that occurs on the pin that just generated the interrupt won't generate any more interrupts because interrupts on that pin have been disabled. The other pin should have changed state some time ago, and should be stable.

There's a complication when you change directions because the interrupt is enabled on the wrong pin. But this is solved by increasing the lookup table to 32 bytes, and including the indentity of the interrupting pin as the fifth bit of the index value.

Another nice feature of this method is that you can eliminate false readings caused by bouncing which takes place between the time the interrupt is triggered and the time the port is read. Since you know which pin generated the interrupt, and can keep track of which change it had to make to do that, you know what value it must have had to generate the interrupt, and you can use that value instead of the value read from the port, which may be wrong.

I've written demonstration sketches using both pin change interrrupts and the external interrupts on D2 and D3 (ATmega328P). At each detent they print to the serial monitor the actual number of interrupts which have been serviced since the last detent. For comparison, I wrote the same feature into the standard lookup table method, which leaves interrupts enabled on both pins all the time, and which therefore has to service all the interrupts generated by bounces. So you can compare the results you get for a particular encoder. These sketches and a PDF explaining everything can be found in the Arduino folder (ignore everything else) of my Github on this subject:

https://github.com/gbhug5a/Rotary-Encoder-Servicing-Routines

I seriously doubt I actually invented this method, but after looking a good bit couldn't find it anywhere, so I took a shot at it myself. Anyway, I think this method would work well with the variable speed idea. Also, I'd like to get some feedback on how well it works for others. I get essentially perfect results, with four interrupts per detent, on the two cheap standard encoder modules I got from Banggood, but would be interested in knowing how well it works with other encoders.

Bouncing is not an issue for quadrature encoders since if you respect every transition you will not lose precise lock with the position.

And you have to deal with one count jitter anyway as when parked an encoder can sometimes jitter between two neighbouring states when it happens to be on the edge.

I see there being two basic ways to handle encoders in software - one is interrupt driven (good for fast encoders like shaft encoders).

The other is regular polling (works for slow encoders like rotary input encoder switches). So long as the polling is faster than the max transition rate of the encoder this will not lose lock (ignoring contact bounce). It may hide some of the contact bounce, but it doesn't matter if it doesn't because as I said you always need to handle +/-1 count jitter gracefully anyway.

For rotary input encoders I would suggest adding 1 count hysteresis to the value reported back to the main program - typical rotary encoders go through 4 transitions (complete 360 degrees of quadrature) per detent so this isn't going to lose resolution.

But respecting every transition means dealing with every bounce. The point of my method is to only have four interrupts per detent even if the switch bounces. It doesn't improve accuracy, it just reduces the servicing overhead.

I don't understand what 1 count hysteresis is. Do you have a code example?

it is not a special code-version. The detection of a state-change in channel A / channel B of a rotary encoder in any code-version can miss a single state-change if inversing the rotating direction occurs at a certain position where one of the two switches are in some "inbetween"-state.

best regards Stefan

You don't have to jump through all those hoops if you use the State Table Approach.

Here's one implementation of that approach: https://github.com/gfvalvo/NewEncoder

Well, my method seems to handle a direction change quite well without missing anything. So I don't know what I would change.

Yes, I started with that, and my method uses the same approach. But the buxtronix method still leaves both interrupts enabled, and an interrupt is triggered on each bounce transition. My method avoids the bounce-triggered interrupts, but otherwise works the same. In any case, my method is not much of a hoop to jump through, as my code shows.

True, but its a mechanical switch turned by a human, there is negligible overhead even if it bounces a dozen times per transistion. If that worries you can poll regularly to limit the overhead.

Hysteresis means having a dead-band, for instance of 1 count - so that oscillating a count back and forth is hidden from the user. One way to code that is record the last two distinct count values (which will differ by 1), and only updating when the actual count becomes larger or smaller than both the last two reported positions - this will hide bounce.

I agree that it may not matter if there are lots of interrupts per transition. I just wanted a way to reduce the interrupts in case it does matter in a particular situation. And I would say that polling hardly reduces overhead. If the encoder is idle, the polling still cranks along.

With a standard encoder you would have to accumulate 4 transitions in one direction or the other before reporting an actual detent change. Or for the other type of encoder it would be +2 or -2. So one switch oscillating back and forth shouldn't cause a problem in the first place.

But if you had an encoder without detents, and were counting every transition of either switch as a reportable tick, you'd have to do something to prevent flutter, and your method would do that. The only downside is you would have that dead spot when you change direction, but that's not a major problem.