EEVblog® Electronics Community Forum
Electronics => Projects, Designs, and Technical Stuff => Topic started by: npelov on September 04, 2016, 07:24:06 am
-
Long time ago the PC mice were made with optical rotary encoders and they were cheap. Even the cheapest ones worked well (at least the rotary encoder part). Now everyone switched to mechanical rotary encoders. They are nasty to debounce - if you do it too much, you loose speed. If you don't - you loose/gain additional pulses. There are probably good onces which are expensive, but they'll still wear out and I heard of very expensive ones that failed.
I need a cheep rotary encoder like this one (http://www.ebay.com/itm/Rotary-encoder-with-switch-EC11-Audio-digital-potentiometer-20mm-handle-/191736125674?hash=item2ca45d18ea:g:cVQAAOSwys5WUrdQ), but optical. Well it doesn't have to be $1-2. $5 is still a good price for optical one (that's the price of a cheap mouse). It doesn't have to be high precision like the ones used in industrial CNC machines. I need it for knob, not for location.
-
I looked into this about three or so years ago, and didn't have any luck, at least not for a volume product.
In the end, as well as trying some expensive (tens of dollars) units, I sourced some via aliexpress or similar for about $3 a pop. When they arrived they turned out to be ex-equipment: they worked, but were spec'd at 5v, that may not be a problem for you, but my device was battery powered and didn't have a 5v power domain, although they did work at 3.3v, just. They are also reasonably bulky.
I am fairly sure that almost all consumer grade rotary encoders use mechanical contacts.
One further thing I was looking for was heavy, reasonably large sized knobs that look like they're not form the 50s. Like cheap optical rotary encoders, nice looking large shiny knobs are hard to find (ooh er missus*).
* Widely used response to a double entendre in the UK.
-
I have just recently tested some cheap mechanical encoders and optical ones (CNC type with 100 steps). Short conclusion - just use anything optical if you can, cheap mechanical ones are horrible.
Mechanical encoders bounced like there is no tomorrow - whatever low pass filter (analog or digital) you implement, you are guaranteed to miss some pulses (especially at higher momentary turn speed). Turn knob faster and you don't even know whether waveforms could possibly come from an encoder. It is barely good enough for simple UI.
On the other hand, optical encoder provided very clean waveforms with no glitches and bounces - very easy to decode at any speed. I would strongly recommend using these if you fear about missing pulses or going in reverse direction (when knob is turned faster).
I used no name optical encoders (named "CNC 100 pulse encoder", ~50mm diameter), these go for $10-15 and use ~80mA at 5V DC. I can't suggest something cheaper and smaller, you have to look around. By the way, I can sell one these for lower price if you are interested in a knob only.
-
http://www.ebay.com/itm/Rotary-Encoder-400P-R-6mm-Incremental-Optical-Shaft-Working-Measurement-5-24V-/171640123948?hash=item27f68c722c:g:90sAAOSwHmhV8Te8 (http://www.ebay.com/itm/Rotary-Encoder-400P-R-6mm-Incremental-Optical-Shaft-Working-Measurement-5-24V-/171640123948?hash=item27f68c722c:g:90sAAOSwHmhV8Te8)
-
http://www.ebay.com/itm/Rotary-Encoder-400P-R-6mm-Incremental-Optical-Shaft-Working-Measurement-5-24V-/171640123948?hash=item27f68c722c:g:90sAAOSwHmhV8Te8 (http://www.ebay.com/itm/Rotary-Encoder-400P-R-6mm-Incremental-Optical-Shaft-Working-Measurement-5-24V-/171640123948?hash=item27f68c722c:g:90sAAOSwHmhV8Te8)
That looks exactly like the ones I boughht a few years ago. The ones I had had varyng cable lengths, leading me to believe they are either ex-equipment or new old stock configured for a particular job.
-
Mechanical encoders bounced like there is no tomorrow - whatever low pass filter (analog or digital) you implement, you are guaranteed to miss some pulses (especially at higher momentary turn speed). Turn knob faster and you don't even know whether waveforms could possibly come from an encoder. It is barely good enough for simple UI.
Low pass filter is not very useful for this purpose. You used a wrong tool to solve the problem.
-
Low pass filter is not very useful for this purpose. You used a wrong tool to solve the problem.
Care to elaborate? I thought all improvements to mechanical encoder performance had came from low pass filter in analog or digital domain.
My problem with mechanical encoders that bounce is that they can skip pulses or go in reverse - and there is little you can do about it (at least without very high sample rate or specialised IC). This issue is especially anoying when quick turn (meaning that you do not take care to turn it slowly and consistently) of knob creates strange results in UI.
Optical encoders at least guarantee (up to a point, of course) that it will not skip pulses or go in reverse.
-
Use a sin/cos hall sensor like MLX90316 (http://www.digikey.com/product-detail/en/melexis-technologies-nv/MLX90316KDC-BDG-100-RE/MLX90316KDC-BDG-100-RECT-ND/1766530), and mount a magnet to the end of your knob shaft. You should be able to get resolution equivalent to a many hundred line encoder, and there are no contacts, rubbing parts, or optical paths to get blocked up with dirt.
-
Use a sin/cos hall sensor like MLX90316 (http://www.digikey.com/product-detail/en/melexis-technologies-nv/MLX90316KDC-BDG-100-RE/MLX90316KDC-BDG-100-RECT-ND/1766530), and mount a magnet to the end of your knob shaft. You should be able to get resolution equivalent to a many hundred line encoder, and there are no contacts, rubbing parts, or optical paths to get blocked up with dirt.
A bit pricey, but at least there are some (from ams) that operate at a convenient voltage instead of 5V. Power consumption is high while actually reading, but it looks like you can get < 100 uA for a reasonable cadence of ~ 10 Hz. And you get absolute position for free.
Where do you find knob/shaft combos with bearings and a suitable "feel" to mount the magnet onto?
-
Low pass filter is not very useful for this purpose. You used a wrong tool to solve the problem.
Care to elaborate? I thought all improvements to mechanical encoder performance had came from low pass filter in analog or digital domain.
This debounce algoritm works great for any bouncing contacts http://auto.teipir.gr/sites/default/files/debounce_kuhn2005_1.pdf (http://auto.teipir.gr/sites/default/files/debounce_kuhn2005_1.pdf)
But the most important for encoder, proper state machine which accepts only valid state changes should be used.
http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html (http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html)
-
https://www.amazon.com/gp/product/B00Y9KDDCY (https://www.amazon.com/gp/product/B00Y9KDDCY)
a project I used that in (it works great):
(https://c1.staticflickr.com/9/8647/28709043975_7a2efb101d_b.jpg)
-
Low pass filter is not very useful for this purpose. You used a wrong tool to solve the problem.
Care to elaborate? I thought all improvements to mechanical encoder performance had came from low pass filter in analog or digital domain.
This debounce algoritm works great for any bouncing contacts http://auto.teipir.gr/sites/default/files/debounce_kuhn2005_1.pdf (http://auto.teipir.gr/sites/default/files/debounce_kuhn2005_1.pdf)
But the most important for encoder, proper state machine which accepts only valid state changes should be used.
http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html (http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html)
Thanks, I will look into this a bit more more and compare with my current algorithm implementation.
Still, I do not expect to completely eliminate missed steps or wrong direction with mechanical encoder.
-
What's your price limit on a single encoder? There are bunch of cheap-ish chinese industrial encoders available for a reasonable price, as shown in previous posts, although nowhere near as cheap as mechanical, and they are rather bulky.
-
Well, I forgot to get back to this thread. I've read everything and I found out optical encoders for UI control are no longer a thing. Industrial incremental encoders have too much steps - like 400 per rotation. Also I don't know if they have well defined stops to avoid a stop between the steps (which can cause backward jumps). What I need is 24 step encoder.
The hall effect sensor seems like a nice idea to play with. There could be a problem if you need more than one knob close together. Also mounting can be a problem. the magnet has to be in the center of the axis for best results. An existing mechanical encoder can be used for the stops. May be if 2 magnets are mounted at 180 deg. from each other, one N facing down, one S facing down and the sensor is in the middle behind the mechanical encoder (maybe on the back of the PCB).
Here is a cheaper chip that could (probably) used for the same purpose:
http://www.digikey.com/product-detail/en/infineon-technologies/TLV493DA1B6HTSA2/TLV493DA1B6HTSA2TR-ND/5887140 (http://www.digikey.com/product-detail/en/infineon-technologies/TLV493DA1B6HTSA2/TLV493DA1B6HTSA2TR-ND/5887140)
-
Well, I forgot to get back to this thread. I've read everything and I found out optical encoders for UI control are no longer a thing. Industrial incremental encoders have too much steps - like 400 per rotation. Also I don't know if they have well defined stops to avoid a stop between the steps (which can cause backward jumps). What I need is 24 step encoder.
The hall effect sensor seems like a nice idea to play with. There could be a problem if you need more than one knob close together. Also mounting can be a problem. the magnet has to be in the center of the axis for best results. An existing mechanical encoder can be used for the stops. May be if 2 magnets are mounted at 180 deg. from each other, one N facing down, one S facing down and the sensor is in the middle behind the mechanical encoder (maybe on the back of the PCB).
Here is a cheaper chip that could (probably) used for the same purpose:
http://www.digikey.com/product-detail/en/infineon-technologies/TLV493DA1B6HTSA2/TLV493DA1B6HTSA2TR-ND/5887140 (http://www.digikey.com/product-detail/en/infineon-technologies/TLV493DA1B6HTSA2/TLV493DA1B6HTSA2TR-ND/5887140)
One thing you might check into is using small (cheap) stepper motor as an magnetic encoder. It does require a little analog signal processing but has been done. Don't have a link handy but perhaps google can find something on this.
-
Thanks, I will look into this a bit more more and compare with my current algorithm implementation.
Still, I do not expect to completely eliminate missed steps or wrong direction with mechanical encoder.
I recently wrote a state machine for reading a mechanical encoder. I wrote it so that it only registers a valid step when the knob reaches the second detent. If any of the pin states is skipped during a cycle, the step is ignored and it waits for the knob to reach a detent before continuing. The polling of the pins is done at 1kHz, which seems to work very well.
It does occasionally skip steps if you flick the knob real quick, but it never registers steps in the wrong direction.
-
Well, I forgot to get back to this thread. I've read everything and I found out optical encoders for UI control are no longer a thing. Industrial incremental encoders have too much steps - like 400 per rotation. Also I don't know if they have well defined stops to avoid a stop between the steps (which can cause backward jumps). What I need is 24 step encoder.
The hall effect sensor seems like a nice idea to play with. There could be a problem if you need more than one knob close together. Also mounting can be a problem. the magnet has to be in the center of the axis for best results. An existing mechanical encoder can be used for the stops. May be if 2 magnets are mounted at 180 deg. from each other, one N facing down, one S facing down and the sensor is in the middle behind the mechanical encoder (maybe on the back of the PCB).
Here is a cheaper chip that could (probably) used for the same purpose:
http://www.digikey.com/product-detail/en/infineon-technologies/TLV493DA1B6HTSA2/TLV493DA1B6HTSA2TR-ND/5887140 (http://www.digikey.com/product-detail/en/infineon-technologies/TLV493DA1B6HTSA2/TLV493DA1B6HTSA2TR-ND/5887140)
Alps have their smaller/lower cost magnetic encoder EM11B16140A4, you should see reasonable pricing in volume when ordering directly.
-
Based on a brilliant little article from http://www.mkesc.co.uk/ise.pdf (http://www.mkesc.co.uk/ise.pdf) , call the _check function from a pin interrupt or on a regular basis;
const int32_t _moveTable[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
volatile struct
{
uint32_t ab;
int32_t psn;
} _p;
void _check(void)
{
_p.ab = (_p.ab << 2)
| (Chip_GPIO_GetPinState(LPC_GPIO_PORT, GETGPIOPORT(ROT_A), GETGPIOPIN(ROT_A)) << 1 )
| (Chip_GPIO_GetPinState(LPC_GPIO_PORT, GETGPIOPORT(ROT_B), GETGPIOPIN(ROT_B)));
_p.psn += _moveTable[(_p.ab & 0xf)];
}
-
Based on a brilliant little article from http://www.mkesc.co.uk/ise.pdf (http://www.mkesc.co.uk/ise.pdf) , call the _check function from a pin interrupt or on a regular basis;
No, don't. Interrupts garantee that you'll pick up every last bit of switch noise and create lots of potential software bugs/race conditions.
or on a regular basis;
Much better idea. A 1ms polling function usually works perfectly.
-
Alps have their smaller/lower cost magnetic encoder EM11B16140A4, you should see reasonable pricing in volume when ordering directly.
16.60 EUR is a bit on the high side (farnell). Ordering directly from the manufacturer might save from the product price, but what about shipping? I buy from farnell using local distributor and I think they add 5% or 10%. If I want to buy 2 to 3 encoders it'll still be cheaper to order locally through farnell.
-
Guys, making a better filter (analog or digital) or any other approach of improving the readings of an mechanical encoder is a battle that you'll eventually loose. These things age and oxidise and do all kinds of horrible stuff. mechanical switches are not supposed to work at these frequencies. When I turn a pot I'm not careful how fast I turn it. A low pass filter won't hurt the performance of a pot noticeably. So I do use a pot when possible, but when you have too many values to change and too little space on the box you have no choice. So unless you use insanely expensive encoder with thick gold plating mechanical is not the way to go. They put more gold in a $5 multimeter range switch than in a $2 rotary encoder.
I remember beating the crap out of cheap old mouses and they still go. Sometimes the photodiodes get misaligned and I have to push them back in alignment. One would thing that technology will improve and they will make these encoders smaller - in form factor of today's mechanical encoders or maybe a bit bigger, but not.
Well I ordered a few sin-cos magnetic sensors and I'll see what I can achieve with them.
-
If you need a lot of them, try US Digital, but again, you need to order many, many, many parts to get the price down.
http://www.usdigital.com/ (http://www.usdigital.com/)
Steve
-
The low cost one:
http://www.usdigital.com/products/encoders/incremental/rotary/kit/E4T (http://www.usdigital.com/products/encoders/incremental/rotary/kit/E4T)
Steve
-
No, don't. Interrupts garantee that you'll pick up every last bit of switch noise and create lots of potential software bugs/race conditions.
Much better idea. A 1ms polling function usually works perfectly.
Yup. As it happens I do use this function under interrupt but with an optical quad encoder and never have problems. If you're intending using it with a mechanical encoder then deffo take precautions, although the state machine implied by the bitshift will protect you to a limited degree.
...not sure I agree about your bugs/races though, all depends how you use the output..the above is obviously very pared down, and polling is the devils spawn when you're trying to save power.
DAVE
-
Why not use the encoder from a mouse, like you already said? The scroll wheel in a modern mouse is still an optical quadrature encoder.
-
Why not use the encoder from a mouse, like you already said? The scroll wheel in a modern mouse is still an optical quadrature encoder.
That's a nice idea. But I have two problems:
1. the axis encoders don't have stops.
2. I can't think of a way to mount them in a box.
3. I can't mount a knob on the shaft.
Maybe when I have time I'll try it. Maybe I can break a cheap mechanical, make a whole in the bottom and try to connect the shaft to the mouse in some way.
-
polling is the devils spawn when you're trying to save power.
You can use an interrupt to wake up. There's no problem there. Go back to sleep after 10 seconds of idle.
Or set up a 1ms interrupt to wake up the chip for the polling and sleep the rest of the time.
As it happens I do use this function under interrupt but with an optical quad encoder and never have problems.
What's the power consumption of an optical encoder? :popcorn:
-
Damn, those optical encoders are expensive: http://www.ebay.com/itm/142146056203 (http://www.ebay.com/itm/142146056203)
It's just two LEDs and a disk with holes in it. What gives?
-
Even its "relatively" cheap, I guess this beats common mechanical encoder's life -> https://goo.gl/dEekXT
Simple, metal shaft and even using the lowest quality ball bearings, still metal beats plastic. :P
-
Well, I forgot to get back to this thread. I've read everything and I found out optical encoders for UI control are no longer a thing. Industrial incremental encoders have too much steps - like 400 per rotation. Also I don't know if they have well defined stops to avoid a stop between the steps (which can cause backward jumps). What I need is 24 step encoder.
The hall effect sensor seems like a nice idea to play with. There could be a problem if you need more than one knob close together. Also mounting can be a problem. the magnet has to be in the center of the axis for best results. An existing mechanical encoder can be used for the stops. May be if 2 magnets are mounted at 180 deg. from each other, one N facing down, one S facing down and the sensor is in the middle behind the mechanical encoder (maybe on the back of the PCB).
Here is a cheaper chip that could (probably) used for the same purpose:
http://www.digikey.com/product-detail/en/infineon-technologies/TLV493DA1B6HTSA2/TLV493DA1B6HTSA2TR-ND/5887140 (http://www.digikey.com/product-detail/en/infineon-technologies/TLV493DA1B6HTSA2/TLV493DA1B6HTSA2TR-ND/5887140)
One thing you might check into is using small (cheap) stepper motor as an magnetic encoder. It does require a little analog signal processing but has been done. Don't have a link handy but perhaps google can find something on this.
i second this. a 20mm 18degree biphase stepper is very robust and provides natural detent positions due to cogging. comparators/amplifiers aside, the primary disadvantage here would probably be insufficient voltage swing at very slow turning speeds or missed individual clicks. Then again, there are miniature motors with high coil resistance (>100 ohms,i.e more turns), which may work better. I have tons of these at work and i'm going to give it a try next week.
-
Mechanical encoders bounced like there is no tomorrow - whatever low pass filter (analog or digital) you implement, you are guaranteed to miss some pulses (especially at higher momentary turn speed). Turn knob faster and you don't even know whether waveforms could possibly come from an encoder. It is barely good enough for simple UI.
Low pass filter is not very useful for this purpose. You used a wrong tool to solve the problem.
Forget filtering to remove bounce; decode the quadrature output by using the mechanical encoder outputs to clock latches. Now each edge can only cause one state change in one direction. This really should be done with optical encoders as well; while they do not have bounce exactly, they can still produce the same problem.
-
Damn, those optical encoders are expensive: http://www.ebay.com/itm/142146056203 (http://www.ebay.com/itm/142146056203)
It's just two LEDs and a disk with holes in it. What gives?
Exactly! If they were able to make $5 mouse, then why can't they make $5 encoder alone? One would think that with the technology improvements it should be even cheaper. Today you can buy a computer for $5 - brand new (https://www.raspberrypi.org/blog/raspberry-pi-zero/).
Btw using a mouse is a limited resource. I only have 2 or 3 old mice. The new ones use mechanical encoders for the scroll and "camera" type sensor for the motion. There are no optical encoders in mice anymore.
-
Damn, those optical encoders are expensive: http://www.ebay.com/itm/142146056203 (http://www.ebay.com/itm/142146056203)
It's just two LEDs and a disk with holes in it. What gives?
Exactly! If they were able to make $5 mouse, then why can't they make $5 encoder alone? One would think that with the technology improvements it should be even cheaper. Today you can buy a computer for $5 - brand new (https://www.raspberrypi.org/blog/raspberry-pi-zero/).
I think it comes down to economics, application, and that signal conditioning for mechanical encoders is a solved problem. To be competitive, an optical or magnetic encoder would need to be cheaper than a mechanical encoder because they are good enough in the application where only 10s of detents are needed or even desired.
With proper decoding, the switch bounce from a mechanical encoder is not a problem; use each edge to clock a flip-flop which captures the other input.
They used to sell dual potentiometers where the elements were 180 degrees out of phase allowing two analog measurements to return absolute position. They work well enough but I think mechanical encoders replaced them.
Btw using a mouse is a limited resource. I only have 2 or 3 old mice. The new ones use mechanical encoders for the scroll and "camera" type sensor for the motion. There are no optical encoders in mice anymore.
The scroll wheels on all of my current mice use optical encoders.
-
With proper decoding, the switch bounce from a mechanical encoder is not a problem; use each edge to clock a flip-flop which captures the other input.
I use an edge interrupt on the one input and I read the other input in the ISR. But I also watch the two pins on the scope and I can see the noise. It's completely random, it's the whole length of the impulse and it gets worse as you turn the encoder faster. If I filter it with a big enough capacitor and/or a time delay in the MCU then I start skipping pulses. Well, I haven't tried a good quality one yet, but most of the good mechanical ones are as expensive as optical. But good mechanical have a lot more gold in them than good optical ones. And if you think a bit a led and two photo transistors plus an opamp is cheaper than a thick gold (or gold-nickel, or whatever they use) plating.
I just received few KMZ60 (http://www.nxp.com/documents/data_sheet/KMZ60.pdf). Even if I don't find an easy way to use them as encoders they might be useful for other angle measuring applications. When I have the time I'll test them and I'll share results. I got them for $1.39 each (price for 3+) from tme.eu (http://www.tme.eu/en/katalog/#idp=1&search=KMZ60&cleanParameters=1)
-
I use a combination of the hardware pull ups and filtering recommended in the spec sheet for PEC11 mechanical encoders and software processing described in the attached document.
The hardware low pass filter eliminates most of the mechanical noise and the software algorithm does not require a lookup table. I have been able to get reasonable results from cheap rotary encoders.
-
I recently played a bit more with the encoders. Schmitt triggers made a big difference. However there is one problem remaining and it's not related to contacts - mechanical or optical. The dents must be distinct and it shouldn't be possible to stay for long time in the middle of two dents. That was the main problem with a well filtered encoder when rotating it slowly. And the problem is that you need the most accuracy when you rotate it slowly, because you rotate it faster to get near the value you want and then rotate it slowly to dial the exact value. That's when the big problems begin (including jump in the opposite direction).
-
It is not clear if you are developing a product, or something that is a one off for yourself. The willingness to salvage mouse parts indicates the latter. Another source of optical encoders (at least once upon a time, I haven't checked recently) is in dot matrix printers. Your local second hand store will have them for near free prices, and the encoders and resolution were amazing.
-
Ok, if you want to use the cheapest mechanical encoder, and a 0.50$ 8 pin pic as with a denounce software, I will help code it for you. I used mechanical encoders on my video scaler's front panel which has a PIC as a generic controller for all the buttons/lcd display & panel led controller controlled through the pic to the main system processor via rs232. I'll snippet out my rotary encoder decoder algorithm.
-
It is not clear if you are developing a product, or something that is a one off for yourself.
It's for me. It's not possible to have good, long lasting encoder on a product - it's too expensive. Well maybe if it's only one and the product itself is expensive. I haven't seen a product below $1000 with a good rotary encoder that never glitches.
I just realized that if I stop in the middle between dents of a mechanical encoder there is big chance to get false steps in either direction, which is what we expect. But then I went to my scope and I rotated the horizontal and and vertical position knobs and realized that they don't have dents (at least not easy to sense them). And they have a lot of pulses per revolution. How does it happen that they don't stop in the middle between two pulses? I know that once they detect direction they only allow this direction until there are no pulses for about 1/4 second - that's how they stop wrong direction pulses. You can't switch directions immediately. As for the forward jumps - even my brand new DS2072A scope has them. They are rare but they happen.
-
How does it happen that they don't stop in the middle between two pulses? I know that once they detect direction they only allow this direction until there are no pulses for about 1/4 second - that's how they stop wrong direction pulses. You can't switch directions immediately. As for the forward jumps - even my brand new DS2072A scope has them. They are rare but they happen.
Study how quadrature decoding works; if properly decoded, it has +/- 1/2 pulse of hysteresis.
-
Ok, here is the technique I use for both debouncing the mechanical rotary encoder inputs combined with all my other button inputs simultaneously:
With this code, a 1000pf, or 10000pf cap on the rotary inputs should be sufficient to get rid of the high frequency noise due to rubbing metallic brush contacts. The the perfectly time digital filter using a sample clock which removes all the low frequency bounces for when a switch is opened or closed.
This portion of code should be called 200 times per second. Adjusting this sampling speed will change how fast the rotary input will function before it skips. In my PIC projects, I usually triggers from the interrupt of a CPU timer set to this speed, I never interrupt or trigger on change of IO pin as this would drive my code nuts interrupting all the time when it's just noise on the input:
---------------------
switches_temp3 = switches_temp2;
switches_temp2 = switches_temp1;
switches_temp1 = IO_port; // The IO port contains all my input pins
switches_debounced_old = switches_debounced;
if (switches_temp1==switches_temp2 && switches_temp2==switches_temp3) switches_debounced = switches_temp1;
volume_temp3 = volume_temp2;
volume_temp2 = volume_temp1;
******(comparing here switches_debounced with switches_debounced_old, you should increment or decrement volume_temp1)*****
if (volume_temp1==volume_temp2 && volume_temp2==volume_temp3) volume = volume_temp1;
---------------------
Now the secondary volume debouncing using the volume_temp123 is optional, but if you really want to get rid of all bouncing possible due to that snap position edge in the cheap mechanical encoders, I would use it.
At this point, all the switches_debounced bits IO pins should contain debounced inputs, including the IO pins with your encoder bits.
If you did you quadrature correctly, which is nothing more than comparing the A&B input bits of switches_debounced & switches_debounced_old, placing those 4 bits in a look-up table with 16 possible results to either add 1, subtract 1, of do nothing, you will have a volume control which wont skip, miss a beat, turnable up to around 50 steps per second, unless you adjust the sample speed and your problem should be solved.
-
Ok, here is the technique I use for both debouncing the mechanical rotary encoder inputs combined with all my other button inputs simultaneously:
With this code, a 1000pf, or 10000pf cap on the rotary inputs should be sufficient to get rid of the high frequency noise due to rubbing metallic brush contacts. The the perfectly time digital filter using a sample clock which removes all the low frequency bounces for when a switch is opened or closed.
This portion of code should be called 200 times per second. Adjusting this sampling speed will change how fast the rotary input will function before it skips. In my PIC projects, I usually triggers from the interrupt of a CPU timer set to this speed, I never interrupt or trigger on change of IO pin as this would drive my code nuts interrupting all the time when it's just noise on the input:
---------------------
switches_temp3 = switches_temp2;
switches_temp2 = switches_temp1;
switches_temp1 = IO_port; // The IO port contains all my input pins
switches_debounced_old = switches_debounced;
if (switches_temp1==switches_temp2 && switches_temp2==switches_temp3) switches_debounced = switches_temp1;
volume_temp3 = volume_temp2;
volume_temp2 = volume_temp1;
******(comparing here switches_debounced with switches_debounced_old, you should increment or decrement volume_temp1)*****
if (volume_temp1==volume_temp2 && volume_temp2==volume_temp3) volume = volume_temp1;
---------------------
Now the secondary volume debouncing using the volume_temp123 is optional, but if you really want to get rid of all bouncing possible due to that snap position edge in the cheap mechanical encoders, I would use it.
There is a code that doesn't require debouncing:
http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html (http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html)
-
There is a code that doesn't require debouncing:
http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html (http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html)
npelov claims he is getting noise from a mechanical encoder brush contacts even the one which should be solid on in the middle of it's fat 'on' state due to it being a piece of junk. But you are right, my code is overkill, but since it handles all the buttons on the front control panel of my video switcher, I thought I would share what I did. Your are right that without the debounce, it still wouldn't mess up.
This is all you need is to call this at regular intervals, no interrupt on IO pin change:
This code was intentionally over simplified to show what's going on......
----------------------
void decode_inputs() {
prev_cha = cha;
prev_chb = chb;
cha = 0;
chb = 0;
if ( PORTB & 16 ) cha = 1;
if ( PORTB & 32 ) chb = 1;
if ( ( prev_cha==0 & cha==1 & prev_chb==0 & chb==0 ) ||
( prev_cha==1 & cha==0 & prev_chb==1 & chb==1 ) ||
( prev_cha==1 & cha==1 & prev_chb==0 & chb==1 ) ||
( prev_cha==0 & cha==0 & prev_chb==1 & chb==0 ) ) location = location + 1;
if ( ( prev_cha==0 & cha==1 & prev_chb==1 & chb==1 ) ||
( prev_cha==1 & cha==0 & prev_chb==0 & chb==0 ) ||
( prev_cha==0 & cha==0 & prev_chb==0 & chb==1 ) ||
( prev_cha==1 & cha==1 & prev_chb==1 & chb==0 ) ) location = location - 1;
}
-------
That's it.... I call this routine 3000 times a second in the app I use it in. This shouldn't mess up, I'm using it to workout the RPM of a directional motor with an encoder going up to 1000 pulses per sec the hardware works error free. For a volume control, calling this only 50 times a second should suffice.