Messy rotary encoder?? - Page 1
Forum section: electronics / general

author: kgavionics
author_rank: Regular Contributor
timestamp: July 05, 2021, 06:28:56 pm
content: Hello guysI bought 2 cjmcu-111rotary encoders from ebay, and I have very messy signal when I turn it clockwise, the counterclockwise direction is good! I only use an RC filter on each pin, because I don't have a Schmidt trigger inverter handy to make a solid debounce circuit!The RE encoder is hoked up to an Ategma328P to increment a counter or decrement it depending on the RE direction! When I turn it counterclockwise it decrements it with no problem, but when it's turned clockwise it sometimes decrements or increment!I have attached 2 screenshots showing the problem! And the RE schematic as well!The first one is the clockwise direction and the second one is the counterclockwise direction!Anybody knows how can I fix the problem, please?

author: Benta
author_rank: Super Contributor
timestamp: July 05, 2021, 07:56:04 pm
content: Signal looks good to me.The negative-going edges are aligned as they should be. I don't understand the problem.

author: PCB.Wiz
author_rank: Super Contributor
timestamp: July 05, 2021, 08:13:07 pm
content: Quote from: kgavionics on July 05, 2021, 06:28:56 pmThose captures both look quadrature valid, but the failing direction is less angle balanced than the always working direction. Thatshouldbe tolerated by the MCU.Did you get a capture when it failed ?Does it work ok CW up to a certain speed ? Does the MCU include debounce in the code ?

author: kgavionics
author_rank: Regular Contributor
timestamp: July 05, 2021, 08:47:46 pm
content: I don't have any debouncing techniques in my code, (I'm not a programmer, I'm an avionics technician who loves embedded systems! (see the code below)!The code consists of an interrupt (INT0) triggered by signal A (rising edge) and once inside the interrupt, it checks for the B signal status, if B is 0, then it's rotating clockwise, else it's counterclockwise! And accordingly, turn on the leds!Code:#include <avr/io.h>#include <util/delay.h>#include <stdlib.h>#include <avr/interrupt.h>unsigned char encoder;int main(void){DDRC |= (1<<PC4) | (1<<PC5);DDRD &=~ (1 << PD2); /* PD2 and PD3 as input */DDRD &=~ (1 << PD3);PORTD |= (1 << PD2)|(1 << PD3); /* PD2 and PD3 pull-up enabled */EIMSK |= (1<<INT0) ; /* enable INT0 and INT1 */EICRA |=(1<<ISC01) | (1<<ISC00);//INT0 RISING EDGEsei();while(1){_delay_ms(1);}return 0;}ISR(INT0_vect ){if(bit_is_clear(PIND, PD3)){encoder++;PORTC |=(1<<PC4);PORTC &=~(1<<PC5);}else{encoder--;PORTC |=(1<<PC5);PORTC &=~(1<<PC4);}}I attached a video showing the problem in the clockwise direction!

author: Bassman59
author_rank: Super Contributor
timestamp: July 05, 2021, 08:51:49 pm
content: Quote from: kgavionics on July 05, 2021, 08:47:46 pmThere's the problem ... you need to actually do the debouncing in hardware if you want reliable interrupt triggering and not have the interrupt continually triggered by the switch bounce.Or you could just poll the two ports on a regular basis and test for changes, which is how it's usually done, especially with an encoder designed to be turned by a person.

author: kgavionics
author_rank: Regular Contributor
timestamp: July 05, 2021, 09:29:06 pm
content: I used the falling edge of INT0 and I got far better result! Thank youCode:#include <avr/io.h>#include <avr/pgmspace.h>#include <util/delay.h>#include <stdlib.h>#include <avr/interrupt.h>unsigned char encoder;int main(void){DDRC |= (1<<PC4) | (1<<PC5);DDRD &=~ (1 << PD2); /* PD2 and PD3 as input */DDRD &=~ (1 << PD3);PORTD |= (1 << PD2)|(1 << PD3); /* PD2 and PD3 pull-up enabled */EIMSK |= (1<<INT0) ; /* enable INT0 and INT1 */EICRA |=(1<<ISC01) ;//INT0 Falling EDGEsei();while(1){_delay_ms(1);}return 0;}ISR(INT0_vect ){if(bit_is_set(PIND, PD3)){encoder++;PORTC |=(1<<PC4);PORTC &=~(1<<PC5);}else{encoder--;PORTC |=(1<<PC5);PORTC &=~(1<<PC4);}}

author: cv007
author_rank: Frequent Contributor
timestamp: July 05, 2021, 10:11:37 pm
content: You can alternate pin interrupts so any bouncing is ignored, and the pin of interest in the irq is 'the other pin' which by now is done with any bouncing it may have had. It then turns out that when you have both recorded pin values low, you can count that as in increment/decrement. Everything continues to work when there is a change of direction, even though it would seem a transition is being skipped.https://godbolt.org/z/hM1n766Yredit- those 3 vars used in the isr's should be volatile even though currently looks ok (the encoder var could then be a problem in other code later on)-https://godbolt.org/z/aTx7Gx3nG

author: kgavionics
author_rank: Regular Contributor
timestamp: July 06, 2021, 02:17:24 am
content: HelloI modified my own code to include a second interrupt and the result is awesome, not a single miss even in high speed rotation!Code:#include <avr/io.h>#include <util/delay.h>#include <stdlib.h>#include <avr/interrupt.h>unsigned char encoder;int main(void){DDRC |= (1<<PC4) | (1<<PC5);DDRD &=~ (1 << PD2); /* PD2 and PD3 as input */DDRD &=~ (1 << PD3);PORTD |= (1 << PD2)|(1 << PD3); /* PD2 and PD3 pull-up enabled */EIMSK |= (1<<INT0) | (1<<INT1) ; /* enable INT0 and INT1 enabled */EICRA = 0x0a; // INT0 AND INT1 FALLING EDGEsei();while(1){_delay_ms(1);}return 0;}ISR(INT0_vect ){if(bit_is_set(PIND, PD3)){encoder++;PORTC |=(1<<PC4);PORTC &=~(1<<PC5);}else{encoder--;PORTC |=(1<<PC5);PORTC &=~(1<<PC4);}}ISR(INT1_vect ){if(bit_is_set(PIND, PD2)){encoder--;PORTC |=(1<<PC5);PORTC &=~(1<<PC4);}else{encoder++;PORTC |=(1<<PC4);PORTC &=~(1<<PC5);}}Thank you guys for all your inputs, it's very much appreciated!

author: Scrts
author_rank: Frequent Contributor
timestamp: July 06, 2021, 03:56:17 pm
content: Just FYI: I had hardware and software debouncers for mechanic rotary encoders. They still skip steps from time to time, depending on the speed of rotation. The solution for me was to switch to optical encoder and I've never had any problems.I've also seen people using hard drive motor as an encoder.

author: Doctorandus_P
author_rank: Super Contributor
timestamp: July 11, 2021, 10:12:18 pm
content: Start by redrawing your schematic in a proper way.As a guide, put high voltages on top of the schematic, and low voltages on the bottom.Then try to use signal flow from left to right (which you already did).Also group components by function.For example put VCC on top, then connect the pullup resistors to it.If you do this, then you will discover you've drawn your schematic wrong.The switch (pins 4 & 5) does not have a pullup to VCC, while I guess your intention was to do so.Even if you did mean to connect it in this way, I still consider it an error, as your schematic does not convey it's intention, and leaves me guessing.You may be thinking I'm nitpicking here, and you're right about that. This is a quite simple schematic. When schematics become more complicated though, this becomes an important factor in readability. In the long run you'd be better off developing a habit of drawing neat schematics.Your scope traces also show RC constants, while the only capacitor (10nF) appears to be some kind of decoupling capacitor connected between GND and VCC.I see no capacitors for the RC time constants.Deriving meaningful data from your scope picture is difficult, because a lot of info is missing.I do see that the duty cycle of the blue trace in the first screenshot is more assymetrical then in the second screenshot, but this can also be because of the way the knob is turned.Trouble shooting such things is easier when some variables are eliminated. For example by rotating the knob with a motor at a (sort of) constant speed, or by a big heavy knob that can be used as a flywheel.----------------In the past I once connected such a rotary encoder wrongly. I switched one of the "signal wires" with the "GND" connection. The encoder worked fine in one direction, but in the other direction both signals switched at the same time on some of the flanks.And where do you probe your signals?I assume you do it on the right side of the resistors. If you do it on the left side, directly on the encoder, you may see debounce noise on your scope, but also see more of what is happening.

author: kgavionics
author_rank: Regular Contributor
timestamp: July 29, 2021, 01:58:20 pm
content: Just an update:By using an MC14490 (Debounce eliminator) I got perfect result!