Hello,
I would like to test how an quadrature encoder component works and to show its counter on my OLED.
From hardware point of view everything is fine, because it works nice with Arduino IDE.
I used the code from examples of Rotary Encoder component page:
https://www.matrixtsl.com/wiki/index.ph ... :_General)
I use also a pushbutton from encoder.
When I push it, then it just changeing the value from 0 to 1 and then back to 0 at the next push.
I tried the attached Flowcode file.
In the simulation it works, but in reality, the OLED and Pushbutton works, but the encoder shows no values.
What can be wrong?
Quadrature encoder and OLED with Arduino
-
- Posts: 18
- http://meble-kuchenne.info.pl
- Joined: Mon Jun 27, 2022 2:56 pm
- Has thanked: 5 times
- Been thanked: 1 time
Quadrature encoder and OLED with Arduino
- Attachments
-
- Arduino Uno SH1106 I2C and Encoder FC9.fcfx
- (17.11 KiB) Downloaded 283 times
-
- Valued Contributor
- Posts: 1528
- Joined: Thu Dec 03, 2020 10:57 am
- Has thanked: 353 times
- Been thanked: 549 times
Re: Quadrature encoder and OLED with Arduino
Hi
My first guess would be with the connections. How have you connected the encoder?
Which of the examples have you tried? Do none of them work or just one in particular (they each use different techniques)?
Regards
My first guess would be with the connections. How have you connected the encoder?
Which of the examples have you tried? Do none of them work or just one in particular (they each use different techniques)?
Regards
-
- Matrix Staff
- Posts: 1926
- Joined: Mon Dec 07, 2020 10:06 am
- Has thanked: 503 times
- Been thanked: 686 times
Re: Quadrature encoder and OLED with Arduino
My Guess is the encoder is changing to fast to catch all the edges and therefore EncChanged is often equal to 255 and resetting the counter.
One option might be to try and remove the 10ms delay and see if that helps.
Another option is to use the interrupt based approach and see if this helps. Ether an IOC type interrupt or a timer based interrupt should be fine. This is probably more suitable because the GLCD will be relatively slow to update and may cause you to miss encoder pulses using a polling method.
One option might be to try and remove the 10ms delay and see if that helps.
Another option is to use the interrupt based approach and see if this helps. Ether an IOC type interrupt or a timer based interrupt should be fine. This is probably more suitable because the GLCD will be relatively slow to update and may cause you to miss encoder pulses using a polling method.
Regards Ben Rowland - MatrixTSL
Flowcode Online Code Viewer (Beta) - Flowcode Product Page - Flowcode Help Wiki - My YouTube Channel
Flowcode Online Code Viewer (Beta) - Flowcode Product Page - Flowcode Help Wiki - My YouTube Channel
-
- Posts: 18
- Joined: Mon Jun 27, 2022 2:56 pm
- Has thanked: 5 times
- Been thanked: 1 time
Re: Quadrature encoder and OLED with Arduino
Hi,
The next code works for me with interrupt on change on Arduino Port D, including Pushbutton state.
I noticed there is a debouncing in ms for the pushbutton.
I expect is the same, probably hidden, for the encoder inputs A and B too.
In Arduino IDE there are many ways how a debouncing can be implemented.
Then I have the next question:
- If I do not want to use the default debouncing, mostly done with timing in milliseconds, I guess, for pushbutton or for rotary encoder, then how can implement my own debouncing subroutine/code?
- With pushbutton seems simpler, because I just set the Debounce to 0ms, but how can I do it with the rotary encoder?
For example, a faster and better debounce code for rotary quadrature encoder, already tested with good results, would be next:
And for a pushbutton:
Now, how can I implement this in Flowcode?
Should I just write C code and consider the pins A and B of the encoder as normal Inputs and just ignore the Flowcode component Rotary Encoder? Or may I change somehow that component? Or do I have to make a new component from scratch?
Or can be the existing component modified, maybe with a free/open code for debouncing, where the user can implement his own code or to have several debouncing subroutines to choose from?
What is the faster, easier or the better way?
Can you help in that direction?
The next code works for me with interrupt on change on Arduino Port D, including Pushbutton state.
I noticed there is a debouncing in ms for the pushbutton.
I expect is the same, probably hidden, for the encoder inputs A and B too.
In Arduino IDE there are many ways how a debouncing can be implemented.
Then I have the next question:
- If I do not want to use the default debouncing, mostly done with timing in milliseconds, I guess, for pushbutton or for rotary encoder, then how can implement my own debouncing subroutine/code?
- With pushbutton seems simpler, because I just set the Debounce to 0ms, but how can I do it with the rotary encoder?
For example, a faster and better debounce code for rotary quadrature encoder, already tested with good results, would be next:
Code: Select all
void read_encoder() {
// Encoder interrupt routine for both pins. Updates counter
// if they are valid and have rotated a full indent
static uint8_t old_AB = 3; // Lookup table index
static int8_t encval = 0; // Encoder value
static const int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; // Lookup table
old_AB <<=2; // Remember previous state
if (digitalRead(ENC_A)) old_AB |= 0x02; // Add current state of pin A
if (digitalRead(ENC_B)) old_AB |= 0x01; // Add current state of pin B
encval += enc_states[( old_AB & 0x0f )];
// Update counter if encoder has rotated a full indent, that is at least 4 steps
if( encval > 3 ) { // Four steps forward
counter++; // Increase counter
encval = 0;
}
else if( encval < -3 ) { // Four steps backwards
counter--; // Decrease counter
encval = 0;
}
}
Code: Select all
bool debounce_switch() {
static uint16_t state = 0; //holds present state
state = (state << 1) | (digitalRead(SW)) | 0xE000;
if (state == 0xF000) return 1;
return 0;
}
Now, how can I implement this in Flowcode?
Should I just write C code and consider the pins A and B of the encoder as normal Inputs and just ignore the Flowcode component Rotary Encoder? Or may I change somehow that component? Or do I have to make a new component from scratch?
Or can be the existing component modified, maybe with a free/open code for debouncing, where the user can implement his own code or to have several debouncing subroutines to choose from?
What is the faster, easier or the better way?
Can you help in that direction?
- Attachments
-
- Arduino Uno SH1106 I2C and Encoder FC9_IOC.fcfx
- (15.87 KiB) Downloaded 342 times