Page 1 of 2 12 LastLast
Results 1 to 10 of 12
  1. #1
    10+ Posting Member
    Join Date
    Apr 2014
    Location
    United States
    Posts
    15
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    controlling two continuous rotation servos for airspeed

    Hi, I'm working on a project using Link2FS to send indicated airspeed to a Uno card that will operate two continuous rotation servos that will be attached to my CH yoke with rubber bands in order to increase the resistance that I feel in the yoke the faster I fly. I had originally intended to use regular servos but the 180 degree limitation would not give me enough travel.

    I have been using the code below originally used to control a turn coordinator gauge.

    Code:
    /* 
        This code is in the public domain
        For use with "Link2fs_Multi"
        Jimspage.co.nz
        My thanks to the Guys that gave me snippets of code. 
        
    // Code adapted for flight simulator interface of turn coordinator ball
    
    */
    #include  //Different Servo Library which offers variable speed
    VarSpeedServo myServo; //define myservo (NOTE- it has different case letters than normal servo library)
    
    int CodeIn;// used on all serial reads
    int KpinNo; 
    int Koutpin;
    String tc;
    int tc1;
    int val;
    
    
    String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
    
    void setup() 
    { 
    myServo.attach(9); // attaches the servo on pin 9 to the servo object 
    Serial.begin(115200); 
    }
    
    void loop() {
     
      if (Serial.available()) {
        CodeIn = getChar();
        if (CodeIn == '=') {EQUALS();} // The first identifier is "="
        if (CodeIn == '<') {LESSTHAN();}// The first identifier is "<"
        if (CodeIn == '?') {QUESTION();}// The first identifier is "?"
        if (CodeIn == '/') {SLASH();}// The first identifier is "/" (Annunciators)
      }
    
    }
    
    char getChar()// Get a character from the serial buffer
    {
      while(Serial.available() == 0);// wait for data
      return((char)Serial.read());// Thanks Doug
    }
    
    void EQUALS(){ // The first identifier was "="
     CodeIn = getChar(); // Get another character
      switch(CodeIn) {// Now lets find what to do with it
        case 'A'://Found the second identifier
           //Do something
        break;
         
        case 'B':
           //Do something
        break;
         
        case 'C':
           //Do something
        break;
        
             //etc etc etc
         }
    }
    
    void LESSTHAN(){ // The first identifier was "<"
    CodeIn = getChar(); // Get another character
      switch(CodeIn) {// Now lets find what to do with it
        case 'N'://Found the second identifier Turn coordinator
           
        {
        tc = "";
        tc += getChar();
        tc += getChar();
        tc += getChar();
        //tc += getChar();
       // tc += getChar();
        //tc += getChar();
        int tc1 = tc.toInt(); // convert it to an integer (Thanks Phill)
           
      val = tc1;            // reads the value of the data from FSX turn coordinator
      val = map(val, 0, 256, 0, 179); // scale it to use it with the servo ( between 0-256 for FSX turn coordinator,between 0 and 180 for servo) 
      myServo.slowmove(val,45); // sets the servo position according to the scaled value (second number is servo speed 0=slowest, 255=fastest)
      Serial.println (val); //added for troubleshooting
       
        }
        break;
         
        case 'B':
           //Do something
        break;
         
        case 'C':
           //Do something
        break;
           
             //etc etc etc
         }
    }
    
    void QUESTION(){ // The first identifier was "?"
    CodeIn = getChar(); // Get another character
      switch(CodeIn) {// Now lets find what to do with it
        case 'A'://Found the second identifier
           //Do something
        break;
         
        case 'B':
           //Do something
        break;
         
        case 'C':
           //Do something
        break;
           
             //etc etc etc
         }
    }
    void SLASH(){ // The first identifier was "/" (Annunciator)
      //Do something
    }
    This code does work and I want to give my thanks to the guy who wrote it but I'm getting old and I can't remember where I got it!

    My question is how can I adapt this code to keep the servos still when showing zero airspeed and how do I use the ++ and -- increments to return a value 1 increment higher or lower than the last value read?

    Thanks for all your help,
    Mark

  2. #2
    150+ Forum Groupie
    Join Date
    Nov 2013
    Location
    Evansville, Indiana
    Posts
    243
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: controlling two continuous rotation servos for airspeed

    You need a case for "P" under the "lessthan" function.
    Since you want tension to tighten the faster you fly....

    Copied from an Arduino Forum:
    You would use the Servo Library; sending it a signal of "0 degrees" with Servo.write (or 900ms with Servo.writemicroseconds) will turn it full speed in one direction, and "180 degrees" is full speed in the opposite direction.

    When you send it a signal for 90 degrees the servo should be stationary. If it's not THEN you use the external potentiometer and adjust it until it stops. To emphasize, the potentiometer is only there to fine tune the midpoint; in all other respects it's just like any other servo.

    For the red/black/yellow wires on the servo, the red connects to 5V, black to GND, and the yellow to one of your digital pins on the Arduino (see the documentation)
    ***********************************************************************
    *******Here is some very simplistic sample code not meant to copy in and be usable.*******
    *****But I would start with it in the airspeed "Case", and then modify, based on results.*****
    ***********************************************************************
    You will probably need a buffer variable to keep the servos from jittering at + or - 1 knot.
    You would also need to experiment to see how fast it tightens so as not to stall the servo.
    You may not want tightening under 30 kts and say no more tightening over 130 kts.

    Code:
    if (airspeed > last_airspeed)  
    {
         servo.write(180);       //  tighten tension
    }
    else if (airspeed < last_airspeed)
    {
         servo.write(0);          //  loosen tension
    }
    else 
    {
          servo.write(90);       // hold tension
    }
    last_airspeed = airspeed;
    I will only ever be, half the Geek that I wished I was.
    TheGeekForge.Com

  3. #3
    10+ Posting Member
    Join Date
    Apr 2014
    Location
    United States
    Posts
    15
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: controlling two continuous rotation servos for airspeed

    Thanks, Fess_ter I think that has got me on the right track. For the buffer variable your talking about, is that just a delay?
    Mark

  4. #4
    150+ Forum Groupie
    Join Date
    Nov 2013
    Location
    Evansville, Indiana
    Posts
    243
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: controlling two continuous rotation servos for airspeed

    Mark,

    The buffer would be like...
    if (airspeed > last_airspeed +3)
    or
    if (airspeed < last_airspeed -3)
    but again dependant on how fast the servo moves.

    last_airspeed = airspeed; would then have to go inside the "if" statement brackets { }

    I believe you can slow the servo motion by using, servo.write(45) and servo.write(135), to move at half speed. But I am not sure on that.
    Test it

    When at all possible, avoid "delays" in your loops.
    Inside "Setup" its ok to get something initialized.

    ~Fess
    I will only ever be, half the Geek that I wished I was.
    TheGeekForge.Com

  5. #5
    75+ Posting Member



    Join Date
    Sep 2013
    Location
    California, USA
    Posts
    109
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: controlling two continuous rotation servos for airspeed

    Mark,
    You will have a problem getting the servo to stop at any desired position, not just at "0", because the continuous rotation servos do not provide any position feedback. To make it work correctly you will need to provide a continuous measurement of your servo position so you can stop the servo from rotating when it gets to the proper rotation angle. If you compare the true position of the servo with the fsx gauge indication you can then generate a signal to drive the needle in the direction needed to make the two readings match.

    The usual method of getting the continuous measurement is with a potentiometer, which works very well as long as you will not exceed approximately 330 degrees of rotation. I'm currently doing a very similar project for my gyro compass, also using a continuous rotation servo. In my case I cannot use a potentiometer because the position sensor must be able to rotate freely without ever reaching a mechanical stop so i am using a NXP KMA210 angle sensor to provide the position feedback.

  6. #6
    25+ Posting Member
    Join Date
    Dec 2010
    Location
    Canada
    Posts
    26
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: controlling two continuous rotation servos for airspeed

    +1 for the thought about troubles with continuous rotation servos. Might be much easier with just standard ones with position feedback.

    Mark- it was me who made that code It was for my Lear project:
    https://www.youtube.com/watch?v=pdeH...oyty0c5xocnw0k

    Cheers
    Eric

    *EDIT* I was just thinking about this- if you need the extra travel/rotation you may want to look into stepper motors instead. That way you don't need positional feedback at all- just tell them how far to go and they will do it.

  7. #7
    10+ Posting Member
    Join Date
    Apr 2014
    Location
    United States
    Posts
    15
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: controlling two continuous rotation servos for airspeed

    You know WhiteStar, that's not a bad idea! Worth thinking about anyway. I had decided not to use steppers because of the lower torque but if I'm just twisting rubber bands it might work. Thanks All.
    Mark

  8. #8
    75+ Posting Member



    Join Date
    Sep 2013
    Location
    California, USA
    Posts
    109
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: controlling two continuous rotation servos for airspeed

    Mark, have a look at Hitec servo HS-785HB. It's a specialty servo designed to run a winch on an RC sailboat, and will give you 3-1/2 revolutions using the standard servo commands.

  9. Likes WhiteStar01 liked this post
  10. #9
    10+ Posting Member
    Join Date
    Apr 2014
    Location
    United States
    Posts
    15
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: controlling two continuous rotation servos for airspeed

    Hi again everyone,

    I've decided to go back to the standard servo and using a system of levers I got a prototype working using the standard servo library.
    I do have a question though, when I upload the sketch to the arduino and test it it all works ok but then when I shut FSX down I can hear the servo humming. I'm only using about 90 degrees of the servo travel and I've adjusted it to where it is set in the map setting at 10, 100. Why would the servo be humming like that and will it burn it up eventually?

    Below is my sketch.

    Code:
    /* 
        This code is in the public domain
        For use with "Link2fs_Multi"
        Jimspage.co.nz
        My thanks to the Guys that gave me snippets of code. 
        
    // Code adapted for flight simulator interface of turn coordinator ball
    
    */
    #include  //Different Servo Library which offers variable speed
    VarSpeedServo myServo; //define myservo (NOTE- it has different case letters than normal servo library)
    
    int CodeIn;// used on all serial reads
    int KpinNo; 
    int Koutpin;
    String ASI;
    int ASI_last;
    int val;
    
    
    String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
    
    void setup() 
    { 
    myServo.attach(9); // attaches the servo on pin 9 to the servo object 
    Serial.begin(115200); 
    }
    
    void loop() {
     
      if (Serial.available()) {
        CodeIn = getChar();
        if (CodeIn == '=') {EQUALS();} // The first identifier is "="
        if (CodeIn == '<') {LESSTHAN();}// The first identifier is "<"
        if (CodeIn == '?') {QUESTION();}// The first identifier is "?"
        if (CodeIn == '/') {SLASH();}// The first identifier is "/" (Annunciators)
      }
    
    }
    
    char getChar()// Get a character from the serial buffer
    {
      while(Serial.available() == 0);// wait for data
      return((char)Serial.read());// Thanks Doug
    }
    
    void EQUALS(){ // The first identifier was "="
     CodeIn = getChar(); // Get another character
      switch(CodeIn) {// Now lets find what to do with it
        case 'A'://Found the second identifier
           //Do something
        break;
         
        case 'B':
           //Do something
        break;
         
        case 'C':
           //Do something
        break;
        
             //etc etc etc
         }
    }
    
    void LESSTHAN(){ // The first identifier was "<"
    CodeIn = getChar(); // Get another character
      switch(CodeIn) {// Now lets find what to do with it
        case 'P'://Found the second identifier Turn coordinator
           
        {
        ASI = "";
        ASI += getChar();
        ASI += getChar();
        ASI += getChar();
        //tc += getChar();
       // tc += getChar();
        //tc += getChar();
        int ASI_last = ASI.toInt(); // convert it to an integer (Thanks Phill)
           
      val = ASI_last;            // reads the value of the data from FSX turn coordinator
      val = map(val, 55, 125, 10, 100); // scale it to use it with the servo ( between 0-256 for FSX turn coordinator,between 0 and 180 for servo) 
      myServo.slowmove(val,150); // sets the servo position according to the scaled value (second number is servo speed 0=slowest, 255=fastest)
      Serial.println (val); //added for troubleshooting
       
        }
        break;
         
        case 'B':
           //Do something
        break;
         
        case 'C':
           //Do something
        break;
           
             //etc etc etc
         }
    }
    
    void QUESTION(){ // The first identifier was "?"
    CodeIn = getChar(); // Get another character
      switch(CodeIn) {// Now lets find what to do with it
        case 'A'://Found the second identifier
           //Do something
        break;
         
        case 'B':
           //Do something
        break;
         
        case 'C':
           //Do something
        break;
           
             //etc etc etc
         }
    }
    void SLASH(){ // The first identifier was "/" (Annunciator)
      //Do something
    }
    image.jpg
    Thanks
    Mark

  11. #10
    25+ Posting Member
    Join Date
    Dec 2010
    Location
    Canada
    Posts
    26
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: controlling two continuous rotation servos for airspeed

    There could be a few things going on. I would suspect the below.

    If you are exerting force on the servo arm the servo will attempt to remain at the position commanded of it by the Arduino- this will buzz unless you either stop commanding the position, depower the servo, or command it somewhere where there is no load.

    There are a few ways to deal with it.

    1. Only command the servo to move IF the simulator is running, flying etc. You can do this a few different ways but an easy one I have used for the pressure panel (code at mkme.org) is to use the Avionics status. If avoinics NOT on- do not command the servo move. Easy.

    2. If no serial data command the servo to a neutral position where you don't have load on it (I dont think this will work very well as there is likely going to still be serial data sometimes so it wont help. Add this after the first IF statement completes:
    else
    {
    analogWrite (9,150);//150 would be whatever position you don't have load
    }

    3. Kill the power to the servo in series when not needed (with a relay/mosfet )

    4. Probably a dozen other ways I'm not thinking of right now.

    I would do #1 and you will be all set.

    Cheers
    Eric

Page 1 of 2 12 LastLast