I am making a flight computer for an rc plabe using an arduino uno rev3 for my computer science A level project, and have been expirencing a problem the pulseIn() function.
The flight controller uses the yaw (rudder) and throttle values in order to vary the thrust between two motors on an rc aircraft in order to create asymetrical thrust, allowing the aircraft to perform maneuvers otherwise impossible.
The Arduino is reading two PWM values from the reciver, one for the engine power, and another for the rudder. Every 23 - 25 seconds the input from both the rudder and throttle pins goes through a semi-predicatble pattern detailed below and in the Dif_thrust input.jpg graph.
-
The input decreases, increase, decreases then increases again before spasming. This happens pretty much every cycle, and is noticable on lower throttle input settings.
-
This is the stage that causes the most problems, where the input quickly changes from approximately the correct value to a lower calue. This lower value increases for a period, before dropping suddenly and increasing again.
-
The input increases gradually in two stepsbefore returning to the correct value.
This behaviour occurs no matter what throttle input, or if the throttle input is changing (see dif thrust changing input.jpg). The behaviour is slightly different for the rudder input, but follows a simialr pattern (see rudder input.jpg).
My Computer Science teacher and I have tried/discovered the following things:
- regularly repeats every 23-25 seconds
- using servo.write() vs servo.writeMicroseconds() has no observable difference
- increasing the timeout for the pulseIn() function has no effect
- removing one PWM input and/or adding a 100ms delay has no effect
Does anyone know either what is causing this issue or how to fix it? If you need any more details please ask.
Here is the code:
#include <Servo.h>
Servo eng1; //left engine (from pilots perspective)
Servo eng2; //right engine
Servo throttle;
Servo rudder_rec;
int eng1_pin = 3;
int eng2_pin = 4;
int throttle_pin = 13;
int rudder_pin = 12;
int throttle_input;
int rudder_input;
int eng1_output;
int eng2_output;
void setup() {
Serial.begin(9600);
eng1.attach(eng1_pin);
eng2.attach(eng2_pin);
pinMode(rudder_pin, INPUT);
pinMode(throttle_pin, INPUT);
TIMSK0=0;
}
void loop() {
//taking input from the recivers
throttle_input = pulseIn(13,HIGH);
rudder_input = pulseIn(12, HIGH);
//Serial.println(rudder_input);
Serial.println(throttle_input);
eng1_output = dif_thrust1(throttle_input, rudder_input);
eng2_output = dif_thrust2(throttle_input, rudder_input);
//Serial.println(eng1_output);
//Serial.println(eng2_output);
eng1.write(eng1_output);
eng2.write(eng2_output);
}
//functions manipulating the throttle input and rudder input
//for eng2
int dif_thrust2(int throttle_input, int rudder_input){//works out power for first motor
int a;
//slows down engine 2 if
if (rudder_input > 1600){
a = throttle_input - (rudder_input - 1600)*1.2;
}
//if the output is less than the minumum value, it is set to the minimum value
if (a < 992){
a=992;
}
//sets the output to the throttle input if the rudder input does not require eng1 to slow
if (rudder_input <= 1600){
a = throttle_input;
}
//between these values the motor doesnt have enough power to turn smoothly
if (a < 1052 and a > 1010){
return 1000;
}
else
{
return a;
}
}
//for eng1
int dif_thrust1(int throttle_input, int rudder_input){//works out power for first motor
int a;
if (rudder_input < 1400){
a = throttle_input + (rudder_input - 1400)*1.2;
}
if (a > 1970){
a=1970;
}
if (a < 992){
a=992;
}
if (rudder_input >= 1400){
a = throttle_input;
}
if (a < 1052 and a > 1010){
return 1000;
}
else
{
return a;
}
}
//Throttle values
//min value = 992
//max value = 1999
//neutral value = 1500
//min spin value = 1052
//no spin max value = 1010
//Rudder values
//neutral value = 1470 - 1510
//max value = 1940
//min value = 1000