1. Do not share user accounts! Any account that is shared by another person will be blocked and closed. This means: we will close not only the account that is shared, but also the main account of the user who uses another person's account. We have the ability to detect account sharing, so please do not try to cheat the system. This action will take place on 04/18/2023. Read all forum rules.
    Dismiss Notice
  2. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Now a Download Plan!
  3. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  4. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

G Seat 4x servo rds 3218 + arduino

Discussion in 'DIY Motion Simulator Projects' started by Fash, Nov 4, 2020.

  1. Fash

    Fash New Member

    Joined:
    Oct 29, 2020
    Messages:
    13
    Balance:
    124Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    Arduino
    Hello everyone!!
    I finally decide to start this project.
    I am a VR player in driving games and I have always missed the information that the car transmits with the forces of gravity.

    Especially the acceleration and brake forces. But without having a rodeo bull at home.

    I have already received the parts and I am obliged to continue.

    The little list for now is:
    4x RDS 318 servo 20kgcm
    1x arduino uno

    For now I already have an error, the servos are 270º and the servo.h library only controls 180º, I will have to translate the degrees into pulse time.

    In the first tests I have done with Arduino it seems that the servo takes about 3 seconds to go from 0º to 180º. It is not something spectacular but my goal is not too ambitious.

    The idea:

    Lateral forces.- Force in the hips. One lever actuated paddle and servo on each side.

    Front and rear forces.- A paddle on the backrest and another paddle on the seat under the knee.

    Well guys this is just a beginning, I might end up having a rodeo bull at home but for now let's ride a rodeo mosquito.


    I do not fully understand the licensing process for simtools.
    You really have to pay € 49.99 to do some tests ...
    It is more expensive than the hardware I buy.

    Cheers

    Actual progress https://www.xsimulator.net/community/threads/g-seat-4x-servo-rds-3218-arduino.15442/#post-212954
    Last edited: Feb 2, 2021
  2. MarkusB

    MarkusB Well-Known Member Gold Contributor

    Joined:
    Jun 30, 2015
    Messages:
    552
    Location:
    Germany
    Balance:
    4,212Coins
    Ratings:
    +594 / 2 / -0
    My Motion Simulator:
    2DOF, 3DOF, DC motor, Arduino, Motion platform
    I was once using servos with a rotation angle of 300° and did not have any problems. There is a function named "map()", which allows you to map an input value range onto a different output value range.
    Have a look at the example sketches for servo-controlled motion simulators in the FAQ section of this forum:
    https://www.xsimulator.net/community/faq/how-to-drive-rc-servo-with-arduino-and-simtools.30/
    These examples make it really easy to get started.

    Why is that? The spec of your servo says 0.14sec / 60 degree. 3 seconds for 180° are much too slow.

    You can test SimTools for free with Live for Speed.

    Edit: Do I understand you correctly that you plan to use one of these servos per g-seat paddle? This will not work, because the motors are much to weak. Or are they just meant for a small simulator model? This will be ok of course.
    • Informative Informative x 1
    • Useful Useful x 1
    Last edited: Nov 4, 2020
  3. Fash

    Fash New Member

    Joined:
    Oct 29, 2020
    Messages:
    13
    Balance:
    124Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    Arduino
    Thanks MarkusB

    Of course they are engines and very devil electronics. They are cheap and can be used for another project or perhaps as a fine adjustment for a more powerful next stage.

    But more power is usually more noise and more electronics that heats up.

    At first I'm just looking for a small sense of pressure. I will try to reach a balance between the levers and the surface of the paddles. It could even be studied which points of the body are more sensitive to pressure.

    I approach the project as a way to unite two hobbies: electronics and simulation.

    Thanks for the info on map (), I just downloaded LFS.

    I have already tested the servo control with arduino, the next thing will be to see that arduino receives data through serial port.

    I do not bother with photos there are already thousands of arduinos and servo in the galleries.
    • Like Like x 1
  4. Fash

    Fash New Member

    Joined:
    Oct 29, 2020
    Messages:
    13
    Balance:
    124Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    Arduino
    A good dose of endorphins in my brain.

    The creature is alive !!!

    @eaorobbie sketch has helped me a lot.

    Inside I modified the map () function to adapt it to my servos.

    Something happens with the servo when there are very fast movements in the axis test panel and in LFS. It seems that the servo loses tracking and is ticking, if you move the cursor near de position, it responds again.

    I have been able to try using a servo for heave and I like the idea of using it for the seat and the pitch in the back.

    Maybe approach the assembly as something to mount on top, some cushions that you can fasten with belcro.

    I think something so cheap and portable would encourage many others to make it.
  5. MarkusB

    MarkusB Well-Known Member Gold Contributor

    Joined:
    Jun 30, 2015
    Messages:
    552
    Location:
    Germany
    Balance:
    4,212Coins
    Ratings:
    +594 / 2 / -0
    My Motion Simulator:
    2DOF, 3DOF, DC motor, Arduino, Motion platform
    • Agree Agree x 1
    • Winner Winner x 1
  6. Fash

    Fash New Member

    Joined:
    Oct 29, 2020
    Messages:
    13
    Balance:
    124Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    Arduino
    I have no words, people is awesome.
    Any idea what i have, someone has performed.
  7. Fash

    Fash New Member

    Joined:
    Oct 29, 2020
    Messages:
    13
    Balance:
    124Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    Arduino
    Hello again.

    I've been busy with work for a while.

    I will try to upload a video and an arduino code.
    It is based on the aeorobbie code.

    I use the <axis1a>R <axis1b>L <axis1c>X <axis1d>Z commands.

    R and L are the same Y axis but I differentiate them to adjust the angle of each servo.

    I found that if I use R<axis1a> .. it delays updating the servo to the next step in the loop.

    I also found that some position values can be confused by ASCII code.
    Any ideas to control those errors?

    Another thing I observe, the servo.h library the write function obviously positions the servos one by one. It is not a big problem in small changes but in jerks I think it delays the sensations

    The mechanism is rudimentary of wood to make modifications easily.

    Thank you for reading

    Attached Files:

    Last edited: Nov 30, 2020
  8. Fash

    Fash New Member

    Joined:
    Oct 29, 2020
    Messages:
    13
    Balance:
    124Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    Arduino
    Now I am printing some pieces in 3d to make the assembly firm, I will upload photos and stl.

    One question ...

    How do I get a diy license code?
  9. noorbeast

    noorbeast VR Tassie Devil Staff Member Moderator Race Director

    Joined:
    Jul 13, 2014
    Messages:
    20,551
    Occupation:
    Innovative tech specialist for NGOs
    Location:
    St Helens, Tasmania, Australia
    Balance:
    145,124Coins
    Ratings:
    +10,779 / 52 / -2
    My Motion Simulator:
    3DOF, DC motor, JRK
  10. Fash

    Fash New Member

    Joined:
    Oct 29, 2020
    Messages:
    13
    Balance:
    124Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    Arduino
    The simtools team has not qualified me for a DIY license.

    So I update the post with a lot of details.


    Concept:

    Develop a sensitive G-force feedback system that is inexpensive and simple to manufacture and assemble on a backet seat.

    Sensations:

    Surge, X-axis. An actuator on the back cushion.

    Sway, Y axis. Two actuators on the hips. An actuator to the right does the + Y thrust. A left actuator does the -Y push.

    Heave, Z axis. An actuator under the knee pad.


    Mechanics.

    Each actuator moves by double crank mechanism, converting the rotation of a servo into linear thrust motion on a paddle that is hinged to the seat frame.

    Photo of the montage in 3D design.

    Minimum Position
    SERRVO POS1.JPG

    Maximun position

    SERRVO POS2.JPG
    Control.
    The XYZ coordinates that simtools sends through serial communication are received through arduino.

    In principle, the sketch that @aerobbie spread was studied, and I rewrote all the code according to my needs.

    Basically simtools sends <axis1> X <axis2> Y <axis3> Z.
    Arduino receives those byte-size parameters and positions the servos at the corresponding angle within a set maximum and minimum.

    Paste arduino code.


    Code:
    
    //********************************************************************************************
    // RC Model Servo
    // Written By FASH
    BASED IN EAOROBBIE (Robert Lindsay)
    // For free use for Sim Tool Motion Software
    //********************************************************************************************
    
    //Modificado FASH 9.11.2020
    //SIMTOOLS  CHAR A ENTERO SERVO EN PULSOS
    //FUERZAS XYZ DIRECTAMENTE AL SERVO
    //FORMATO DE PUERTO SERIE <axis1a>X<axis1b>Y<axis1c>Z
    //CALIBRATION OF SERVOS STORED IN EEPROM
    
    #include <Servo.h>
    #include <EEPROM.h>
    
    
     const int s_add_Y_max=0;
     const int s_add_Y_min=2;
     const int s_add_X_max=4;
     const int s_add_X_min=6;
     const int s_add_Z_max=8;
     const int s_add_Z_min=10;
    
     
      Servo myservo1;    // create servo object to control a servo
      Servo myservo2;    // create servo object to control a servo
      Servo myservo3;    // create servo object to control a servo
      Servo myservo4;    // create servo object to control a servo
    
      char kind_of_data; // to capture which servo needs to be move
                         //servo.h says // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
                         //then i use pulse to get more resolution
     
     
      //SWAY
      int Y_min_ang= 40    *6.87 + 544;//Coverted to pulse //set limits of movement servo has 270º and servo.h assumes max angle is 180º
      int Y_max_ang= 160   *6.87 + 544;                    // default limits pulse 544 to 2400 in 180º then center pos is 1472 us
                                                          // in 270º servo center is same but to get +-90º  (2400 - 544)/270= 6.87us pulse/deg
      //SURGE                                                    // 1472 + 6.8*90 = 2090
      int X_min_ang= 37    *6.87 + 544;
      int X_max_ang= 203   *6.87 + 544;
      //HEAVE
    
      int Z_min_ang= 0     *6.87 + 544;
      int Z_max_ang= 270   *6.87 + 544;
     
     
                             
      int val_YLSP =  Y_max_ang; //+ (Y_max_ang - Y_min_ang)/2;   // set the intial Left Servo Position to centre FUERZA -Y SWAY
      int val_YRSP = Y_min_ang;// + (Y_max_ang - Y_min_ang)/2;   // set the intial Right Servo Position to centre FUERZA Y SWAY
      int val_ZSP =  Z_min_ang + (Z_max_ang - Z_min_ang)/2;   // set the intial Left Servo Position to centre FUERZA Z HEAVE
      int val_XSP =  X_min_ang +(X_max_ang - X_min_ang)/2;   // set the intial Right Servo Position to centre FUERZA X SURGE
     
      String val_ST;   // Valor que envia simtools
      String cmd_ST= "";
    /*void read_EEPROM(){
     
            Y_max_ang= EEPROM.read(s_add_Y_max) *6.87 + 544;
            Y_min_ang= EEPROM.read(s_add_Y_max) *6.87 + 544;
            X_max_ang= EEPROM.read(s_add_X_max) *6.87 + 544;
            X_min_ang= EEPROM.read(s_add_X_max) *6.87 + 544;
            Z_max_ang= EEPROM.read(s_add_Z_max) *6.87 + 544;
            Z_min_ang= EEPROM.read(s_add_Z_max) *6.87 + 544;
    }*/
    void setup()
    {
    
     
     
    
         // read_EEPROM();
          myservo1.attach(4);      //Y attaches the servo on pin 5 to the servo object
          myservo2.attach(5);      //Y attaches the servo on pin 4 to the servo object
          myservo3.attach(6);      //X attaches the servo on pin 5 to the servo object
          myservo4.attach(7);      //Z attaches the servo on pin 4 to the servo object
     
          myservo1.write(val_YRSP);  // sets the servo position according to the scaled value
          myservo2.write(val_YLSP);   // set the servo position according to the scaled value
          myservo3.write(val_XSP);  // sets the servo position according to the scaled value
          myservo4.write(val_ZSP);   // set the servo position according to the scaled value
          Serial.begin(19200);      // opens serial port at a baud rate of 38400
    }
     
    void loop()
    {
     
          //****************************** READ DATA FROM SERIAL ******************************
          while (Serial.available() > 0)
          {
    
              kind_of_data = Serial.read();
     
              if (isDigit(kind_of_data)) {
                    val_ST += kind_of_data;
                   
              }
             
              if (kind_of_data == 'Y' )   Read_YServo();
               
              if (kind_of_data == 'Z' )   Read_ZServo();
       
              if (kind_of_data == 'X' )   Read_XServo();    
           
             
           //MOVE SERVOS TO READED POSITION
              myservo1.write(val_YRSP);                  // sets the servo position according to the scaled value
              myservo2.write(val_YLSP);                  // sets the servo position according to the scaled value
              myservo3.write(val_ZSP);                  // sets the servo position according to the scaled value
              myservo4.write(val_XSP);                  // sets the servo position according to the scaled value
             
          }
    }
    
    void Read_XServo()
    {
            int XServoPos = 0;
            XServoPos=val_ST.toInt();
            val_ST="";
            int m =X_min_ang ;
            int M= X_max_ang ; // THIS FIX PROBLEM MAP() READS GLOBAL VAR AND ALLWAYS RETURNS 2290, EXTRANGE PROBLEM val_XSP = map(XServoPos, 0, 255,  X_min_ang, X_max_ang);
    
    
            if ((XServoPos > -1) && (XServoPos<256) )
            {
                  val_XSP = map(XServoPos, 0, 255, m, M);
                  Serial.println("Posicion Cmd X: "+ String(XServoPos));
                  Serial.println("Valor pulso Servo X: "+ String(val_XSP));
            }
    }
    
    void Read_YServo()
    
    {
            //THIS CASE SWAY IS HANDLED WITH TWO SERVOS +Y AND -Y
              int RServoPos = 0;
              RServoPos=val_ST.toInt();
              int m =Y_min_ang ;
              int M= Y_max_ang ;
    
              if ((RServoPos > -1) && (RServoPos<256) )
              {
                  if (RServoPos <128){ RServoPos = 127;} //Limito a medio recorrido del eje
                  val_YRSP = map(RServoPos, 127, 255, m, M);
                  Serial.println("Posicion Cmd R: "+ String(RServoPos));
                  Serial.println("Valor pulso Servo R: "+ String(val_YRSP));
              }
             
              int LServoPos = 0;
              LServoPos=val_ST.toInt();
              val_ST="";
    
              if ((LServoPos > -1) && (LServoPos<256) )
              {
                  if (LServoPos >126){ LServoPos = 127;} //Limito a medio recorrido del eje
                  val_YLSP = map(LServoPos, 0, 127 , M, m);
                  Serial.println("Posicion Cmd L: " + String(LServoPos));
                  Serial.println("Valor pulso Servo L: " + String(val_YLSP));            
              }
    }
    
    void Read_ZServo()
    {
    
            int ZServoPos = 0;
            ZServoPos=val_ST.toInt();
            val_ST="";
            int m =Z_min_ang ;
            int M= Z_max_ang ;
            if ((ZServoPos > -1) && (ZServoPos<256) )
            {
                  val_ZSP = map(ZServoPos, 0, 255,  m, M);
                  Serial.println("Posicion Cmd Z: " + String(ZServoPos));
                  Serial.println("Valor pulso Servo Z: " + String (val_ZSP));
            }
    }
    
    WIRING

    proteus.JPG

    Test and travel adjustments.

    Each axis is associated with a servo and each servo moves in an interval, the minimum angle corresponds to the value 0 of the axis and the maximum angle corresponds to the value 255.
    Using the serial terminal of the arduino IDE, simtools communication is simulated and the maximum and minimum value of the corresponding variables is set in the sketch. These variables are used in the mapping function.


    Mounting the elements to the seat.

    Left hip paddle detail
    1612290229431.jpg

    Left sway servo
    1612290229346.jpg

    1612290229282.jpg


    Minimum position of servos
    1612290229190.jpg



    Maximun position of servo


    1612290229031.jpg

    Post in progress, I will edit and post wiring and more details

    Attached Files:

    • Like Like x 2
  11. Fash

    Fash New Member

    Joined:
    Oct 29, 2020
    Messages:
    13
    Balance:
    124Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    Arduino
    The failures are also posted of course.

    The servo profiles reach the seat frame before the end of their travel.

    This has happened to me twice, while I was distracted modifying the code, adjusting the travel limits ... the servo was forced on the seat and it gets quite hot.
    The outcome is two fried servos. At least they are very cheap, but if I keep cooking servos this will become more expensive than a platform with a wiper.

    There is a Spanish saying that says ..
    "Everything happens to him who cooks and kneads."

    My boss listens to that saying a lot.

    Am I the only one who has fun burning electronics?
    Should I ask for medical help?

    Who cares, I'll have to buy a fire extinguisher.
    • Funny Funny x 1
  12. RacingMat

    RacingMat Well-Known Member Gold Contributor

    Joined:
    Feb 22, 2013
    Messages:
    2,234
    Location:
    Marseille - FRANCE
    Balance:
    20,895Coins
    Ratings:
    +2,084 / 21 / -2
    My Motion Simulator:
    2DOF, DC motor, Arduino
    no, you're not alone @Pit has been well known for his penchant of burning motomonsters by batch! ;)
  13. Fash

    Fash New Member

    Joined:
    Oct 29, 2020
    Messages:
    13
    Balance:
    124Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    Arduino
    More code improves

    added functions to convert rotational to lineal movements
    added start comands for max and min angles of axis

    max angle X <0 to 270>Mx; min angle <0 to 270> mx
    max angle Y <0 to 270>My; min angle <0 to 270> my
    max angle Z <0 to 270>Mz; min angle <0 to 270> mz
    i.e. 1mx 270Mx 1my 270My 1mz 270Mz



    This version uses servo.h, it moves servos one by one

    Code:
    //********************************************************************************************
    //FLYPT-ino.ino
    //RC Model Servo
    // Written By FASH
    //BASED IN EAOROBBIE (Robert Lindsay)
    // For free use for FLYPT MOVER Software
    //WITH servo.h
    //********************************************************************************************
    
    //Modificado FASH 11.2.2021
    //SIMTOOLS FLYPT  CHAR A ENTERO SERVO EN PULSOS
    //FUERZAS XYZ DIRECTAMENTE AL SERVO
    //FORMATO DE PUERTO SERIE <axis1a>X<axis1b>Y<axis1c>Z
    //CALIBRATION OF SERVOS STORED IN EEPROM
    
    #include <Servo.h>
    #include <math.h>
    
     const double raiz2= sqrt(2);
      Servo myservo1;    // create servo object to control a servo
      Servo myservo2;    // create servo object to control a servo
      Servo myservo3;    // create servo object to control a servo
      Servo myservo4;    // create servo object to control a servo
    
      char serial_data; // to capture which servo needs to be move
                         //servo.h says // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
                         //then i use pulse to get more resolution
     
    
    
      //SERVOS 270º
     
      //SWAY
      int Y_min_ang =58;
      int Y_max_ang =170;
                                                     
      //SURGE                                              
      int X_min_ang =90;
      int X_max_ang =90;
     
      //HEAVE
      int Z_min_ang =90;
      int Z_max_ang =90;
     
     
                         
      int val_YLSP ;
      int val_YRSP ;
      int val_ZSP  ;
      int val_XSP  ;
     
      String val_ST;   // Valor que envia simtools
      String cmd_ST;
    
    void setup()
    {
    
          myservo1.attach(3);      //Y attaches the servo on pin 5 to the servo object
          myservo2.attach(5);      //Y attaches the servo on pin 4 to the servo object
          myservo3.attach(6);      //X attaches the servo on pin 5 to the servo object
          myservo4.attach(9);      //Z attaches the servo on pin 4 to the servo object
    
          in_servo();
    
          myservo1.write(val_YRSP);  // sets the servo position according to the scaled value
          myservo2.write(val_YLSP);   // set the servo position according to the scaled value
          myservo3.write(val_XSP);  // sets the servo position according to the scaled value
          myservo4.write(val_ZSP);   // set the servo position according to the scaled value
          Serial.begin(500000);      // opens serial port at a baud rate of 500000
    }
    void in_servo()
    {
          val_YLSP =  ang2pulse(Y_max_ang);                               // set the intial Left Servo Position to centre FUERZA -Y SWAY
          val_YRSP =  ang2pulse(Y_max_ang );                              // set the intial Right Servo Position to centre FUERZA Y SWAY
          val_ZSP  =  ang2pulse(Z_min_ang + (Z_max_ang - Z_min_ang)/2);   // set the intial Left Servo Position to centre FUERZA Z HEAVE
          val_XSP  =  ang2pulse(X_min_ang + (X_max_ang - X_min_ang)/2);   // set the intial Right Servo Position to centre FUERZA X SURGE
          myservo1.write(val_YRSP);                                       // sets the servo position according to the scaled value
          myservo2.write(val_YLSP);                                       // set the servo position according to the scaled value
       //   myservo3.write(val_XSP);                                        // sets the servo position according to the scaled value
        //  myservo4.write(val_ZSP);                                        // set the servo position according to the scaled value
    
    }
    
    int Lim_Servo(String ang)
    {
        int a = ang.toInt();
        if ((a>= 0) && (a<=270))
        {
          Serial.println("Establecido limite " + cmd_ST + " : " + ang);
          val_ST="";
          cmd_ST="";
          return a;
     
        }
     
     
    }
    
    void Move_XServo()
    {
            int XServoPos = 0;
            XServoPos=val_ST.toInt();
            val_ST="";
            cmd_ST="";
            int m =X_min_ang ;
            int M= X_max_ang ; // THIS FIX PROBLEM MAP() READS GLOBAL VAR AND ALLWAYS RETURNS 2290, EXTRANGE PROBLEM val_XSP = map(XServoPos, 0, 255,  X_min_ang, X_max_ang);
    
    
            if ((XServoPos >= 0) && (XServoPos <=255) )
            {
                  val_XSP = pos2pulse(map(XServoPos, 0, 255, m, M));
                  Serial.println("Posicion Cmd X: "+ String(XServoPos));
                  Serial.println("Valor pulso Servo X: "+ String(val_XSP));
            }
    }
    
    
    void Move_YServo()
    
    {
            //THIS CASE SWAY IS HANDLED WITH TWO SERVOS +Y AND -Y
              int RServoPos = 0;
              RServoPos=pos_line2ang(val_ST.toInt());
         
              int m =Y_min_ang ;
              int M= Y_max_ang ;
    
              if ((RServoPos >=0 ) && (RServoPos<=255) )
              {
                  if (RServoPos <110){ RServoPos = 110;} //Limito a medio recorrido del eje
                  val_YRSP =  pos2pulse(map(RServoPos, 110, 255, M, m));
                  Serial.println("Posicion Cmd R: "+ String(RServoPos));
                  Serial.println("Valor pulso Servo R: "+ String(val_YRSP));
              myservo1.write(val_YRSP);
              }
         
              int LServoPos = 0;
              LServoPos=pos_line2ang(val_ST.toInt());
         
         
       
              if ((LServoPos >= 0) && (LServoPos <= 255) )
              {
                  if (LServoPos >144){ LServoPos = 144;} //Limito a medio recorrido del eje
                  val_YLSP = pos2pulse( map(LServoPos, 0, 144 ,m, M));
                  Serial.println("Posicion Cmd L: " + String(LServoPos));
                  Serial.println("Valor pulso Servo L: " + String(val_YLSP));        
              myservo2.write(val_YLSP);
              }
         
         
    }
    
    void Move_ZServo()
    {
    
            int ZServoPos = 0;
            ZServoPos=val_ST.toInt();
            val_ST="";
            cmd_ST="";
            int m =Z_min_ang ;
            int M= Z_max_ang ;
            if ((ZServoPos >=0 ) && (ZServoPos<=255) )
            {
                  val_ZSP = pos2pulse(map(ZServoPos, 0, 255,  m, M));
                  Serial.println("Posicion Cmd Z: " + String(ZServoPos));
                  Serial.println("Valor pulso Servo Z: " + String (val_ZSP));
            }
    }
    
    int pos_line2ang(double p_lin){
    
     
      double p_ang_d;
      if ((p_lin >= 0)&&  (p_lin <= 255))
     
        {
     
          p_ang_d= acos(double (1-(p_lin/127.5)));
    
          return int((p_ang_d/M_PI)*255);
    
     
        }
     
      }
    
    int ang2p_ang(int ang){
     
      return (map(ang,0,270,0, 255));
     
      }
    int pos2pulse(int pos){
     
      return (map(pos,0,255,544, 2400));
     
      }
    
    int ang2pulse(int ang){
     
      return (map(ang,0,270,544, 2400));
     
      }
    
     
    void loop()
    {
     
          //****************************** READ DATA FROM SERIAL ******************************
          while (Serial.available() > 1)
          {
    
              serial_data = Serial.read();
     
              if (isDigit(serial_data))
              {
                    val_ST += serial_data;
                    cmd_ST="";
              }else //if (val_ST !="")
                    {
             
                    cmd_ST = serial_data;
           
                    }
              if (cmd_ST=="Y"){
                    Move_YServo();
                    val_ST="";
                    cmd_ST="";
                    }
           
              if (cmd_ST=="Z"){   Move_ZServo(); }
     
              if (cmd_ST=="X"){   Move_XServo(); }
    
              if (cmd_ST=="Mx"){  X_max_ang = Lim_Servo(val_ST); }
    
              if (cmd_ST=="mx"){  X_min_ang = Lim_Servo(val_ST); }
           
              if (cmd_ST=="My"){  Y_max_ang = Lim_Servo(val_ST); }
    
              if (cmd_ST=="my"){  Y_min_ang = Lim_Servo(val_ST); }
    
              if (cmd_ST=="Mz"){  Z_max_ang = Lim_Servo(val_ST); }
    
              if (cmd_ST=="mz"){  Z_min_ang = Lim_Servo(val_ST); }
           
         
           //MOVE SERVOS TO READED POSITION
         
             // myservo2.write(val_YLSP); // sets the servo position according to the scaled value
             //Serial.println(val_YLSP);
             // myservo1.write(val_YRSP); // sets the servo position according to the scaled value
             //Serial.println(val_YRSP);
             // myservo3.write(val_ZSP);                  // sets the servo position according to the scaled value
             // myservo4.write(val_XSP);                  // sets the servo position according to the scaled value
         
          }
    }
    this is de same program usin RCarduinoFastLib.h, this operates servos at same time.


    Code:
    //********************************************************************************************
    //adapted to RCArduinoFastLib.h
    // RC Model Servo
    // Written By FASH
    //BASED IN EAOROBBIE (Robert Lindsay)
    // For free use for FLYPT MOVER Software
    //********************************************************************************************
    
    //Modificado FASH 11.2.2021
    //SIMTOOLS FLYPT  CHAR A ENTERO SERVO EN PULSOS
    //FUERZAS XYZ DIRECTAMENTE AL SERVO
    //FORMATO DE PUERTO SERIE <axis1a>X<axis1b>Y<axis1c>Z
    //CALIBRATION OF SERVOS STORED IN EEPROM
    
    //#include <Servo.h>
    #include <math.h>
    #include <RCArduinoFastLib.h>
    
    #define SERVO_FRAME_SPACE  5 //numero de servos
    
    
     #define servo1 1
     #define servo2 2
     #define servo3 3
     #define servo4 4
    
     #define servoPin1 5
     #define servoPin2 6
     #define servoPin3 7
     #define servoPin4 8
     const double raiz2= sqrt(2);
    
      char serial_data; // to capture which servo needs to be move
                         //servo.h says // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds
                         //then i use pulse to get more resolution
     
    
    
      //SERVOS 270º
     
      //SWAY
     
      int Y_min_ang =58;
      int Y_max_ang =170;
                                                    
      //SURGE                                              
      int X_min_ang =50;
      int X_max_ang =210;
     
      //HEAVE
      int Z_min_ang =50;
      int Z_max_ang =210;
     
     
                          
      int val_YLSP ;
      int val_YRSP ;
      int val_ZSP  ;
      int val_XSP  ;
     
      String val_ST;   // Valor que envia simtools
      String cmd_ST;
    
    void setup()
    {
    
         /* myservo1.attach(5);      //Y attaches the servo on pin 5 to the servo object
          myservo2.attach(6);      //Y attaches the servo on pin 4 to the servo object
          myservo3.attach(8);      //X attaches the servo on pin 5 to the servo object
          myservo4.attach(9);      //Z attaches the servo on pin 4 to the servo object
          */
    
          CRCArduinoFastServos::attach(servo1,servoPin1);
          CRCArduinoFastServos::attach(servo2,servoPin2);
          CRCArduinoFastServos::attach(servo3,servoPin3);
          CRCArduinoFastServos::attach(servo4,servoPin4);
     
          CRCArduinoFastServos::setFrameSpaceA(SERVO_FRAME_SPACE,7*2000);
     
          in_servo();
          CRCArduinoFastServos::begin();
          /*myservo1.write(val_YRSP);  // sets the servo position according to the scaled value
          myservo2.write(val_YLSP);   // set the servo position according to the scaled value
          myservo3.write(val_XSP);  // sets the servo position according to the scaled value
          myservo4.write(val_ZSP);   // set the servo position according to the scaled value
          */
    
     
          Serial.begin(38400);      // opens serial port at a baud rate of 500000
    }
    void in_servo()
    {
          val_YLSP =  ang2pulse(Y_max_ang);                               // set the intial Left Servo Position to centre FUERZA -Y SWAY
          val_YRSP =  ang2pulse(Y_max_ang );                              // set the intial Right Servo Position to centre FUERZA Y SWAY
          val_ZSP  =  ang2pulse(Z_min_ang + (Z_max_ang - Z_min_ang)/2);   // set the intial Left Servo Position to centre FUERZA Z HEAVE
          val_XSP  =  ang2pulse(X_min_ang + (X_max_ang - X_min_ang)/2);   // set the intial Right Servo Position to centre FUERZA X SURGE
          //myservo1.write(val_YRSP);                                       // sets the servo position according to the scaled value
          //myservo2.write(val_YLSP);                                       // set the servo position according to the scaled value
       //   myservo3.write(val_XSP);                                        // sets the servo position according to the scaled value
        //  myservo4.write(val_ZSP);                                        // set the servo position according to the scaled value
    
    }
    
    int Lim_Servo(String ang)
    {
        int a = ang.toInt();
        if ((a>= 0) && (a<=270))
        {
          Serial.println("Establecido limite " + cmd_ST + " : " + ang);
          val_ST="";
          cmd_ST="";
          return a;
     
        }
     
    
    }
    
    void Move_XServo()
    {
            int XServoPos = 0;
            XServoPos=val_ST.toInt();
            val_ST="";
            cmd_ST="";
            int m =X_min_ang ;
            int M= X_max_ang ; // THIS FIX PROBLEM MAP() READS GLOBAL VAR AND ALLWAYS RETURNS 2290, EXTRANGE PROBLEM val_XSP = map(XServoPos, 0, 255,  X_min_ang, X_max_ang);
    
    
            if ((XServoPos >= 0) && (XServoPos <=255) )
            {
                  val_XSP = pos2pulse(map(XServoPos, 0, 255, m, M));
                  Serial.println("Posicion Cmd X: "+ String(XServoPos));
                  Serial.println("Valor pulso Servo X: "+ String(val_XSP));
            }
    }
    
    
    void Move_YServo()
    
    {
            //THIS CASE SWAY IS HANDLED WITH TWO SERVOS +Y AND -Y
              int RServoPos = 0;
              RServoPos=pos_line2ang(val_ST.toInt());
        
              int m =Y_min_ang ;
              int M= Y_max_ang ;
    
              if ((RServoPos >=0 ) && (RServoPos<=255) )
              {
                  if (RServoPos <110){ RServoPos = 110;} //Limito a medio recorrido del eje
                  val_YRSP =  pos2pulse(map(RServoPos, 110, 255, M, m));
                  Serial.println("Posicion Cmd R: "+ String(RServoPos));
                  Serial.println("Valor pulso Servo R: "+ String(val_YRSP));
        
              }
        
              int LServoPos = 0;
              LServoPos=pos_line2ang(val_ST.toInt());
        
        
        
              if ((LServoPos >= 0) && (LServoPos <= 255) )
              {
                  if (LServoPos >144){ LServoPos = 144;} //Limito a medio recorrido del eje
                  val_YLSP = pos2pulse( map(LServoPos, 0, 144 ,m, M));
                  Serial.println("Posicion Cmd L: " + String(LServoPos));
                  Serial.println("Valor pulso Servo L: " + String(val_YLSP));        
        
              }
        
        
    }
    
    void Move_ZServo()
    {
    
            int ZServoPos = 0;
            ZServoPos=val_ST.toInt();
            val_ST="";
            cmd_ST="";
            int m =Z_min_ang ;
            int M= Z_max_ang ;
            if ((ZServoPos >=0 ) && (ZServoPos<=255) )
            {
                  val_ZSP = pos2pulse(map(ZServoPos, 0, 255,  m, M));
                  Serial.println("Posicion Cmd Z: " + String(ZServoPos));
                  Serial.println("Valor pulso Servo Z: " + String (val_ZSP));
            }
    }
    
    int pos_line2ang(double p_lin){
    
    
      double p_ang_d;
      if ((p_lin >= 0)&&  (p_lin <= 255))
     
        {
     
          p_ang_d= acos(double (1-(p_lin/127.5)));
    
          return int((p_ang_d/M_PI)*255);
    
     
        }
     
      }
    
    int ang2p_ang(int ang){
     
      return (map(ang,0,270,0, 255));
     
      }
    int pos2pulse(int pos){
     
      return (map(pos,0,255,544, 2400));
     
      }
    
    int ang2pulse(int ang){
     
      return (map(ang,0,270,544, 2400));
     
      }
    
    
    void loop()
    {
     
          //****************************** READ DATA FROM SERIAL ******************************
          while (Serial.available() > 1)
          {
    
              serial_data = Serial.read();
     
              if (isDigit(serial_data))
              {
                    val_ST += serial_data;
                    cmd_ST="";
              }else //if (val_ST !="")
                    {
              
                    cmd_ST = serial_data;
          
                    }
              if (cmd_ST=="Y"){
                    Move_YServo();
                    val_ST="";
                    cmd_ST="";
                    }
            
              if (cmd_ST=="Z"){   Move_ZServo(); }
     
              if (cmd_ST=="X"){   Move_XServo(); }
    
              if (cmd_ST=="Mx"){  X_max_ang = Lim_Servo(val_ST); }
    
              if (cmd_ST=="mx"){  X_min_ang = Lim_Servo(val_ST); }
          
              if (cmd_ST=="My"){  Y_max_ang = Lim_Servo(val_ST); }
    
              if (cmd_ST=="my"){  Y_min_ang = Lim_Servo(val_ST); }
    
              if (cmd_ST=="Mz"){  Z_max_ang = Lim_Servo(val_ST); }
    
              if (cmd_ST=="mz"){  Z_min_ang = Lim_Servo(val_ST); }
          
        
           //MOVE SERVOS TO READED POSITION
    
    
              CRCArduinoFastServos::writeMicroseconds(servo1,uint16_t (val_YLSP));
              CRCArduinoFastServos::writeMicroseconds(servo2,uint16_t (val_YRSP));
              CRCArduinoFastServos::writeMicroseconds(servo3,uint16_t (val_ZSP));
              CRCArduinoFastServos::writeMicroseconds(servo4,uint16_t (val_XSP));
        
        
             // myservo2.write(val_YLSP); // sets the servo position according to the scaled value
             Serial.println(val_YLSP);
             // myservo1.write(val_YRSP); // sets the servo position according to the scaled value
             Serial.println(val_YRSP);
             // myservo3.write(val_ZSP);                  // sets the servo position according to the scaled value
             // myservo4.write(val_XSP);                  // sets the servo position according to the scaled value
        
          }
    }
    


    This is the config for Flypt. uploaded fash.mover.rar

    Flypt.JPG

    Src PCars2.JPG


    Src Assetto.JPG


    Dir Surge.JPG


    Dir Sway.JPG


    Dir Heave.JPG

    OUT Serial.JPG

    Attached Files:

    • Like Like x 1
    Last edited: Feb 14, 2021