So is there a way to slow down the servo speed using millis function. Would I need to download anything from the library
something like this you mean?
/*the sg90 accepts 3 command pulse width
1ms - CCW movement
1.5ms - return to center position
2ms - CW movement
minimum time between pulses/steps - 20ms
Servo can rotate approximately 180 degrees end-to-end
This example uses millis() and micros() to demonstrate servo operation.
*/
uint8_t DirectionInputPin = 9; //change this to the ACTUAL pin being used!!!
uint8_t sg90ControlPin = 8; //change this to the ACTUAL pin being used!!!
uint8_t millisbetweenSteps = 20; // milliseconds - or try larger values for slower steps
uint16_t CCWpulseWidth[2] = {1000, millisbetweenSteps}; // 1000us, millisbetweenSteps in milliseconds
uint16_t CWpulseWidth[2] = {2000, millisbetweenSteps}; // 2000us, millisbetweenSteps in milliseconds
uint8_t element_number = 1;
unsigned long oldtime;
uint8_t numberOfSteps = 100;
uint8_t currentStepCnt = 0;
uint8_t dir_req;
void move_servo(int Steps, uint16_t *pulseWidth) {
if (currentStepCnt < Steps) {
if (element_number == 1 && (millis() - oldtime) > pulseWidth[1]) {
digitalWrite(sg90ControlPin, HIGH);
oldtime = micros();
element_number = 0;
++currentStepCnt;
}
else if (element_number == 0 && (micros() - oldtime) > pulseWidth[0]) {
digitalWrite(sg90ControlPin, LOW);
oldtime = millis();
element_number = 1;
++currentStepCnt;
}
}
}
void setup() {
Serial.begin(115200);
pinMode(sg90ControlPin, OUTPUT);
digitalWrite(sg90ControlPin, HIGH); //reduces chances of jitter on powerup/reset
//a 1k pullup resistor between sg90ControlPin and VCC would also help
pinMode(DirectionInputPin, INPUT_PULLUP);
//initialise direction flag
dir_req = digitalRead(DirectionInputPin);
Serial.println("Starting Sg90 Demo");
//abitrary delay
delay(2000);
//servo initialisation
//move servo to center positon
digitalWrite(sg90ControlPin, LOW);
delay(20);
digitalWrite(sg90ControlPin, HIGH);
delayMicroseconds(1500);
digitalWrite(sg90ControlPin, LOW);
delay(20);
//move servo fully CounterClockwise (approximately 90 steps)
move_servo(90, CCWpulseWidth);
//abitrary delay
delay(2000);
}
void loop() {
if (digitalRead(DirectionInputPin) != dir_req) {
dir_req = digitalRead(DirectionInputPin);
digitalWrite(sg90ControlPin, LOW);
oldtime = millis();
element_number = 1;
currentStepCnt = 0;
}
if (currentStepCnt < numberOfSteps) {
//move servo Clockwise
if (dir_req == HIGH) {
move_servo(numberOfSteps, &CWpulseWidth[0]);
}
//move servo Counter-Clockwise
else {
move_servo(numberOfSteps, &CCWpulseWidth[0]);
}
}
}
hope that helps...
Thank you
@sherzaad sooo.. much.
I’m going to give it a go. I’d just start learning about millis a few days ago and still kinda experiment with it vs delay function…
here I have another example & explanation:
https://werner.rothschopf.net/microcontroller/202207_millis_slow_servo.htm
Just remember that the millis() function makes a periodic adjustment to make up for running a bit slow. So sometimes the value produced by millis() will increment by two even though only 1mS has passed since it last changed.
Thank you @noiasca im still somewhat at a beginners level when it comes to the programming aspect
You can refer to how to control speed of servo motor using millis()
what are micros?
micros( ) is a function that at returns the number of microseconds (within 4us) since restart, similar to millis( ).
the code I shared uses both millis() and micros() as millis() on its own is not accurated enough as already mentioned here.
As already mentioned also, micros() is essentially millis() equivalent except that it returns microseconds instead on milliseconds!
hope that thelps...
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.