Servos and Potentiometers for flight simulator device

Hello all,
I am fairly new to coding in C and i've got a school engineering project that i need help with.
I have 3D printed an artificial horizon which i have connected to servos and made it follow a control yokes inputs which come from 2 potentiometers.
And this works great, but it isn't how a plane works and as this is a flight simulator i want to to simulate as realistically as possible how a plane flies.
So i want it to do is:

  • have a deadzone in the centerpoint of the pots
  • continually move the servos in the direction which the pot is turned until it hits the end of the servos throw using the amount that the pot is turned as a kind of guide for speed (e.g when you move pot half way to the left, servo will move to the left at half speed, move it all the way and it will move at a much higher speed)

Here is a video of the thing in action maybe it will help.
I hope i have explained my problem as best as i could

Thankyou very much in advance

~ Jozef

Whoops i forgot to show you the code i currently have

/*
Controlling a servo position using a potentiometer (variable resistor)
by Michal Rinott http://people.interaction-ivrea.it/m.rinott

modified on 8 Nov 2013
by Scott Fitzgerald

*/

#include <Servo.h>

Servo pitchServo; // create servo object to control a servo
Servo rollServo;
int pitchPin = A0; // analog pin used to connect the potentiometer
int rollPin = A1;

int val; // variable to read the value from the analog pin

void setup()
{
rollServo.attach(10);
pitchServo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop()
{
val = analogRead(pitchPin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 180, 0); // scale it to use it with the servo (value between 0 and 180)
pitchServo.write(val); // sets the servo position according to the scaled value
delay(15); // waits for the servo to get there

val = analogRead(rollPin);
val = map(val, 0, 1023, 0, 180);
rollServo.write(val);
delay(15);

}

Its really quite simple

again, thanks in advance :slight_smile:

This is a fairly frequent question with joysticks where the person wants the servo to not follow the joystick when the joystick returns to the neutral position. Below is some test code that incrementally moves a servo when a condition (button press) is detected. You might use something similar with a pot with the servo move direction and speed determined by pot value.

//zoomkat servo button sweep test 12-23-2013
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include <Servo.h>
int button1 = 5; //button pin, connect to ground to move servo
int press1 = 0;
int button2 = 6; //button pin, connect to ground to move servo
int press2 = 0;
Servo servo1;
int pos = 90; // variable to store and set the servo position 

void setup()
{
  Serial.begin(9600);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  servo1.attach(7);
  servo1.write(pos); //starting position
  digitalWrite(5, HIGH); //enable pullups to make pin high
  digitalWrite(6, HIGH); //enable pullups to make pin high
  Serial.println("servo button sweep test 12-23-2013");
}

void loop()
{
  press1 = digitalRead(button1);
  if (press1 == LOW)
  {
    pos=(pos+1);
    if(pos>180) pos=180; //limit upper value
    Serial.println(pos); //for serial monitor debug
    servo1.write(pos); // tell servo to go to position in variable 'pos' 
    delay(150); // waits 150ms to slow servo movement 
  }    

  press2 = digitalRead(button2);
  if (press2 == LOW)
  {
    pos=(pos-1);
    if(pos<0) pos=0; //limit lower value
    Serial.println(pos); //for serial monitor debug
    servo1.write(pos); // tell servo to go to position in variable 'pos' 
    delay(150); // waits 150ms to slow servo movement
  }
}

This simple joystick - servo demo may be useful

...R

Thats exactly what i was looking for Robin2, just now to make it move faster depending on where it is, any ideas how to write that into code?

Edit: I just tried it out on my setup and its very jittery, i guess you lower int servoMove = 3 to make it smoother? Other than that it works basically how i need it, thanks!

Hi,
Can you post your working sketch and a link to the final result video?
The cockpit looks impressive.
Do you have any schematics?

Tom..... :slight_smile:

Hi Tom,
Yeah I have schematics as i designed and manufactured it all myself, heres some links to photos:

Panel drawn in CAD

Panel laser cut, painted then engraved

White backlighting closeup

Green backlighting closeup

Panel being laser engraved after being painted

Parts of the Artificial Horizon assembly

Enjoy!
If you have facebook it would be cool if you could throw me a like :slight_smile:
Ive got other aviation related projects on there that i designed and made like a 1:55 scale Boeing 777-200 :slight_smile:

737_Sim_Builder:
Thats exactly what i was looking for Robin2, just now to make it move faster depending on where it is, any ideas how to write that into code?

Use the difference between potValue and potCentre to change the value of servoMove

...R

You need two reference values for the ends of the deadband, if the value is above the top one
then take the difference from the top one, if below the bottom reference, take the difference
from that, else its in the middle, and you call it zero.

Robin2:
Use the difference between potValue and potCentre to change the value of servoMove

But wont that make the servo jitter as i said before? what if i adjusted the 100ms delay instead? so i can have it move at 1 degree intervals but faster?

Edit: Nevermind, i should test before i speak, lowering the delay to 5ms makes it much smoother regardless of the servoMove value.

MarkT:
You need two reference values for the ends of the deadband, if the value is above the top one
then take the difference from the top one, if below the bottom reference, take the difference
from that, else its in the middle, and you call it zero.

How would i do that with the current code? As i said im fairly new to coding so i don't quite have the hang of it for that :confused:

Some servo pot code with dead bands to minimize pot "noise" on the final output.

//zoomkat dual pot/servo test 12-29-12
//view output using the serial monitor

#include <Servo.h> 
Servo myservoS1;
Servo myservoS2;

int potpinS1 = 0;  //analog input pin A0
int potpinS2 = 1;

int newvalS1, oldvalS1;
int newvalS2, oldvalS2;

void setup() 
{
  Serial.begin(9600);  
  myservoS1.attach(2);  
  myservoS2.attach(3);
  Serial.println("testing dual pot servo");  
}

void loop() 
{ 
  newvalS1 = analogRead(potpinS1);           
  newvalS1 = map(newvalS1, 0, 1023, 0, 179); 
  if (newvalS1 < (oldvalS1-2) || newvalS1 > (oldvalS1+2)){  
    myservoS1.write(newvalS1);
    Serial.print("1- ");
    Serial.println(newvalS1);
    oldvalS1=newvalS1;
  }

  newvalS2 = analogRead(potpinS2);
  newvalS2 = map(newvalS2, 0, 1023, 0, 179);
  if (newvalS2 < (oldvalS2-2) || newvalS2 > (oldvalS2+2)){  
    myservoS2.write(newvalS2);
    Serial.print("2- ");    
    Serial.println(newvalS2);
    oldvalS2=newvalS2;
  }
  delay(50); //slow down looping to better read serial monitor 
}

737_Sim_Builder:
But wont that make the servo jitter as i said before? what if i adjusted the 100ms delay instead? so i can have it move at 1 degree intervals but faster?

Edit: Nevermind, i should test before i speak, lowering the delay to 5ms makes it much smoother regardless of the servoMove value.

I was going to say that depends on how you write the code - but perhaps you have figured that out.

...R

Robin2:
I was going to say that depends on how you write the code - but perhaps you have figured that out.

i wish i had figured it out, i don't think my problem solving is any good, ill keep working on it but i doubt ill get a good outcome.
Although the only idea i have is to write if statements that say 'if the pot is beyond this certain point, change the servoMove value to 4'
Thats a solution to it though its a bit of a bodge as suddenly at one point of the pots movement the servo will speed up instead of gradually increasing with the pots movements.

Hi,
Have you got the servos running of their own power supply?

Tom... :slight_smile:

TomGeorge:
Hi,
Have you got the servos running of their own power supply?

Yes i made sure that they are only getting a signal from the arduino

737_Sim_Builder:
Although the only idea i have is to write if statements that say 'if the pot is beyond this certain point, change the servoMove value to 4'

That's a perfectly workable solution.
But what about something like

servoMove = (potValue - potCentre) / 32;

which will give a range from 0-16 for pot values from 512 to 1023 and 0 to -16 for the other half (I hope)

You will need to do some expermineting to get exactly what you want. The Arduino system is ideal for experimenting.

...R

Robin2:

servoMove = (potValue - potCentre) / 32;

which will give a range from 0-16 for pot values from 512 to 1023 and 0 to -16 for the other half (I hope)

Bingo, works, well, it does to one side, but to the other you run into a bit of a wall.
I made a spreadsheet that shows clearly what the problem is.

I attached a screenshot of that spreadsheet.

737_Sim_Builder:
Bingo, works, well, it does to one side, but to the other you run into a bit of a wall.
I made a spreadsheet that shows clearly what the problem is.

I attached a screenshot of that spreadsheet.

Your picture is exactly what I expected. What is the problem?

...R

Robin2:
Your picture is exactly what I expected. What is the problem?

Well the negatives, you see servoMove dictates at what intervals the servo moves regardless of direction but when you make servoMove a negative number, it makes the servo move in the opposite direction, so what you get is a servo that can only turn to one side. I hope I didn't confuse you :confused: Because im sort of confusing myself here.