Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 11 of 11

Thread: Servo Sweep Using millis(); ?

  1. #1
    Junior Member
    Join Date
    May 2020
    Posts
    19

    Servo Sweep Using millis(); ?

    Can anybody tell me why my servo sweep function does not work? Its meant to be a simple mod of the generic servo sweep using millis();

    Not shown--

    In both the setup and loop:

    currentMillis = millis();

    and at the beginning of the sketch:

    #include <PWMServo.h>
    PWMServo myservo;
    int previousMillisServo = 0;
    int pos = 0;
    long servoInterval = 15;
    unsigned long currentMillis = 0;

    So, the issue is with how I am writing the function.
    Please weigh in.
    Thank you!!

    HTML Code:
    void servoSweep() {
    if (currentMillis - previousMillisServo > servoInterval) {
      previousMillisServo = currentMillis;
      for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
        // in steps of 1 degree
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        //delay(15);                       // waits 15ms for the servo to reach the position
      }
      for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        //delay(15);                       // waits 15ms for the servo to reach the position
      }
    }
    }

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,539
    Quote Originally Posted by siredward View Post
    Please weigh in.
    We generally expect you to show a complete program, not code fragments and assurances like "In both the setup and loop: currentMillis = millis();" without the actual code.

    We do help here (probably more than most forms), but you need to do your part. Compose a small but complete program which reproduces the problem. If this is part of a huge project, trim it to a small program and verify that program really demonstrates the problem, then post the complete code.

  3. #3
    Junior Member
    Join Date
    May 2020
    Posts
    19
    Roger. Thanks for your time.

  4. #4
    Junior Member
    Join Date
    May 2020
    Posts
    19
    Here is the complete code -

    I am trying to substitute a millis() based function for delay()

    If the delay commands were to be uncommented, and the first two lines in the function servoSweep() were to be commented out, then the servo sweeps.

    However if the delays are commented out as seen below, the millis code here does not do what I intend for it to.

    Any thoughts on using millis() in place of delay for servo pauses?

    Thank you

    Code:
    //SweepwithMillis
    
    #include <PWMServo.h>
    PWMServo myservo;
    int previousMillisServo = 0;
    int pos = 0;  
    long servoInterval = 15;
    unsigned long currentMillis = 0;
    
    void setup() {
      myservo.attach(9);  // attaches the servo on pin 9 to the servo object
    }
    
    void loop() {
      currentMillis = millis();
      servoSweep();                   
      }
    
    
    void servoSweep() {
    if (currentMillis - previousMillisServo > servoInterval) {
      previousMillisServo = currentMillis;
      for (pos = 0; pos <= 175; pos += 1) { 
        myservo.write(pos);              
        //delay(15);                       
      }
      for (pos = 175; pos >= 0; pos -= 1) { 
        myservo.write(pos);              
        //delay(15);                     
      }
    }
    Last edited by siredward; 07-16-2020 at 03:56 AM.

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,237
    Nothing updates :: unsigned long currentMillis = 0;

    It might work with this change to a PJRC elapsedMillis that auto updates with reference to millis() :: elapsedMillis currentMillis = 0;

  6. #6
    Junior Member
    Join Date
    May 2020
    Posts
    19
    Ah yes. I added that line of code in currentMillis = millis(); . It produces a very erratic result however.

  7. #7
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,237
    next problem is this :: int previousMillisServo = 0;

    Should be :: uint32_t previousMillisServo = 0;

    That is the clearest way to get known Unsigned 32 bit integer.

  8. #8
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    126
    Quote Originally Posted by siredward View Post
    Here is the complete code -

    I am trying to substitute a millis() based function for delay()

    If the delay commands were to be uncommented, and the first two lines in the function servoSweep() were to be commented out, then the servo sweeps.

    However if the delays are commented out as seen below, the millis code here does not do what I intend for it to.

    Any thoughts on using millis() in place of delay for servo pauses?

    Thank you

    Code:
    //SweepwithMillis
    
    #include <PWMServo.h>
    PWMServo myservo;
    int previousMillisServo = 0;
    int pos = 0;  
    long servoInterval = 15;
    unsigned long currentMillis = 0;
    
    void setup() {
      myservo.attach(9);  // attaches the servo on pin 9 to the servo object
    }
    
    void loop() {
      servoSweep();                   
      }
    
    
    void servoSweep() {
    if (currentMillis - previousMillisServo > servoInterval) {
      previousMillisServo = currentMillis;
      for (pos = 0; pos <= 175; pos += 1) { 
        myservo.write(pos);              
        //delay(15);                       
      }
      for (pos = 175; pos >= 0; pos -= 1) { 
        myservo.write(pos);              
        //delay(15);                     
      }
    }
    @siredward:

    The very first time your program calls the servoSweep() function, using the values of currentMillis (which == 0), previousMillisServo (which == 0), & servoInterval (which == 15), your "if" comparison looks like this:

    Code:
    if (0 - 0 > 15)
    With these values, this comparison will never be true, so nothing after this in the servoSweep() function will be executed. Maybe you intended to add the following as the first line in the servoSweep() function:

    Code:
    currentMillis = millis();
    As an alternative, you could just do away with the currentMillis variable & use the millis() call in its place as follows:

    Code:
    void servoSweep() {
    if (millis() - previousMillisServo > servoInterval) {
      previousMillisServo = millis();
      for (pos = 0; pos <= 175; pos += 1) { 
        myservo.write(pos);              
        //delay(15);                       
      }
      for (pos = 175; pos >= 0; pos -= 1) { 
        myservo.write(pos);              
        //delay(15);                     
      }
    }
    However, this still suffers from another problem: the original code using the delay(15) call will delay 15ms between servo steps, but your modified code will not delay at all between servo steps. Not sure if this is what you intended. Normally, if you want to use the millis() function call to allow you to delay for a fixed amount, you would use the following generic approach (using the previous 15ms delays as an example):

    Code:
    void servoSweep() {
      for (pos = 0; pos <= 175; pos += 1) { 
        myservo.write(pos);              
    
        previousMillisServo = millis();
    
        // delay for the servoInterval
        while ((millis() - previousMillisServo) < servoInterval) ;
      }
    
      for (pos = 175; pos >= 0; pos -= 1) { 
        myservo.write(pos);              
    
        previousMillisServo = millis();
    
        // delay for the servoInterval
        while ((millis() - previousMillisServo) < servoInterval) ;
      }
    }
    See if that's what you had in mind. Let me know if I misinterpreted you intentions and/or if you have any other questions.


    Good luck & have fun !!

    Mark J Culross
    KD5RXT

  9. #9
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    126
    Whoops . . . I see that @defragster & I crossed in the ether.

    Mark J Culross
    KD5RXT

  10. #10
    Junior Member
    Join Date
    May 2020
    Posts
    19
    Mark!! IT WORKS!! (The last function in your post)
    Thank you so much for your time and contribution. I am going to study what you did here and learn from it.
    Now onwards to see if I can run it simultaneously with the other libraries which were getting interrupted.
    Great job!!

  11. #11
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    126
    Quote Originally Posted by siredward View Post
    Mark!! IT WORKS!! (The last function in your post)
    Thank you so much for your time and contribution. I am going to study what you did here and learn from it.
    Now onwards to see if I can run it simultaneously with the other libraries which were getting interrupted.
    Great job!!
    Glad that I was able to help. Feel free to ask any other questions & the forum members will do our best to help if/as we can . . .

    Mark J Culross
    KD5RXT

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •