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