Implementing Rotary Encoder for Motion Control

Hello,

I am having troubles implementing an United Digital MA3 PWN encoder. The micro-controller and encoder are communicating and the readings are mostly good. The only problem I am facing at the moment is some of the logic in reading the encoder values.

The encoder works by outputting a PWM pulse of a varied length on one channel that corresponds to the position of the encoder (ex: a PWM length of 1025 us is 359.65 degrees). The hard part is when the encoder goes through the zero point and you have to figure out if the encoder went through the 0 point clockwise (moving in the forward direction) or counterclockwise (moving in the backwards direction). I need to figure this out because I am using the encoder values to calculate position, speed, etc and I can’t get it to work.

if (portD_pchg & 0x10) { //PD4 changed
		if (portD_di_new & 0x10) { //PD4 changed to high
			enc_at_PD4.t_rise = time;
		}
		else
		{
			enc_at_PD4.t_fall = time;
			enc_at_PD4.pw_high_cur = (enc_at_PD4.t_fall - enc_at_PD4.t_rise); //pulse width in ticks
			
			if(enc_at_PD4.pw_high_cur > 2565) //corrects for pwm pulse signal overlap (max tick per pulse is 1026 us and 1 tick is .4 us) 
			{
				enc_at_PD4.pw_high_cur = 2565;
			}			
			if (enc_at_PD4.pw_high_cur == enc_at_PD4.pw_high_last) //when encoder is not turned
			{
				enc_at_PD4.pw_high_last = enc_at_PD4.pw_high_cur; 
			}
			if (enc_at_PD4.pw_high_cur > enc_at_PD4.pw_high_last)
			{
				direction = 1; 
			}		
			else 
			{
				direction = 0;
			}
			if (direction == 0 & (enc_at_PD4.pw_high_last > 2560)) //when encoder is turned clockwise through zero
			{
				enc_at_PD4.pw_high_last = enc_at_PD4.pw_high_cur;
			}
			
			else if (direction == 1) //when encoder is turned clockwise
			{
				enc_at_PD4.travel += (enc_at_PD4.pw_high_cur - enc_at_PD4.pw_high_last);
				enc_at_PD4.pw_high_last = enc_at_PD4.pw_high_cur;
			}
			else if ((direction == 1) & (enc_at_PD4.pw_high_last < 100)) //when encoder is turned counterclockwise through zero
			{
				enc_at_PD4.pw_high_last = enc_at_PD4.pw_high_cur;
			}
			else if (direction == 0) //if encocder is turned counterclockwise
			{
				enc_at_PD4.travel -= labs(enc_at_PD4.pw_high_cur - enc_at_PD4.pw_high_last);
				enc_at_PD4.pw_high_last = enc_at_PD4.pw_high_cur; 
			}
			else
			{
				enc_at_PD4.pw_high_last = enc_at_PD4.pw_high_cur;
			}
			
		}
	}

Currently the reading when the encoder passes through the 0 point clockwise is okay, but when it passes through the 0 point counterclockwise it is treated as a forward movement rather than a backwards movement…I realize it’s because the if statement for going past the 0 point counterclockwise is preceded by the the if statement for a clockwise movement so it never gets evaluated. However, I cannot put it in front of the clockwise if statement because I end up getting astronomically weird outputs on the ucontroller…

Any input on how the code can be fixed or a different method of approach is appreciated.