PWM input from Spektrum RX to Orangutan X2

So, I’ve been banging my head against the wall for days with this one. I’m trying to set up pins D7 and D6 to accept the PWM signal from my Spektrum RX throttle and pitch channels respectively, but I can’t seem to receive any pulses. The RX is getting power and binding with the TX, just fine, but when I try to check for new pulses using the Orangutan libs, it always comes back false. Here is my code, hopefully someone can help me out here.

 #include <pololu/orangutan.h>

 #define LEFT	0
 #define RIGHT	1
 #define LEFT_CHANNEL	7
 #define RIGHT_CHANNEL	6
 #define LEFT_CHANNEL_INDEX 0
 #define RIGHT_CHANNEL_INDEX 1

 void set_motor_speed_pwm_us(signed long pulseWidthMicroseconds, unsigned int motor);
 void set_motor_speed_pwm_ticks(unsigned pulseWidthTicks, unsigned int motor);

 int main()
 {
	// Print battery voltage (in mV) on the LCD.
	clear();
	print_long(read_battery_millivolts_x2());
	// Set up display for showing motor speed
	lcd_goto_xy(0,2);
	print("LEFT:  ");
	print(0);
	lcd_goto_xy(0,3);
	print("RIGHT:  ");
	print(0);
	
	// Start accepting Pulses on
	pulse_in_start((unsigned char[]) {LEFT_CHANNEL, RIGHT_CHANNEL}, 2);
	struct PulseInputStruct pulseInfoLeft;
	struct PulseInputStruct pulseInfoRight;
 
	// Turn green LEDs on to indicate that setup is complete and the main loop is starting.
	green_led(HIGH);
	green_led2(HIGH);

	while(1)
	{
		// Update LCD with battery voltage
		lcd_goto_xy(0,0);
		print_long(read_battery_millivolts_x2());
		// Is there a new high pulse on the left channel?
		if (new_high_pulse(LEFT_CHANNEL_INDEX))
		{
			// Write "Pulse!" to show the first pulse has been received for debugging
			lcd_goto_xy(10,2);
			print("Pulse!");
			get_pulse_info(LEFT_CHANNEL_INDEX, &pulseInfoLeft);  // get pulse info for the left channel
			set_motor_speed_pwm_ticks(pulseInfoLeft.lastHighPulse, LEFT);
		}
		// is there a new pulse on the right channel?
		if (new_high_pulse(RIGHT_CHANNEL_INDEX))
		{
			// Write "Pulse!" to show the first pulse has been received for debugging
			lcd_goto_xy(10,3);
			print("Pulse!");
			get_pulse_info(RIGHT_CHANNEL_INDEX, &pulseInfoRight);  // get pulse info for the right channel
			set_motor_speed_pwm_ticks(pulseInfoRight.lastHighPulse, RIGHT);
		}
	}
}

// Set the motor speed from RC controller input converted to ms
void set_motor_speed_pwm_us(signed long pulseWidthMicroseconds, unsigned int motor)
{
	signed int motorSpeed;
	// 1500 is the neutral point of an RC servo pulse, so subtract 1500 to zero the neutral position, then divide by 2 to reduce a range of ~500 down to 250
	// for the Pololu OrangutanMotor functions
	motorSpeed = ((pulseWidthMicroseconds - 1500) /2);
	if (motor == LEFT)
	{
		set_m1_speed(motorSpeed);
		// Update LCD
		lcd_goto_xy(0,2);
		print("LEFT:  ");
		print_long((signed long) motorSpeed);
	}	
	else
	{
		set_m2_speed(motorSpeed);
		// Update LCD
		lcd_goto_xy(0,3);
		print("RIGHT:  ");
		print_long((signed long) motorSpeed);
	}		
}

// Set the motor speed from RC controller input in system ticks
void set_motor_speed_pwm_ticks(unsigned long pulseWidthTicks, unsigned int motor)
{
	signed long pulseWidthMicroseconds;
	pulseWidthMicroseconds = (signed long) pulse_to_microseconds(pulseWidthTicks);
	set_motor_speed_pwm_us(pulseWidthMicroseconds, motor);
}

Hello.

Did you remember to connect the ground of the receiver to the GND of the Orangutan X2? How is everything connected and what voltage levels do you expect the receiver’s output signal to use?

I recommend simplifying your code as much as possible to try to find the problem. For example, try taking out all motor code and just use the LCD for debugging. See if you can reproduce the problem with just one input channel instead of two.

Also, you should make sure your project is properly configured for the Orangutan X2. Assuming you have a recent Orangutan X2 with an ATmega1284p, the _X2_1298 preprocessor macro should be defined (its value does not matter) and the project should be linking to the libpololu_atmega1284p_x2.a library.

–David

Yes, I have the ground, 5 volt, and signal from the RX going into the ground, 5 volt, D7 pins on the X2 using a standard 3 pin RC servo cable. I have also verified that the jumpers on the bottom of the board are configured to provide 5 volts. The receiver is getting power from the x2 (5 volts), so I know I haven’t reversed the wires or anything. I don’t know what voltage to expect for the pulses. To be honest, I hadn’t really considered that, but I will have to do some research and find an answer to that. I will try cutting the code to the bare minimum tonight, see what I get with just one channel, and report back.

So, apparently my RX is dead. It’s getting power, binds just fine, but it simply won’t output anything on the signal lines. It was working fine when I flew with it last week, but apparently, somewhere between there and when I started testing the connection to my X2, it died. So, I guess the problem isn’t in the code (though there may still be some problems with the code). I will test again after I RMA my RX and report back if I still can’t get it running.

After finding out my receiver was dead and while waiting on the RMA process to complete, I set up an Arduino to output the RC servo signals and got this working properly. In case it is helpful to someone else, the following is a very simplified version of the code, checking only for high pulses on one channel:

#include <pololu/orangutan.h>

int main()
{
	// Print battery voltage (in mV) on the LCD.
	clear();
	print_long(read_battery_millivolts_x2());
	// Set up display for showing motor speed
	lcd_goto_xy(0,2);
	print("LEFT:  ");
	print("0");
	
	// Start accepting Pulses on
	pulse_in_start((unsigned char[]) {IO_D7}, 1);
	struct PulseInputStruct pulseInfo;

	while(1)
	{
		// Update LCD with battery voltage
		lcd_goto_xy(0,0);
		print_long(read_battery_millivolts_x2());
	
		// get pulse info for the left channel
		get_pulse_info(0, &pulseInfo);
	
		unsigned char Pulse = new_high_pulse(0);
	
		// Is there a new high pulse on the left channel?
		if (Pulse)
		{
			// Write "Pulse!" to show the first pulse has been received for debugging
			lcd_goto_xy(12,2);
			print("Pulse!");
			lcd_goto_xy(0,2);
			print("LEFT:  ");
			print_unsigned_long(ticks_to_microseconds(pulseInfo.lastHighPulse));
		}
	}
}