Orangutan X2 Resetting Due to Rotary Absolute Encoder PWM

Hi all,

I am having troubles with my micro-controller reading in rotary absolute encoder values. It’s a 10-bit encoder US Digital MA3 outputting a single channel PWM signal. I am using the Orangutan library linked below to manage the PWM signals for ease of programming:

pololu.com/docs/0J18/8

Here are the snippets of my code dealing with the encoder values:

MAIN.C

struct abs_encoder enc1; //data structure representing encoder readings
struct abs_encoder enc2;
struct PulseInputStruct p6; //data structure representing encoder pulse PWM information
pulse_in_start((unsigned char[]) {IO_D6, IO_D4},2);
	read_encoder(&p6, 0, &enc1); 
        read_encoder(&p4, 0, &enc2);

ENCODER.C

void read_encoder(struct PulseInputStruct *pulse, unsigned char channel, struct abs_encoder *enc){
get_pulse_info(channel, &pulse); //(This line is causing the micro-controller to go into a continuous reset)
	unsigned int direction;//to determine if encoder is going clockwise or counterclockwise 
	if (pulse->newPulse & HIGH_PULSE) {
		if(enc->last_PWM_width == pulse->lastHighPulse) {
			enc->enc_travel_A = enc->enc_travel_A;
		} else if(pulse->lastHighPulse > enc->last_PWM_width) {
			direction = 1;
			enc->last_PWM_width = pulse->lastHighPulse;
		} else {
			direction = 0;
			enc->last_PWM_width = pulse->lastHighPulse;
		}
	}
	if (direction = 1) {
		enc->enc_travel_A = enc->enc_travel_A + ticks_to_microseconds(pulse->lastHighPulse);
	} else {
		enc->enc_travel_A = enc->enc_travel_A - ticks_to_microseconds(pulse->lastHighPulse);
	}
};

Any insight on the reset problem is appreciated!

UPDATE: I disconnected both encoders so no signals are going into the pins PD4 and PD6…still getting a reset.

Hello.

I briefly looked at the code you posted and did not noticed anything obviously wrong, aside from your last IF/ELSE statement using an assignment operator instead of a comparison operator. How did you know that your Orangutan X2 resets after calling the get_pulse_info method?

It definitely sounds like something in your code is causing your Orangutan X2 to reset. Can you post your entire code here? (You can use the “Upload attachment” feature if the code is too long.)

By the way, I added code tags ([ code ][ /code ] - without spaces) to your post to make it easier to read; please use this method to post code in the future.

- Amanda

Hi,

I’ve gotten the ucontroller reset problem fixed. However, my readings from the lastHighPulse of the struct PulseInputStruct does not make sense. I am expecting values that increase or decrease corresponding to the physical turn of the encoder clockwise and counterclockwise. What I am getting is a value that keeps incrementing like a timer, independent of the encoder. Is there more documentation on the Orangutan PWM functions that just pololu.com/docs/0J18/8

main.c

[code]struct abs_enc enc1; //data structure representing encoder values
struct abs_enc enc2; //data structure representing encoder values
volatile struct PulseInputStruct pd_4; //struct containing PWM values
volatile struct PulseInputStruct pd_6; //struct containing PWM values

int main (void) {
pulse_in_start((unsigned char[]) {IO_D4, IO_D6}, 2);
while(1) {
get_pulse_info(0, &pd_4);
get_pulse_info(1, &pd_6);
read_abs_enc(&pd_4, &enc1, 0);
read_abs_enc(&pd_6, &enc2, 1);
…}}[/code]

encoder.h

struct abs_enc { volatile unsigned long travel; //represents encoder travel since last reset [counts] volatile unsigned long cur_pulse_width; volatile unsigned long past_pulse_width; }; void set_abs_encoder (struct abs_enc *enc, struct PulseInputStruct *pulse); //sets encoder values void set_abs_encoder2 (struct abs_enc *enc, struct PulseInputStruct *pulse); void read_abs_enc (struct PulseInputStruct *pulse, struct abs_enc *enc, unsigned char ch);

encoder.c

[code]void set_abs_encoder (struct abs_enc *enc, struct PulseInputStruct *pulse) {
if(enc->past_pulse_width == pulse->lastHighPulse) {
lcd_goto_xy(0, 2);
//print(“Same!”);
//printf("%08lu", enc->past_pulse_width);
printf(" %08lu", pulse->lastHighPulse);
enc->past_pulse_width = pulse->lastHighPulse;
enc->travel = enc->travel;
} else if(pulse->lastHighPulse > enc->past_pulse_width) {
direction = 1;
lcd_goto_xy(0, 2);
//printf("%d", direction);
//printf("%08lu", enc->past_pulse_width);
printf(" %08lu", pulse->lastHighPulse);
enc->past_pulse_width = pulse->lastHighPulse;
} else {
direction = 0;
lcd_goto_xy(0, 2);
printf("%d", direction);
//printf("%08lu",enc-> past_pulse_width);
printf(" %08lu", pulse->lastHighPulse);
enc->past_pulse_width = pulse->lastHighPulse;
}
if(direction == 1) {
enc->travel = enc->travel + ticks_to_microseconds(pulse->lastHighPulse);
} else {
enc->travel = enc->travel - ticks_to_microseconds(pulse->lastHighPulse);
}
}

void set_abs_encoder2 (struct abs_enc *enc, struct PulseInputStruct *pulse) {
if(enc->past_pulse_width == pulse->lastHighPulse) {
lcd_goto_xy(0, 3);
//print(“Same!”);
//printf("%08lu", enc->past_pulse_width);
printf(" %08lu", pulse->lastHighPulse);
enc->past_pulse_width = pulse->lastHighPulse;
enc->travel = enc->travel;
} else if(pulse->lastHighPulse > enc->past_pulse_width) {
direction = 1;
lcd_goto_xy(0, 3);
//printf("%d", direction);
//printf("%08lu", enc->past_pulse_width);
printf(" %08lu", pulse->lastHighPulse);
enc->past_pulse_width = pulse->lastHighPulse;
} else {
direction = 0;
lcd_goto_xy(0, 3);
//printf("%d", direction);
//printf("%08lu",enc-> past_pulse_width);
printf(" %08lu", pulse->lastHighPulse);
enc->past_pulse_width = pulse->lastHighPulse;
}
if(direction == 1) {
enc->travel = enc->travel + ticks_to_microseconds(pulse->lastHighPulse);
} else {
enc->travel = enc->travel - ticks_to_microseconds(pulse->lastHighPulse);
}
}

void read_abs_enc (struct PulseInputStruct *pulse, struct abs_enc *enc, unsigned char ch) {
if (ch == 0) {
if (pulse->newPulse & HIGH_PULSE) {
set_abs_encoder(&enc, &pulse);
} else {
lcd_goto_xy(0, 2);
print(“No Pulse!”);
}
}
if(ch == 1) {
if (pulse->newPulse & HIGH_PULSE) {
set_abs_encoder2(&enc, &pulse);
} else {
lcd_goto_xy(0, 3);
print(“No Pulse!”);
}
}
}[/code]

Thank you

I looked at your code a little bit and do not see anything obviously wrong with it.

We do not have any other documentation on the Orangutan Pulse/PWM inputs aside from the source code. To get a better understanding of how lastHighPulse is computed, you should look at the source code of the library itself.

- Amanda

How do I get to the source code? I can only access the header files…

Thanks

You can find the source code on the OrangutanPulseIn library’s GitHub page.

- Amanda

Solved.