Results 1 to 9 of 9
  1. #1
    10+ Posting Member
    Join Date
    Aug 2013
    Location
    Australia
    Posts
    11
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Arduino servos and sim gauges - smoothing servo movements

    Hi Everyone, I am looking for some help with the coding for gauges with the Arduino. I am using Jim's basic servo code, which works fine and is easy to edit. I have tried to put some smoothing code into the code to stop jerky servos. Yes I have a high quality servo and all that, the issue is code. The code below needs to be debugged, I know a bit about coding, I am not up to speed with all c+ syntax. It would be great to have one set of code that you can edit to your gauge requirements with Arduino and link2fs. I have made the code bold that I tried to add in. Thank you.
    /*
    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.

    This sets the complete Arduino card for "keys" input except pin 13.
    Attach a switch to any pin (except 13) and program that pin in "Multi"
    Pin 13 is used for the servo to indicate flaps.
    For this servo code to work you must tick " Everything to do with "Keys" starts with a "K" in this code.

    Code:
    */
    #include 
    Servo RPMServo;
     
    int CodeIn;// used on all serial reads
    int KpinNo; 
    int Koutpin;
    String flaps;
    String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
    void setup() 
    {
      Kstringoldstate = "111111111111111111111111111111111111111111111111111111111111111111111";
      
      for (int KoutPin = 2; KoutPin < 70; KoutPin++)// Get all the pins ready for "Keys"  
      {
        pinMode(KoutPin, INPUT);
        digitalWrite(KoutPin, HIGH);  
      }
     Serial.begin(115200); 
     pinMode(13, OUTPUT);// For the servo.
     RPMServo.attach(13);
      
    }
    void loop() {
      {KEYS();} //Check the "keys" section
      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;
         }
    }
    void LESSTHAN(){    // 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 'T'://Found the second identifier ("T" RPM)
          flaps = "";
          flaps += getChar();
          flaps += getChar();
          flaps += getChar();
          int flapsi = flaps.toInt(); // convert it to an integer (Thanks Phill)
          flapsi = (flapsi - 16);// Manual correction to suit servo zero.
          
                int pos = 0;    // variable to store the servo position 
          
       
    void loop()
    {
       for(pos = 0; pos < 180; pos += 1);  // goes from 0 degrees to 180 degrees
       {                                  // in steps of 1 degree
         RPMServo.write(flapsi / 0.06);              // tell servo to go to position in variable 'pos'
         delay(15);                       // waits 15ms for the servo to reach the position
       }
       for(pos = 180; pos>=1; pos-=1);     // goes from 180 degrees to 0 degrees
       {                                
         RPMServo.write(flapsi / 0.06);              // tell servo to go to position in variable ‘pos’
        delay(15);                       // waits 15ms for the servo to reach the position  
       
       } 
    }  
    break;
    
    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;
         }
    }
    void SLASH(){    // The first identifier was "/" (Annunciator)
      //Do something
    }
    void KEYS() 
    {
      Kstringnewstate = "";
      for (int KpinNo = 2; KpinNo < 70; KpinNo++){
        KpinStateSTR = String(digitalRead(KpinNo)); 
        KoldpinStateSTR = String(Kstringoldstate.charAt(KpinNo - 2));
        if (KpinStateSTR != KoldpinStateSTR)
        {
          if (KpinNo != 13){
          Serial.print ("D"); 
          if (KpinNo < 10) Serial.print ("0");
          Serial.print (KpinNo);
          Serial.println (KpinStateSTR);
          }
        }
        Kstringnewstate += KpinStateSTR;
      }
      Kstringoldstate = Kstringnewstate;
    }
    Last edited by Matt Olieman; 09-06-2013 at 08:03 AM.

  2. #2
    150+ Forum Groupie
    Join Date
    Apr 2011
    Location
    United States of America
    Posts
    232
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Arduino servos and sim gauges - smoothing servo movements

    Hello icarus172. Let me first state I do not have a servo nor the servo library to perform a successful build. However, I can assist you in the the theory of applying the inserted code, if, indeed, that was the intention.

    Firstly, I moved int pos = 0 to the top; I like my declarations at the top.
    Secondly, I moved your inserted void loop() to the very end and renamed it to void Servo().
    Third, a line to call the loop Servo() was created after the flaps variable.

    As a recommendation, I would reload Jim's original code and perform the steps above; it should build with no problems.

    Hope this helps,
    JM
    Code:
    #include 
    Servo RPMServo;
    int pos = 0; // variable to store the servo position 
    int CodeIn;// used on all serial reads
    int KpinNo; 
    int Koutpin;
    String flaps;
    String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
    void setup() 
    {
    Kstringoldstate = "111111111111111111111111111111111111111111111111111111111111111111111";
    
    for (int KoutPin = 2; KoutPin < 70; KoutPin++)// Get all the pins ready for "Keys" 
    {
    pinMode(KoutPin, INPUT);
    digitalWrite(KoutPin, HIGH); 
    }
    Serial.begin(115200); 
    pinMode(13, OUTPUT);// For the servo.
    RPMServo.attach(13);
    
    }
    void loop() {
    {KEYS();} //Check the "keys" section
    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;
    }
    }
    void LESSTHAN(){ // 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 'T'://Found the second identifier ("T" RPM)
    flaps = "";
    flaps += getChar();
    flaps += getChar();
    flaps += getChar();
    int flapsi = flaps.toInt(); // convert it to an integer (Thanks Phill)
    flapsi = (flapsi - 16);// Manual correction to suit servo zero.
    Servo();  // calls the loop
    
    } 
    } 
    break;
    
    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;
    }
    }
    
    void SLASH(){ // The first identifier was "/" (Annunciator)
    //Do something
    }
    void KEYS() 
    {
    Kstringnewstate = "";
    for (int KpinNo = 2; KpinNo < 70; KpinNo++){
    KpinStateSTR = String(digitalRead(KpinNo)); 
    KoldpinStateSTR = String(Kstringoldstate.charAt(KpinNo - 2));
    if (KpinStateSTR != KoldpinStateSTR)
    {
    if (KpinNo != 13){
    Serial.print ("D"); 
    if (KpinNo < 10) Serial.print ("0");
    Serial.print (KpinNo);
    Serial.println (KpinStateSTR);
    }
    }
    Kstringnewstate += KpinStateSTR;
    }
    Kstringoldstate = Kstringnewstate;
    }
    
    void Servo()
    {
    for(pos = 0; pos < 180; pos += 1); // goes from 0 degrees to 180 degrees
    { // in steps of 1 degree
    RPMServo.write(flapsi / 0.06); // tell servo to go to position in variable 'pos'
    delay(15); // waits 15ms for the servo to reach the position
    }
    for(pos = 180; pos>=1; pos-=1); // goes from 180 degrees to 0 degrees
    { 
    RPMServo.write(flapsi / 0.06); // tell servo to go to position in variable ‘pos’
    delay(15); // waits 15ms for the servo to reach the position
    }
    } // END void Servo

  3. #3
    10+ Posting Member
    Join Date
    Aug 2013
    Location
    Australia
    Posts
    11
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Arduino servos and sim gauges - smoothing servo movements

    Hi JM thank you for your assistance, it is greatly appreciated. I corrected the first line of code #include , the code still wont verify. below are the verifying errors. sketch_sep02a:2: error: 'Servo' does not name a type
    sketch_sep02a.ino: In function 'void setup()':
    sketch_sep02a:20: error: 'RPMServo' was not declared in this scope
    sketch_sep02a.ino: At global scope:
    sketch_sep02a:76: error: expected unqualified-id before 'break'
    sketch_sep02a.ino: In function 'void Servo()':
    sketch_sep02a:122: error: 'RPMServo' was not declared in this scope
    sketch_sep02a:122: error: 'flapsi' was not declared in this scope
    sketch_sep02a:127: error: 'RPMServo' was not declared in this scope
    sketch_sep02a:127: error: 'flapsi' was not declared in this scope

  4. #4
    150+ Forum Groupie
    Join Date
    Apr 2011
    Location
    United States of America
    Posts
    232
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Arduino servos and sim gauges - smoothing servo movements

    Hello again icarus172. I loaded Jim's original code and then inserted your code. I also did not realize the Servo library came default with the programmer. Nonetheless, it still failed to build. To understand why, we'll go through it together:

    error: 'RPMServo' was not declared in this scope
    #include (Servo.h)
    Servo flapsServo; was changed to Servo RPMServo;

    Also I made an error in naming the inserted loop "Servo": this is illegal since the name is a function of the Servo.h library. Oops!
    The loop was renamed to "Flaps_Servo"

    error: expected unqualified-id before 'break'

    Unknown. An error probably produced by a line not having ";" at the end to close it.

    error: 'flapsi' was not declared in this scope
    This was my fault; Since the integer variable flapsi was declared in case 'G' and not at the very top of the code, flapsi will not be recognized outside of case'G'. To correct, I declared flapsi as an integer at the top of the code; this makes it public to all loops. Then I modified the existing line from:
    int flapsi = flaps.toInt(); // convert it to an integer (Thanks Phill)
    to:
    flapsi = flaps.toInt(); // convert it to an integer (Thanks Phill)

    After correcting all of my mistakes(noted in Bold font), the code builds properly:

    Code:
    
    include "Servo.h"
    Servo RPMServo;
    
    int CodeIn;// used on all serial reads
    int KpinNo; 
    int Koutpin;
    String flaps;
    int flapsi;
    int pos = 0; // variable to store the servo position 
    String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
    
    
    void setup() 
    {
      Kstringoldstate = "111111111111111111111111111111111111111111111111111111111111111111111";
      
      for (int KoutPin = 2; KoutPin < 70; KoutPin++)// Get all the pins ready for "Keys"  
      {
        pinMode(KoutPin, INPUT);
        digitalWrite(KoutPin, HIGH);  
      }
     Serial.begin(115200); 
     pinMode(13, OUTPUT);// For the servo.
     RPMServo.attach(13);
      
    }
    
    
    void loop() {
      {KEYS();} //Check the "keys" section
      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;
         }
    }
    
    
    void LESSTHAN(){    // 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 'G'://Found the second identifier ("G" Flaps position)
          flaps = "";
          flaps += getChar();
          flaps += getChar();
          flaps += getChar();
          flapsi = flaps.toInt(); // convert it to an integer (Thanks Phill)
          flapsi = (flapsi -16);// Manual correction to suit servo zero.
          //flaps_i = flapsi;
          //flapsServo.write(flapsi * 3); // Manual fiddle to get full span of servo.
          // Note.. Using the "Map" method slows it down.
          //Serial.print(flapsi); // Used for testing
          Flaps_Servo();
        break;
         }
          
    }
    
    
    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;
         }
    }
    void SLASH(){    // The first identifier was "/" (Annunciator)
      //Do something
    }
    void KEYS() 
    {
      Kstringnewstate = "";
      for (int KpinNo = 2; KpinNo < 70; KpinNo++){
        KpinStateSTR = String(digitalRead(KpinNo)); 
        KoldpinStateSTR = String(Kstringoldstate.charAt(KpinNo - 2));
        if (KpinStateSTR != KoldpinStateSTR)
        {
          if (KpinNo != 13){
          Serial.print ("D"); 
          if (KpinNo < 10) Serial.print ("0");
          Serial.print (KpinNo);
          Serial.println (KpinStateSTR);
          }
        }
        Kstringnewstate += KpinStateSTR;
      }
      Kstringoldstate = Kstringnewstate;
    }
    
    
    void Flaps_Servo()
    {
    for(pos = 0; pos < 180; pos += 1); // goes from 0 degrees to 180 degrees
    { // in steps of 1 degree
    RPMServo.write(flapsi / 0.06); // tell servo to go to position in variable 'pos'
    delay(15); // waits 15ms for the servo to reach the position
    }
    for(pos = 180; pos>=1; pos-=1); // goes from 180 degrees to 0 degrees
    { 
    RPMServo.write(flapsi / 0.06); // tell servo to go to position in variable ‘pos’
    delay(15); // waits 15ms for the servo to reach the position
    }
    } // END void Servo
    Cheers!
    JM







  5. #5
    10+ Posting Member
    Join Date
    Aug 2013
    Location
    Australia
    Posts
    11
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Arduino servos and sim gauges - smoothing servo movements

    Thanks JM.

  6. #6
    10+ Posting Member
    Join Date
    Aug 2013
    Location
    Australia
    Posts
    11
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Arduino servos and sim gauges - smoothing servo movements

    Ok, it seems that the maths that is being used isn't quite right. I have messed with it quite a bit, the issues seems to be writing flapsi / 0.06 as one degree increase or decrease. flapsi is an integer, converting the data input to an angle. The code runs, still not smooth, because the date being sent to the servo isn't smooth due to the wrong maths. /*
    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.

    This sets the complete Arduino card for "keys" input except pin 13.
    Attach a switch to any pin (except 13) and program that pin in "Multi"
    Pin 13 is used for the servo to indicate flaps.
    For this servo code to work you must tick " Everything to do with "Keys" starts with a "K" in this code.
    Code:
    */
     
    #include 
    Servo RPMServo;
    int CodeIn;// used on all serial reads
    int KpinNo; 
    int Koutpin;
    String flaps;
    int flapsi;
    int pos = 0; // variable to store the servo position 
    String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
    
    void setup() 
    {
      Kstringoldstate = "111111111111111111111111111111111111111111111111111111111111111111111";
      
      for (int KoutPin = 2; KoutPin < 70; KoutPin++)// Get all the pins ready for "Keys"  
      {
        pinMode(KoutPin, INPUT);
        digitalWrite(KoutPin, HIGH);  
      }
     Serial.begin(115200); 
     pinMode(13, OUTPUT);// For the servo.
     RPMServo.attach(13);
      
    }
    
    void loop() {
      {KEYS();} //Check the "keys" section
      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;
         }
    }
    
    void LESSTHAN(){    // 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 'T'://Found the second identifier ("T" RPM ENG 1)
          flaps = "";
          flaps += getChar();
          flaps += getChar();
          flaps += getChar();
          flapsi = flaps.toInt(); // convert it to an integer (Thanks Phill)
          flapsi = (flapsi -16);// Manual correction to suit servo zero.
          //flaps_i = flapsi;
          //flapsServo.write(flapsi * 3); // Manual fiddle to get full span of servo.
          // Note.. Using the "Map" method slows it down.
          //Serial.print(flapsi); // Used for testing
          Flaps_Servo();
        break;
         }
          
    }
    
    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;
         }
    }
    void SLASH(){    // The first identifier was "/" (Annunciator)
      //Do something
    }
    void KEYS() 
    {
      Kstringnewstate = "";
      for (int KpinNo = 2; KpinNo < 70; KpinNo++){
        KpinStateSTR = String(digitalRead(KpinNo)); 
        KoldpinStateSTR = String(Kstringoldstate.charAt(KpinNo - 2));
        if (KpinStateSTR != KoldpinStateSTR)
        {
          if (KpinNo != 13){
          Serial.print ("D"); 
          if (KpinNo < 10) Serial.print ("0");
          Serial.print (KpinNo);
          Serial.println (KpinStateSTR);
          }
        }
        Kstringnewstate += KpinStateSTR;
      }
      Kstringoldstate = Kstringnewstate;
    }
    
    void Flaps_Servo()  // smoothing loop
    {
    for(pos = 0; pos < 180; pos += 1); // goes from 0 degrees to 180 degrees
    { // in steps of 1 degree
    RPMServo.write(flapsi / 0.06); // tell servo to go to position in variable 'pos'
    delay(15); // waits 15ms for the servo to reach the position
    }
    for(pos = 180; pos>=1; pos-=1); // goes from 180 degrees to 0 degrees
    { 
    RPMServo.write(flapsi / 0.06); // tell servo to go to position in variable ‘pos’
     delay(15);// waits 15ms for the servo to reach the position
    }
    } // END void Servo
    Last edited by Matt Olieman; 09-06-2013 at 08:02 AM.

  7. #7
    10+ Posting Member
    Join Date
    Aug 2013
    Location
    Australia
    Posts
    11
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Arduino servos and sim gauges - smoothing servo movements

    I have done some research to see how they do smooth movements in robotics.
    They use a shift over time function. I saw the squiggles of maths equations, eeek.
    It was a sin function equation. It has completely gone over my head.

  8. #8
    150+ Forum Groupie
    Join Date
    Apr 2011
    Location
    United States of America
    Posts
    232
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Arduino servos and sim gauges - smoothing servo movements

    icarus,
    Will you paste the math functions? Or, better yet, a link to the page describing the functions so I can file it in my "servo-to-do" pile.

    Thanks,
    JM

  9. #9
    10+ Posting Member
    Join Date
    Aug 2013
    Location
    Australia
    Posts
    11
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Arduino servos and sim gauges - smoothing servo movements

    Hi JM, the link is Smooth Head Rotation | Let's Make Robots! . The code here is about turning a robots head servo to look natural, it accelerates up to a point then decelerates at the end.