How to use a quadrature encoder with STM32/Mbed online compiler? This code is how I’ve solved it.
At first, surfing the net searching for a solution I’ve found this forum post: POST
Then I’ve found a working example program HERE
The following code is that one modified by me for my needs:
- Obtain a number: positive for clockwise turning, negative for conterclockwise.
- The number must be proportional of the turning speed
- I’m using the EC11 encoder that outputs 4 pulses each click
Please nothe that in this code I’ve activated the CPU internal pullups on input lines/pins PC_10 and PC_12. You can change the pins according with your needs and cpu or board used.
#include "mbed.h" // Pin declarations DigitalIn phA1(PC_10); // phase a of the quadrature encoder 1 DigitalIn phB1(PC_12); // phase b of the quadrature encoder 1 // Global variables declaration int encoderClickCountA = 0; // hold the signed value corresponding to the number of clicks left or right since last sample int previousEncoderStateA = 0; // keep a record of the last actioned sample state of the Qb+Qa outputs for comparison on each interrupt // Rotation accumulator for the quadrature encoder void quadratureDecoder1( void ) { int currentEncoderStateA = (phB1.read() << 1) + phA1.read(); // create a two bit value out of phaseB and phaseA if( currentEncoderStateA == previousEncoderStateA ) { return; } switch( previousEncoderStateA ) { case 0: if( currentEncoderStateA == 1 ) { encoderClickCountA--; } else if( currentEncoderStateA == 2 ) { encoderClickCountA++; } break; case 1: if( currentEncoderStateA == 3 ) { encoderClickCountA--; } else if( currentEncoderStateA == 0 ) { encoderClickCountA++; } break; case 2: if( currentEncoderStateA == 0 ) { encoderClickCountA--; } else if( currentEncoderStateA == 3 ) { encoderClickCountA++; } break; case 3: if( currentEncoderStateA == 2 ) { encoderClickCountA--; } else if( currentEncoderStateA == 1 ) { encoderClickCountA++; } break; default: break; } previousEncoderStateA = currentEncoderStateA; } // read the rotation accumulator, and once read, reset it to zero int getClicksA( void ) { int res = encoderClickCountA; // this allows the knob to be rotated "while im not looking at it' and still return the encoderClickCountA = 0; // actual number of clicks that have been rotated since last time I was checking it. return res; } int main() { Serial pc( USBTX, USBRX ); pc.baud(115200); Ticker sampleTicker; // create a timer to sample the encoder int ClicksA; // Click encoder A phA1.mode(PullUp); phB1.mode(PullUp); sampleTicker.attach_us( &quadratureDecoder1, 1000 ); // make the quadrature decoder function check the knob once every 1000us = 1ms pc.printf("test started\r\n"); //Loop principale infinito while( 1 ) { ClicksA = getClicksA()/4; if(ClicksA != 0 ) // If there is some movement on encoders I display it { pc.printf("clicks %d\r\n", ClicksA); } }