cancel
Showing results for 
Search instead for 
Did you mean: 

Quadrature encoder wont work

stefanskos9
Associate II
Posted on February 14, 2013 at 06:16

Hi All,

I have copied a few different code examples from this forum for quadrature encoder but I just cant seem to get it to work.

I have tried on TIM8, TIM3, TIM12 with no luck. The examples I have copied the code from seem to have been resolved and confirmed as working.

I thought maybe my encoder is at fault, so tied CH1 to ground and CH2 to +3V6, then vice versa but the CNT doesnt seem to increment - should it? Unfortunately I do not have an oscilloscope to test the encoder.

Someone had written that their encoder wasn't working because they had the wrong signal levels - but I guess 3.6V is fine?

Any help/thoughts would be greatly appreciated.

This is the code I'm using ATM

void initEncoder(void)

{

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_ICInitTypeDef TIM_ICInitStruct;

GPIO_InitTypeDef  GPIO_InitStructure;

//Configure peripheral clocks

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);  

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  

//Configure pins

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; // GPIO_PuPd_DOWN; //GPIO_PuPd_NOPULL;

GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8);  //C6 -TIM8_CH1

GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM8);  //C7  TIM8_CH2

//Configure Timer

TIM_TimeBaseStructure.TIM_Prescaler = 0;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_Period = 8191;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  

TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

TIM_ARRPreloadConfig(TIM8, ENABLE);

//Debounce filter

TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;

TIM_ICInitStruct.TIM_ICFilter=3;

TIM_ICInit(TIM8, &TIM_ICInitStruct);

TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;

TIM_ICInitStruct.TIM_ICFilter=3;

TIM_ICInit(TIM8, &TIM_ICInitStruct);

//Setup quadrature encoder and enable timer

TIM_EncoderInterfaceConfig(TIM8,TIM_EncoderMode_TI12,TIM_ICPolarity_Falling,TIM_ICPolarity_Falling);

TIM_Cmd(TIM8, ENABLE);  

#quadrature-encoder #encoder
12 REPLIES 12
flyer31
Senior
Posted on February 14, 2013 at 09:21

Hi Steve,

sorry, but if you have no oscilloscope, I cannot make you much hope that you get it running. It is not THAT easy ... . You will have to do some testing, and if you cannot see both encoder channels, then this will not be possible.

frankfrank956
Associate III
Posted on February 14, 2013 at 23:09

How about you connect your encoder to a couple of transistor switches with LEDs to see the states change and turn them over real slow.

What are the encoders on? They may be open collector and need pull-up resistors.

What processor is this for? I have known working code for an STM32F4.

stefanskos9
Associate II
Posted on February 14, 2013 at 23:49

What are the encoders on? They may be open collector and need pull-up resistors.

The encoder is on a motor and is 64pulse/rev open collector. I guess the internal pull up isn't strong enough? Thanks for this suggestion! I'll give it a try

What processor is this for? I have known working code for an STM32F4.

The STM32F4 🙂 Is your code different to mine? I never used to have the timebaseinit or ICinit, but saw someone else using this so i added it in.

No idea why the period is 8191, or what it should be :s

64pulse/rev @ 10,000RPM max = 10,666 pulse/s

hrobinson
Associate II
Posted on February 15, 2013 at 17:59

I suggest you use a couple of GPIO pins, set them up as outputs, and you can toggle them in your code.  Connect these pins to your encoder inputs.  That will help you debug.

Now, having got some quadrature encoders running myself some months ago, I scanned your code...

Check the pins.  Depending on the device, pins C6, C7... well, on STM32F100xx for example, these are REMAP to TIM3 ch1, ch2.  But you seem to be trying TIM8.  And you have not called GPIO_RemapConfig(...).  So it could be that.

Curiously, in my code I left the pins configured as IPU - not AF_OD - hadn't noticed that before, but I can assure you it works even though it's connected to a timer.

Other than that, I can't see anything missing or obviously wrong.

Henry

hrobinson
Associate II
Posted on February 15, 2013 at 22:44

Oops, yes of course the pins have to be IPU (or in floating, depending on the signals driving them).  Nothing odd about that.  I was having a dozy moment there...

jj2
Associate II
Posted on February 16, 2013 at 14:37

Note the following:

//Configure peripheral clocks

RCC_

APB2

PeriphClockCmd(RCC_

APB2

Periph_TIM8, ENABLE);  

RCC_

AHB1

PeriphClockCmd(RCC_

AHB1

Periph_GPIOC, ENABLE);  

Should not

these

be the same? 

A scope would be nice - but @ ''hand rotation'' speeds you can likely observe each encoder channel driving an Led.  (suggest a ''decent'' Led - and current limiting R such that 2-3mA flows. R ~ 430 ohms if Led ''drop'' is ~ 2V)  Series connect the R to 3V3 - other side of R to led Anode - and led Cathode to encoder channel. Most encoders ''sink'' to ground when switching - there will likely be encoder connections to ground - possibly 3V3 to 5V as well.  You must make all such encoder connections.  While testing - isolate all encoder signals from the MCU.  At ~ every 6% of encoder rotation - the encoder channel output (1 or the other) should toggle - and be captured/displayed upon the Led.  Should you ''spin'' the encoder the Led On times will lessen - but should still be visible.  (i.e. poor-man's scope)

Test described should get the encoder, ''off the hook.''  Especially like ''Henry's'' suggestion of then testing your encoder SW via, ''routing free GPIO outputs back to the encoder inputs.''  The output strength of these GPIO must be sufficient to properly ''pull down'' each of the encoder inputs - simple DVM @ encoder input pins will confirm.  Beauty of the MCU-GPIO approach is that you then have, ''total easy/control'' of signal relationships, frequency, and duty cycle.  Monitoring the appropriate Registers should then guide you toward success... 

frankfrank956
Associate III
Posted on February 16, 2013 at 16:09

Sorry for the delay. I have written up my quadrature encoder implementation for the STM32F4 here:

http://www.micromouseonline.com/2013/02/16/quadrature-encoders-with-the-stm32f4

The code is listed there. I connect the encoders from a pair of Faulhaber motors direct to the appropriate timer pins. Only the internal pull-ups on the pins are used. The encoders run just fine at the 3.3V system supply even though they are supposed to be 5V devices.

I would be interested to know what your application might be and how you get on. Also, if there are any problems with the code I have so that I can improve it if necessary.

emalund
Associate III
Posted on February 16, 2013 at 16:13

I'm confused

there is much talk about a quadrature encoder and then hand rotation and LEDs which would need a quadrature decoder what is it?

a quadrature encoder generate output a quadrature decoder need input

Erik
jj2
Associate II
Posted on February 16, 2013 at 19:32

''I'm confused''   And who isn't?

OP has no test gear - suggestion I provided creates a simple ''monitor'' to confirm that his encoder is in fact toggling its channel outputs.

Even world class code will fail if the driving source is flawed...