Millis() timing issue: servo not sweeping smoothly

The purpose should be to execute an action once every interVal1a or interVal1B milliseconds, i.e. advance and then retreat (as in "sweep") a servo (SG90) in 1-increments between servoMin=250 and servoMax=250.
However the "incr=true" cycle results in irregular advance of the servo; the "incr=false") cycle executes smoother (not perfect yet).

What could be wrong in this code?

/* https://mytectutor.com/how-to-use-pca9685-16-channel-12-bit-pwm-servo-driver-with-arduino/

  PCA9685 without delay, with millis()
  default PCA9685 I2C slave address = 40
*/

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver myServo = Adafruit_PWMServoDriver();
#define servoMin 250
#define servoMax 500
unsigned long previousMillis1a = 0;
unsigned long previousMillis1b = 0;
// unsigned long previousMillis2a = 0;
// unsigned long previousMillis2b = 0;
unsigned long currentMillis;
int interVal1a = 70;
int interVal1b = 100;
// int interVal2a = 30;
// int interVal2b = 60;
uint8_t servonum = 0;
uint8_t numberOfServos = 6;
int pulseLgth = servoMin;
bool incr = true; //

void setup() {
  Serial.begin(9600);
  myServo.begin();
  myServo.setPWMFreq(60);
  delay(10);
}

void loop() {
  currentMillis = millis();
  if (incr == true && currentMillis - previousMillis1a >= interVal1a) {
    myServo.setPWM(servonum, 0, pulseLgth);
    Serial.println(pulseLgth);
    pulseLgth = pulseLgth + 1;
    if (pulseLgth == servoMax) {
      incr = false;
    }
    previousMillis1a = currentMillis;
  }
  if (incr == false && currentMillis - previousMillis1a >= interVal1b) {
    myServo.setPWM(servonum, 0, pulseLgth);
    Serial.println(pulseLgth);
    pulseLgth = pulseLgth - 1;
    if (pulseLgth == servoMin) {
      incr = true;
    }
    previousMillis1b = currentMillis;
  }
  servonum ++;
  if (servonum > numberOfServos - 1)
    servonum = 0;
}

Try here

Funny, you made me smile.
However, there I had two servo's (with an interference issue). Here, one servo, and being controlled by a PCA9685.
I can't see the connection, sorry.

Here, the increasing values of pulseLgth give a halting behaviour of the servo, the decreasing values work a lot smoother when the servo returns to a low angle.

What would be wrong in my program?

Ok: following needs to be ommited (bottom of program), but then still same issue:

...
  servonum ++;
  if (servonum > numberOfServos - 1)
    servonum = 0;
```
uint8_t numberOfServos = 6;

How many servos ?

Just one servo; that line you show has a variable that is not used, sorry for the confusion.

I think though I solved it:

  if (incr == false && currentMillis - previousMillis1a >= interVal1b) {

must be

  if (incr == false && currentMillis - previousMillis1b >= interVal1b) {

Yet, the progress of the sweep has no regular feel to it, like a haltering progress.

Could it be that the resolution of the intervals is too close to the time to execute each step of the servo? I.e. should the millis() timer not rather be in microseconds instead of milliseconds?

Isn't the SG90 servo a 50hz servo?

I do not know, but your comment made me try a few out: 50 and 70Hz seem to give more erratic behaviour, 60Hz seems the smoothest.

OK. I was just looking at the data sheet and other examples using this library.

quality of posted textes still below than described in
tips how to improve your posting style

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.