10

According to this:

The Servo library supports up to 12 motors on most Arduino boards and 48 on the Arduino Mega. On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins. On the Mega, up to 12 servos can be used without interfering with PWM functionality; use of 12 to 23 motors will disable PWM on pins 11 and 12.

However, according to this:

Digital I/O Pins 14 (of which 6 provide PWM output)

So how can the Uno control more than 6 servos if it only has 6 digital I/O pins that can provide PWM output?

user41158
  • 103
  • 1
  • 1
  • 4

2 Answers2

9

The Servo library doesn't use PWM. When you call write() it computes a pulse width in microseconds and stores it in a global array. Then there is a single timer that regularly triggers an interrupt which changes the output signals according to each channel's desired pulse width.

You can find the source code below : Github link

Thomas Weller
  • 1,008
  • 1
  • 11
  • 25
Grapsus
  • 206
  • 1
  • 2
  • 1
    So it essentially simulates PWM? What is the point of the digital pins with PWM channels then? – user41158 Apr 30 '14 at 22:29
  • 2
    In general, servo pulses are about 1 ms long. Therefore they must by driven by frequencies around 1 kHz which is very easy to generate by software on any output with a micro running at several MHz. AVR PWM outputs are generated by dedicated hardware and can reach the CPU frequency but the number of channels is limited. I guess the authors of the Servo module decided to use a single timer in order to handle as many channels as pins and save the PWM hardware for other uses. – Grapsus Apr 30 '14 at 22:53
  • 1
    The PWM of the Arduino outputs is for variable-power outputs with duty cycles between 0 and 100%. RC-style "PWM" control has a very limited duty cycle range -- 1000 us at 50 Hz is 5%, 2000 us at 50 Hz is 10%. Think of RC PWM as a "pulse train" rather than traditional "PWM." – Jon Watte May 01 '14 at 00:23
  • @user41158 If you have unlimited CPU time, you can use any digital output as PWM and control them in software, not only PWM, in theory you can create any digital communication systems by writing a program and toggling these outputs, it's called "[bit-banging](https://en.wikipedia.org/wiki/Bit_banging)". But in practice, the CPU time is not unlimited and it's best to solve hardware tasks by hardware. For servo control, the PWM frequency is fairly low, so it's practical to bit-bang the PWM in software to create additional outputs. – 比尔盖子 Jan 26 '20 at 23:57
2

The 6 PWM pins use the built in UART on the ATmega328P to produce their output. This makes the pulses very fast for a higher quality "analog" output. Because servo's communicate at a slow enough speed, they can be driven using software interrupts. Software interrupts go away from the code you're executing and run code included with the servo library. This code uses standard means to change the state of the pins. By doing it using interrupts rather than using the UART you waste some processing time but gain the ability to drive more servos.

John Dood
  • 21
  • 2
  • Can you explain (or link to) more? How is the UART used for PWM? – Martin Thompson May 01 '14 at 10:52
  • I think it would be better to say that the PWM library may use the UART I/O pins if desired. the PWM library won't use the UART itself, but the pins used by the UART can also be used as standard digital I/O if not required for the UART. – Peter Bennett May 01 '14 at 16:20