5

As education exercise on sending digital signals, I'm trying to code the pulse train for a servo without using the servo.h library.

The servo is a 9g micro servo. Hardware is correct, as many examples using servo.h work fine.

I have the following code. The problem is that the servo jerks around for 3 seconds rather than moving and holding still.

void loop() {
    movePulse_1000();
    delay(3000);
}

void movePulse_1000(){
    Serial.print("Start movePulse_1000()\t\t");
    for (int pulseCounter=0; pulseCounter<=150; pulseCounter++){
        digitalWrite(pinServo,LOW);
        delay(20); // between pulses
        digitalWrite(pinServo,HIGH);
        delayMicroseconds(1000);
    }
    Serial.println("End movePulse_1000()");
}
gre_gor
  • 6,669
  • 9
  • 47
  • 52
Playing with GAS
  • 565
  • 3
  • 10
  • 18

2 Answers2

2

Using an analog servo, the average pulse width must be 1.5ms apart, and the duty cycle changes based on the desired position. To keep the servo where you want it, you must constantly refresh the servo data. This isn't a super simple task and that servo library is quite optimized. There's few reason not to use it.

It creates hardware timers and uses them to refresh the servos. This allows your regular code to appear to continue regularly even though it's being interrupted by the servo library to service the servos. Duty cycle, pwm frequency, and refresh rates all come into play. You'll have to look at the data sheet of the servo you are using to get the full details. But its not as simple you think and those delay/delaymicros functions you're using aren't always precise enough. That's why you would use times and overflow interrupts. Though most servos aren't too picky and you can get away with a ton of slop.

DiamondDrake
  • 974
  • 8
  • 24
  • Diamond: Thanks for thoughts. I've done this in other languages and worked easily. Aren't the pulses separated by 20ms and the pulse duration 1-2ms? http://akizukidenshi.com/download/ds/towerpro/SG90.pdf – Playing with GAS Mar 01 '18 at 21:16
0

The library servo.h constantly sends pulses which means servo growling = battery consumption.

I changed your function to only rotate the servo without a timer from 0 to 180 degrees.

del = (7 * x) +500; - for my servo-pulse 500 to 1260us (calculated, not measured)

void movePulse(int x){
    int del=(7*x)+500;
    for (int pulseCounter=0; pulseCounter<=50; pulseCounter++){
        digitalWrite(pinServo,HIGH);
        delayMicroseconds(del);
        digitalWrite(pinServo,LOW);
        delay(20); // between pulses
    }
}
Kate Orlova
  • 3,225
  • 5
  • 11
  • 35