Author Topic: Messy rotary encoder??  (Read 1613 times)

0 Members and 1 Guest are viewing this topic.

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 195
  • Country: ca
Messy rotary encoder??
« on: July 05, 2021, 06:28:56 pm »
Hello guys
I 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?
« Last Edit: July 05, 2021, 06:54:00 pm by kgavionics »
 

Online Benta

  • Super Contributor
  • ***
  • Posts: 5874
  • Country: de
Re: Messy rotary encoder??
« Reply #1 on: July 05, 2021, 07:56:04 pm »
Signal looks good to me.
The negative-going edges are aligned as they should be. I don't understand the problem.
 
The following users thanked this post: kgavionics

Online PCB.Wiz

  • Super Contributor
  • ***
  • Posts: 1544
  • Country: au
Re: Messy rotary encoder??
« Reply #2 on: July 05, 2021, 08:13:07 pm »
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?

Those captures both look quadrature valid, but the failing direction is less angle balanced than the always working direction.  That should be 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 ?
 
The following users thanked this post: kgavionics

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 195
  • Country: ca
Re: Messy rotary encoder??
« Reply #3 on: July 05, 2021, 08:47:46 pm »
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: [Select]
#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 EDGE
sei();


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!
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
Re: Messy rotary encoder??
« Reply #4 on: July 05, 2021, 08:51:49 pm »
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!

There'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.
 

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 195
  • Country: ca
Re: Messy rotary encoder??
« Reply #5 on: July 05, 2021, 09:29:06 pm »
I used the falling edge of INT0 and I got far better result! Thank you


Code: [Select]
#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 EDGE
sei();


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);
    }
}

 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 826
Re: Messy rotary encoder??
« Reply #6 on: July 05, 2021, 10:11:37 pm »
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/hM1n766Yr

edit- 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
« Last Edit: July 05, 2021, 11:45:33 pm by cv007 »
 
The following users thanked this post: kgavionics, thm_w

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 195
  • Country: ca
Re: Messy rotary encoder??
« Reply #7 on: July 06, 2021, 02:17:24 am »
Hello
I modified my own code to include a second interrupt and the result is awesome, not a single miss even in high speed rotation!
Code: [Select]
#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 EDGE
sei();


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!
 

Offline Scrts

  • Frequent Contributor
  • **
  • Posts: 797
  • Country: lt
Re: Messy rotary encoder??
« Reply #8 on: July 06, 2021, 03:56:17 pm »
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.
 
The following users thanked this post: kgavionics

Online Doctorandus_P

  • Super Contributor
  • ***
  • Posts: 3360
  • Country: nl
Re: Messy rotary encoder??
« Reply #9 on: July 11, 2021, 10:12:18 pm »

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.

 

Offline kgavionicsTopic starter

  • Regular Contributor
  • *
  • Posts: 195
  • Country: ca
Re: Messy rotary encoder??
« Reply #10 on: July 29, 2021, 01:58:20 pm »
Just an update:
By using an  MC14490 (Debounce eliminator) I got perfect result!
« Last Edit: July 29, 2021, 02:23:45 pm by kgavionics »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf