I am working on an Arduino Uno battle bot that uses a Sabertooth moter controller. Right now it is connected to the Arduino through Serial communication. Which is would be faster (So I can increase response time on my robot) Serial, or pwm using DigitalWrite?

  • I don't understand how you could substitute one for the other. Are you designing both ends? What sort of commands are you sending? Speed? Direction?
    – Nick Gammon
    Mar 6, 2016 at 20:33

4 Answers 4


Using digitalWrite() is the slowest by far.

Using PWM could be the fastest.

Using Serial could be the fastest.


You have to filter the PWM output to be a smooth analogue signal for it to be of any use. The filtering adds an inherent sluggishness, or response time, to the system - the harder the filtering the slower the reaction to changes in the PWM duty cycle. Adjusting the filter component's values will give an optimum point between smoothness and response time. Bear in mind that the motors may respond erratically if there is insufficient damping of the signal. This will probably give the Sabertooth a hard time, too. The datasheet recommends are filter response time of greater than 1ms.


If you are considering the 2x 60Amp version (thanks for adding plenty of information in the question, by the way) then the fastest baud rate is 384kbps - or 48k commands per second. The Arduino will of course not be churning data continuously because it'll be busy running the rest of the program, but using serial it is theoretically possible to send commands faster than the motor controller's output PWM.

So which is faster?

No idea. Only you can determine this, and I doubt you'll be able to determine the answer without wasting your time on some experiments.

The motors will have an inherent mechanical dampening thus creating an overall bottleneck in the whole system response time. I can almost guarantee that both PWM and Serial methods will be much faster than the response time of the motors themselves.


The fastest would be “Simplified Serial Mode” at 38400 bps. In this mode, a command is a single byte, transmitted as ten bits (1 start + 8 data + 1 stop), which would take 0.26 ms to be transmitted. Compare with the ≈ 1 ms lag you would get with an analog filter. As per the data sheet, the caveats are:

  • resolution reduced to 7 bits
  • the communication may not be reliable at this fast speed.

Update: The fastest may actually be PWM, if you “cheat” a little bit with the analog filter. The Sabertooth datasheet recommends

  • PWM frequency = 1 kHz
  • filter with 10 kΩ + 0.1 µF.

This gives a time constant RC = 1 ms, which is one PWM period. You can then expect a worst case ripple of 1.22 V peak-to-peak. The datasheet says you can increase the frequency or the capacitance beyond those minimum recommended values. In both cases you would get less ripple. But if we assume that this level of ripple is acceptable, we can make things faster by decreasing both the PWM period and the filter's time constant.

The trick is to configure the PWM output to run as fast as possible. The outputs of the Uno can run as fast as 62.5 kHz at 8-bit resolution, but for this we have to configure a timer using low-level port access, instead of relying on the analogWrite() Arduino function. I would rather avoid messing with Timer 0, because that would break all the Arduino timing functions (millis(), micros(), delay() and delayMicroseconds()). Here is an example program that uses Timer 2 to output two PWM waveforms at 62.5 kHz on outputs 11 (aka OC2A) and 3 (aka OC2B):

void setup() {
    DDRB  |= _BV(PB3);    // OC2A = PB3 = Arduino 11 as output
    DDRD  |= _BV(PD3);    // OC2B = PD3 = Arduino  3 as output
    OCR2A  = 127;         // output A starts at 2.5 V
    OCR2B  = 127;         // same for output B
    TCCR2A = _BV(COM2A1)  // output A in non-inverting mode
           | _BV(COM2B1)  // same for B
           | _BV(WGM21)   // fast PWM
           | _BV(WGM20);  // ditto
    TCCR2B = _BV(CS20);   // clock with no prescaling

void loop() {
    // Full forward both motors.
    OCR2A  = 255;
    OCR2B  = 255;
    delay (1000);

    // Stop.
    OCR2A  = 127;
    OCR2B  = 127;
    delay (1000);

You could then smooth these outputs with an RC filter of 2.2 kΩ and 10 nF. That would give a time constant of 22 µs, longer than the PWM period which is 16 µs, and a worst-case ripple of 0.9 V peak-to-peak.


pwm is faster. PWM is directly to the port. Serial goers to a buffer is send char by char and the receiver needs to wait for all the data to arrive.


Both are (relatively) slow. When speed is of the essence, use port manipulation. This can execute a pin change as fast as a single clock cycle--faster than any library.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.