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