Decoding Quadrature Encoder

If you have a simple question and just want an answer.
User avatar
Automatyk
Member
Posts: 13
Joined: Thu Jul 30, 2015 12:10 pm

Decoding Quadrature Encoder

Post by Automatyk »

Hi
I wanted to build simple app which would be decoding data from quadrature encoder and later would send data via UART.

I had an idea to create one task for decoding encoder and the second one to send data via UART.
I connected encoder channel A to 0 bit of 4-bit port and channel B to 1bit. Bits 2 and 3 are connected to GND.

In first task there is an event which is waiting for changind state on 4-bit port. Later it compares actual state with previous state to distinguish the direction of rotation and increment or decrement EnkoderPosition variable respectively. At the end, this task send EncoderPosition to the 2nd task via channel ( streaming channel was also tested).

Here is code for first task:

Code: Select all

void Enkoder_Task( chanend Position_Chan){     int PreviousPinState=0;      int ActualPinState;     p_enkoder :> PreviousPinState;     int EnkoderPosition =0;     timer tmr;     int TimeToElaps=T_1ms;    while(1)    {        select         {            case p_enkoder when pinsneq(PreviousPinState) :> ActualPinState:                    switch(ActualPinState)                    {                    case 0:                        if(PreviousPinState==2)EnkoderPosition++;                        else if(PreviousPinState==1)EnkoderPosition--;                        break;                    case 1:                        if(PreviousPinState==0)EnkoderPosition++;                        else if(PreviousPinState==3)EnkoderPosition--;                        break;                    case 2:                        if(PreviousPinState==3)EnkoderPosition++;                        else if(PreviousPinState==0)EnkoderPosition--;                        break;                    case 3:                        if(PreviousPinState==1)EnkoderPosition++;                        else if(PreviousPinState==2)EnkoderPosition--;                        break;                    }                    PreviousPinState=ActualPinState;                    Position_Chan <: EnkoderPosition;                    break;          }    }}
 
 
In 2nd task there are two events. First is triggered by channel ( waiting for EnkoderPosition from 1st task). Second task is sending recived enkoder position via UART every 100ms.
 

Code: Select all

void SendEnkoderPosition_UART_task(client interface uart_tx_if tx_if,                                    chanend EnkoderPos_Chan){    unsigned char bufforTx[10]={0};    int bufforTx_index = 0;    timer Timer;    uint32_t TimeToElaps;    Timer:>TimeToElaps;    int EnkoderPosition,RecivedData;    while(1)    {        select        {            case Timer when timerafter(TimeToElaps) :> void:                sprintf((char *)bufforTx,"%i\n\r",EnkoderPosition);                while (bufforTx[bufforTx_index] != '\r')tx_if.write(bufforTx[bufforTx_index++]);                bufforTx_index=0;                TimeToElaps+=T_100ms;                break;            case EnkoderPos_Chan :>  RecivedData:                  EnkoderPosition = RecivedData;                break;        }    }}
 
This example that I showed here doesn't work for me. At the begining it looks like it is working ok, but later it doesn't stop counting even when the motor is off, and it counts more pulses per turn than it should.
It seems like the way I decode the encoder is wrong, but for me it looks good. 
 
I also tried to send the data via interface but it doesn't help. 
 
I have chacked the output of the encoder with logic state analyzer and it is working ok.
 
I don't know what I am doing wrong. If you have any idea what can be the reason for this issue, please let me know :)
 
Sorry for my poor english :)
 
Regaeds 
~Automatyk
 
 
 
 
 
User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am

Post by mon2 »

Maybe the issue is with the very slow printf calls to the UART ?

Consider to revise the code to use real time printf ideas as suggested here:

https://www.xmos.com/search/content?ter ... +real-time

and redirect the printing function to use xScope for debugging.

 

Update

======

Also review this on topic thread:

http://www.xcore.com/forum/viewtopic.ph ... quadrature