Arduino control for Servo

bobbyboy1962 Nov 7, 2017

  1. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    YES! success so far with my attempt at arduino controlled servos for turnouts. I am just posting a video to youtube showing what i have. Bobbyboy1962. Can i post the video here for all to see?
     
    Atani likes this.
  2. RBrodzinsky

    RBrodzinsky November 18, 2022 Staff Member TrainBoard Supporter In Memoriam

    5,685
    2,786
    98
    Yes, just post the YouTube link, and the forum software will embed it automatically
     
  3. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    this is the link i think,
     
  4. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    now trying to figure out how to make the servos move slower in the arduino sketch.
     
  5. Xmtrman

    Xmtrman TrainBoard Member

    155
    60
    13
    Something like this (from my code):
    Definitions:
    ChServo -->an array of servo objects, as defined in the standard Arduino servo library, each associated with its output pin
    pinnum --> the index number of one of those servo objects within the array
    Dly --> delay value, expressed in milliseconds
    Assumption:
    The end-points of your servo are 0(zero) to 180 degrees.
    These are the numbers in the first line conditions of the 'for' loop;
    adjust or externally define as necessary.

    Code fragment:

    for (int i=0; i < 181; i++) {
    ChServo[pinnum].write(i);
    delay(Dly);
    }


    Setting 'Dly' to zero would run the servo at close to full speed.
    Setting it to 1000 would take a bit over 3 minutes to go from end-to-end.

    I hope it helps.
     
  6. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    // MRH 6 Switched 6 Servos with Pushbuttons & LED Indicators
    // G. Bunza 2016
    //
    #include <SoftwareServo.h>
    #define numpins 6 // Number of Servos
    SoftwareServo servo[numpins] ;

    int i,k,l;
    int pins [ ]= {14,15,16,17,18,19}; // Pushbutton/LED pins
    int spins [ ]= {2,3,4,5,6,7}; // Servo pins
    int sstart [ ]= {25,59,25,25,25,25}; // Servo Start Positions
    int sstop [ ]= {160,94,160,160,160,160}; // Servo Stop Positions
    boolean pinval [ ]= { true,true,true,true,true,true }; // Servo State
    //
    void setup() {
    for (i=0; i<numpins; i++) {
    servo.attach (spins); // Set up servo controls
    servo.write(sstart); // Set each servo to start position
    }
    pinMode(pins,OUTPUT); // Initialize PB/LED pins
    digitalWrite(pins,HIGH);
    }
    void loop() {
    SoftwareServo::refresh(); // Must Refresh the Internal Servo Control

    for (i=0; i<numpins; i++) {
    pinMode (pins,INPUT_PULLUP);
    if (digitalRead(pins)==LOW) { // Check if a Pushbutton is pressed
    pinval=!pinval; // Assume only one at a time
    if (pinval==true) servo.write(sstart);
    else servo.write(sstop);
    while (digitalRead(pins)==LOW) {SoftwareServo::refresh(); } // Wait until PB is released
    }
    pinMode(pins,OUTPUT); // Now go back to maintaining LEDs
    digitalWrite(pins,pinval);
    }
    }


    So, first off thank you for the help. This is the code i am using and i adjust the sstart and sstop variables to suit. How would i add in your code or do i need to add it all or only the delay. Thanks again, Bob
     
  7. Xmtrman

    Xmtrman TrainBoard Member

    155
    60
    13
    First off make sure your existing code is saved so you don't lose it.
    The easiest way to do that is to open it in your editor then immediately use "Save AS" to save it with a different name.
    Then edit this re-named file as follows---

    After your existing line:
    "boolean pinval [ ]= { true,true,true,true,true,true }; // Servo State"

    Add this line:
    int Dly = 10; // This is the delay, in milliseconds, between each 1 degree step of servo travel.
    // Change this value to adjust. Positive numbers only. '0' equals full speed. Higher = slower



    Then where your code now reads:

    "if (pinval==true) servo.write(sstart);
    else servo.write(sstop);"


    Delete those two lines and insert:

    if (pinval==true) { //We are located at sstop and need to go to sstart
    for (int i=sstop; i > (sstart-1); i = i - 1) { //Decrement 1 degree at a time from our position 'i'. Loop until we get to sstart
    servo.write(i);
    delay(Dly);
    } else { //We are located at sstart and need to go to sstop
    for (int i=sstart; i < (sstop+1); i = i + 1) { //Increment 1 degree at a time from our position 'i'. Loop until we get to sstop
    servo.write(i);
    delay(Dly);
    }
    //Note that the LEDs won't change until the servo completes its travel



    Caveats:
    -This code assumes that the value of the servo start position in degrees (sstart) is less than the stop position (sstop).
    If your physical mounting position of the servo should reverse that relationship then this code will NOT work and a new approach would be necessary.

    - I don't have the tools to test this code. I broke down my Arduino workstation and put it away before I went into the hospital for knee replacement two weeks ago.

    - Because of that surgery, I am taking pain medication that may or may not have interfered with my ability to write code. ;)
    (That's why I had you save your existing code first!)

    - I'm not familiar with the SoftwareServo library so this code is based entirely on how I perceive it works.

    I'm gonna need a nap now.

    Have fun!
     
  8. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    Wow. Thank you very much. I will try this and let you know how it turns out. Now go get some rest, Bob
     
  9. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    Hello sir. I finally had a chance to add your code and when i verify i get an error msg of, request for member 'write' in 'servo', which is of non-class type 'SoftwareServo [6]' any idea why or what im doing wrong. I copy and pasted the code off of here, thanks again
     
  10. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    Arduino: 1.8.4 (Windows 7), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

    C:\Users\bob\Documents\Arduino\Sketches\Switched_6_Servos_my_one_servo_try_with_delay\Switched_6_Servos_my_one_servo_try_with_delay.ino: In function 'void loop()':

    Switched_6_Servos_my_one_servo_try_with_delay:34: error: request for member 'write' in 'servo', which is of non-class type 'SoftwareServo [6]'

    servo.write(i);

    ^

    Switched_6_Servos_my_one_servo_try_with_delay:36: error: expected '}' before 'else'

    } else { //We are located at sstart and need to go to sstop

    ^

    Switched_6_Servos_my_one_servo_try_with_delay:48: error: expected '}' at end of input

    }

    ^

    exit status 1
    request for member 'write' in 'servo', which is of non-class type 'SoftwareServo [6]'

    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.
     
  11. Xmtrman

    Xmtrman TrainBoard Member

    155
    60
    13
    Since servo.write(value) is in your original code, I do not know why you would be getting that error message.
    Make sure that you paste my code in two pieces, exactly where I indicated.

    The first block
    int Dly = 10; // This is the delay, in milliseconds, between each 1 degree step of servo travel.
    // Change this value to adjust. Positive numbers only. '0' equals full speed. Higher = slower

    goes in one place as indicated.

    The second block
    if (pinval==true) { //We are located at sstop and need to go to sstart
    for (int i=sstop; i > (sstart-1); i = i - 1) { //Decrement 1 degree at a time from our position 'i'. Loop until we get to sstart
    servo.write(i);
    delay(Dly);
    } else { //We are located at sstart and need to go to sstop
    for (int i=sstart; i < (sstop+1); i = i + 1) { //Increment 1 degree at a time from our position 'i'. Loop until we get to sstop
    servo.write(i);
    delay(Dly);
    }
    //Note that the LEDs won't change until the servo completes its travel

    goes in a different place and replaces the two lines indicated.

    If you pasted it all as one block it would generate errors.
    The sequence that things execute in is important.
     
  12. papahnash

    papahnash TrainBoard Member

    337
    69
    17
    Nice work, bobbyboy. As I understand the video, you are mechanically actuating 2 micro switched with servos controlled by a sketch in your Arduino to light your LED's. Would it not be possible to accomplish this using relays in place of the servo and switch?
     
  13. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    The setup in the video was for my benefit to see if what i was thinking would actually work. The servos will be attached under the bench work and an actuating rod sent up through to control the points on the layout. I have just finished installing 8 of them on an area of the layout that has 4 crossovers, took about an hour to build and install them. I will post another video shortly to show my progress. Still trying to get the delay working, thanks to the help of Bob Craig, thanks again Bob. But not having much luck so far, but will get it.
     
    papahnash likes this.
  14. papahnash

    papahnash TrainBoard Member

    337
    69
    17
    Now I understand. I have built crossing gates with Arduino and servo combination. In the sketch there is code to control the rate of servo movement. I will look it up and try to post it.
     
  15. papahnash

    papahnash TrainBoard Member

    337
    69
    17
    The crossing gates were made by Geoff Bunza and can be found here:

    http://model-railroad-hobbyist.com/node/20176

    I also found a sketch for 8 servo controlled turnouts you may or may not be aware of.

    Hope this helps.

    //Turnout Controller for 8 turnouts (could be expanded to 48 with Arduino Mega!)
    //Arduino 2009
    //uses VarSpeedServo library by Korman found at :http://rapidshare.com/files/425318464/VarSpeedServo.zip
    //by David Garrison, May 2011
    //This drives up to 48 servos (with the Arduino Mega) it is limited to 8 servos on the Uno or 2009 boards due to lack of I/O pins.
    //Used to control model railroad turnouts with inexpensive RC servos. The input is a panel mounted DPDT toggle switch (for each turnout) that is driving (by reversing a +5V and Gnd connection) two bi-color LEDs.
    //The amount of movement (in degrees), direction and speed of the servos is programmable.
    //The LEDs are placed in the track diagram at the turnout locations and indicate the turnout position by changing color Red -closed , green open for each leg of the turnout.
    //The switched +5 and ground is used as the level input.
    //A servo centering function is provided to aid in the installation of the servos.
    //All- in- all this has been a fun project that was really made very simple by using the VarSpeedServo library (and help provided by Arduino Forum members!)...lots going on here but not much code to write!



    #include <VarSpeedServo.h>


    const int numberOfServos=7; //number of servos ( I only need 7 for this project)

    VarSpeedServo servo[numberOfServos]; //create servo objects
    int portNumber[numberOfServos] ={14,15,16,17,18,19,9}; //initalize input pin numbers
    int servoPin[numberOfServos] ={2,3,4,5,6,7,8}; //intialize output pins servos connect to
    int closepos = 120; //value (in degrees) for servo closed position value
    int openpos = 60; //value (in degrees) for servo open postion
    int mid = 90; //value (in degrees) for servo mid postion



    void setup()
    {

    for (int i =0; i<numberOfServos; i++)
    {
    servo.attach(servoPin); // attach servos to output pins
    pinMode (portNumber, INPUT); //set up input pins
    }

    pinMode(10, INPUT); //set up input pin for centering mode switch
    digitalWrite(10, HIGH); //pull up resitor set for center mode switch

    }

    void loop ()
    {
    //tests for setup mode
    if (digitalRead(10) == 0) centerAll(); //looks for a low on pin 10, provided by a SPST switch to GND

    // reads input conditions and moves servos if required

    for (int i=0;i<numberOfServos;i++){
    if (digitalRead(portNumber) == 0) //read all inputs and outputs servo.move commands

    servo.slowmove (openpos,20); // second arg is servo speed , 20 is about 3 seconds

    else

    servo.slowmove (closepos,20); // second arg is servo speed , 20 is about 3 seconds
    }
    }


    void centerAll()

    //test if switch on input 10 is closed to ground and if so center all servos
    //blink on board LED 13 to indicate Center Mode of operation
    {
    for (int i=0;i<numberOfServos;i++)
    {
    servo.slowmove (mid, 20); //center all servos
    }
    do
    {
    digitalWrite(13,HIGH);
    delay(300);
    digitalWrite(13,LOW);
    delay(300);
    }
    while (digitalRead(10) == 0); //blink led 13 until setup switch is opened
    }
     
  16. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    Arduino: 1.8.4 (Windows 7), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

    C:\Users\bob\Documents\Arduino\Sketches\sketch_nov12c\sketch_nov12c.ino:1:27: fatal error: VarSpeedServo.h: No such file or directory

    #include <VarSpeedServo.h>

    ^

    compilation terminated.

    exit status 1
    Error compiling for board Arduino/Genuino Mega or Mega 2560.

    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.


    NOTE when i add this code via copy and paste the above is the error msg i get after compiling. i suck at this
     
  17. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    oh wait i see. I have the varspeedservo.h but where do i put it? in the sketch folder?
     
  18. papahnash

    papahnash TrainBoard Member

    337
    69
    17
    The <VarSpeedServo.h> needs to be downloaded to your Arduino library. The original Arduino download only includes <Servo.h>. It's been a while since I did this, I am only a copy and paste guy, I will have to search how I got it. I'll let you know when I find it.
    If you do have it, It must be in your Library file.
     
    Last edited: Nov 12, 2017
  19. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    ok got it. Now it wont compile lol.

    Arduino: 1.8.4 (Windows 7), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

    C:\Users\bob\Documents\Arduino\Sketches\sketch_nov12c\sketch_nov12c.ino: In function 'void setup()':

    sketch_nov12c:20: error: request for member 'attach' in 'servo', which is of non-class type 'VarSpeedServo [7]'

    servo.attach(servoPin); // attach servos to output pins

    ^

    C:\Users\bob\Documents\Arduino\Sketches\sketch_nov12c\sketch_nov12c.ino: In function 'void loop()':

    sketch_nov12c:39: error: request for member 'slowmove' in 'servo', which is of non-class type 'VarSpeedServo [7]'

    servo.slowmove (openpos,20); // second arg is servo speed , 20 is about 3 seconds

    ^

    sketch_nov12c:43: error: request for member 'slowmove' in 'servo', which is of non-class type 'VarSpeedServo [7]'

    servo.slowmove (closepos,20); // second arg is servo speed , 20 is about 3 seconds

    ^

    C:\Users\bob\Documents\Arduino\Sketches\sketch_nov12c\sketch_nov12c.ino: In function 'void centerAll()':

    sketch_nov12c:55: error: request for member 'slowmove' in 'servo', which is of non-class type 'VarSpeedServo [7]'

    servo.slowmove (mid, 20); //center all servos

    ^

    exit status 1
    request for member 'attach' in 'servo', which is of non-class type 'VarSpeedServo [7]'

    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.
     
  20. bobbyboy1962

    bobbyboy1962 TrainBoard Member

    23
    5
    2
    I have the same error with Bobs code so it must be something im doing. I am also a copy and paste guy
     

Share This Page