Servo Motor Control With PIC Microcontroller – Software PWM PT2

Previous Tutorial Previous Tutorial Tutorial 31 Next Tutorial Next Tutorial
Servo Motor Control With PIC Microcontrollers | Software PWM
Intermediate Level ★★☆☆☆


Servo Motor Control Tutorial – PART 2

Servo Motor Tutorial With PIC Part2 - Thumbnail


In this Article / Tutorial, we’ll discuss how to control servo motor with PIC microcontroller using the Software PWM technique. We’ll generate a 50Hz software PWM signal and vary the duty cycle to change the angular position (angle) of the servo motor. This method enables us to control as many servo motors as we want and have a little bit more control over the PWM resolution!

In the previous tutorial (servo motor control Part1), we did lower the Fosc of the system as much as we could in order to get the CCP PWM running @ 50Hz. Conversely, today we’ll pump up the Fosc using the internal PLL up to the maximum possible frequency for PIC18F2550 which is 48MHz. In this way, we can get reasonable PWM duty cycle resolution.

Without further ado, let’s get started!


   Required Components For This Tutorial   


Qty. Component Name Buy On
1 PIC18F2550 Add
1 BreadBoard Add
1 Micro Servo Motor (Metal Gear) Add
1 LED Add    Add
1 Resistors Kit Add    Add
1 Capacitors Kit Add    Add
1 Jumper Wires Pack Add    Add
1 LM7805 Voltage Regulator (5v) Add
1 Crystal Oscillator Add
1 PICkit2 or 3 Programmer Add
2 9v Battery or DC Power Supply Add    Add    Add

My DSO Siglent-SDS1104 (on

My Function Generator Fy-6900 (on

*Affiliate Links Disclosure: links will make me a small commission at no additional cost to you*

The Prototyping Board Setup

Prototyping Board - Embedded Systems Tutorials With PIC MCUs


   How To Control Servo Motors?   


The way servo motors are working is simply by comparing a reference voltage to the actual angular shaft position using a potentiometer attached to the gearbox. The reference voltage can be controlled by sending a 50Hz PWM (pulse-width-modulated) signal to the servo motor. Which in turn changes the reference voltage and the control circuitry steers the motor in the right direction until it reaches the exact required angle position and it keeps holding it while the PWM signal is not changing.

The diagram down below indicates the behavior of the servo motor’s shaft due to the change of the PWM pulse width. Typically the full sweep (0->180°) is achieved by sweeping the pulse width from (1ms to 2ms).

How To Control Servo Motor With PIC Microcontroller

Different servo motors have different ranges for the pulse width of the 50Hz PWM signal which corresponds to the 0° position and 180° maximum angular position. So, it’s important to double-check the datasheet for the specific servo motor you are using.

The range for the PWM pulse width for my servo motors (MG90S) is 0.6ms to 2.4ms for angular motion from 0° to 180°. And that’s what we’ll be using.

 Note That:

 0.6ms of 20ms period is a 3% duty cycle (0° Position), 

 1.4ms of 20ms period is a 7% duty cycle (90° Position), 

 2.4ms of 20ms period is a 12% duty cycle (180 ° Position). 


   Servo Motor Control With PIC Microcontrollers   


There are different ways to generate the 50Hz PWM signal required by the servo motor using a microcontroller. Speaking about PIC microcontroller, the first thing that should pop-up in your mind is the CCP PWM hardware module inside the microcontroller itself. But it turns out to be a little bit tricky business to get that right. We’ve discussed the reasons for this in the previous tutorial and put it to the test.


What Are Some Design Techniques & Solutions To Control Servo Motors?


1 CCP PWM Hardware Module & Lowering Down Fosc using LP internal RC oscillator

(This solution was implemented in the previous tutorial PART-1).

2 Software PWM Generation Using Timer or Compare Match Interrupts

(This is the solution we’ll be implementing today).

In a previous article, I’ve discussed the topic of software-generated PWM signals and how to precisely control the resolution, frequency, and duty cycle of it. You can refer to this article, or wait for the software PWM servo driving. But all in all, it’s a viable way to generate the 50Hz PWM signal and more importantly, it opens up the possibility to control any number of servo motors simultaneously (at least theoretically and @ high Fosc).

3 Using PCPWM module in Microchip PIC Microcontrollers

The Power Control PWM module from Microchip is available in a number of microcontrollers dedicated to motors and power control applications. Embedded systems designers for these sorts of applications are more familiar with this module and the dsPIC part with sophisticated PWM generation hardware.

The PCPWM hardware module is controlled by a total of 22 registers. And it has a larger time base registers and a very wide range of Prescaler values that makes your task much easier. The output channels may be up to 6 or 8.

4 Using NCO (Numerically Controlled Oscillator) Module

The NCO module from Microchip is available in too many microcontrollers especially the 8-Bit parts. This intelligent hardware module is capable of LINEARLY sweep over a wide range of frequencies and it can reach a resolution of 1/Fosc. I just can’t emphasize more how powerful and elegant this module is! It’s definitely a huge topic to be discussed in the future.

And it can potentially be the solution for a problem like a servo control. And let me show you how to do this but in another article!

5 The CCP Capture + Timer1 = 16-Bit PWM!

Theoretically, the 16-Bit Timer1 module can be combined with the CCP Capture module and use the CCPR1 16-Bit register pair to work as a Duty Cycle controller. We’ll end up having a 16-Bit of resolution PWM signal with a wide band of frequency control!

This means, we can effectively push the CCP PWM beyond its fundamental limits in terms of 10-Bit resolution, so we end up with a x64 times more levels of resolution in the duty cycle which will potentially increase our control ability over the servo motor’s angle!

This magical solution should work practically as it does in theory. And that’s what we’ll verify and investigate much deeper in the next article!



Well, I think there still be other solutions like using external I2C servo drivers and maybe combining CLC with timers. The list goes on, that’s enough for this section. Other solutions will be discussed and hopefully implemented in future articles. If you’re interested in that, please drop me a comment! I’d really like to know about this!


   Servo Motor Control With Software PWM   



1 Timer Modules Tutorial

2 Timer Preloading

3 Software PWM Technique

4 ADC Tutorial

5 Servo Motor Control PART-1 (the previous tutorial)


How To Generate The Required PWM Signal?

The process of designing a software-generated PWM signal starts with deciding on the required resolution for the duty cycle. Then deciding on the required frequency of the PWM signal. Therefore, a timer base interrupt could be set up to increment a software counter (variable) and generate the PWM signal on compare match events (in code). This is basically the mechanics of that technique.

In the Software PWM Article, I did mention the exact steps and calculations required to do so. And also a numerical example, luckily enough, it had the same frequency which we need today (50Hz) and 100 levels of resolution which is not bad (You can increase it though). You’ll also find the code listing there which we’ll also make use of in today’s experiments!


How To Control The Servo Motor With Soft PWM?

The software generated PWM signal in the provided code example has 100 levels of resolution for the duty cycle. So, if you want a 3% DC, you’ll simply write PWM1Dc = 3; and so on. And as we’ve stated earlier our motor moves from 0° to 180° over the duty cycle range from 3% up to 12%

By creating a simple mathematical mapping function, we can easily command the motor to move to specific angles or sweep over the entire range. Here are the code snippets for both of the functions mentioned. 

As you might have noticed, I’m passing the PWMxDC variable from the main function (in main.c) to these functions (in Servo.c) by reference. So that I can easily de-reference the specified address and manipulate the value in memory.


   Servo Motor Sweep – LAB3   


Lab Name PWM – Servo Motor Sweep
Lab Number 40
Lab Level Intermediate
Lab Objectives Learn how to generate software PWM signals @ 50Hz and control the position of a servo motor.


In this LAB, we’ll command the servo motor to move to certain angles (0° -> 45° -> 90° -> 135° -> 180° -> 0°). Then we’ll make it sweep from (0° up to 180° then back to 0°) twice. And keep repeating!


       1. Coding       


Open the MPLAB IDE and create a new project name it “Servo_Software”. If you have some issues doing so, you can always refer to the previous tutorial using the link below.

Create New Project With MPLAB IDE

Set the configuration bits to match the generic setting which we’ve stated earlier. And if you also find troubles creating this file, you can always refer to the previous tutorial using the link below.

Now, open the main.c file and let’s start developing the firmware for our project.

The full code listing for this lab is as follows


Project Files Download


       2. Simulation       


> The Motor Moves To 0° then 45° then 90° then 135° then 180° then back to 0°

> The motor sweeps from 0° up to 180° then back to 0° (Twice)


Servo Motor Control With PIC Microcontroller Software PWM LAB1


       3. Prototyping       


Connect the Brown wire to GND and the Red to Vdd and the Orange to RC2 (CCP1 PWM Pin). And turn on the power supply. The 50Hz PWM signal is captured by my DSO (digital storage oscilloscope).


Here is a short demo video for the running test for this LAB



   Servo Motor Manual Knob – LAB4   


Lab Name Software PWM – Servo Motor Knob
Lab Number 41
Lab Level Intermediate
Lab Objectives Learn how to use the software PWM generation technique to generate PWM signals @ 50Hz and control the position of a servo motor & a pot connected to the ADC.


In this LAB, we’ll replicate the Arduino servo example that uses the ADC and potentiometer to manually control the position of the servo motor using the analog input. We’ll read the AN1 channel, then the AD_RES result will get mapped to fit in the range of the servo PWM duty cycle 3% to 12%.



       1. Coding       


Open the MPLAB IDE and create a new project name it “Servo_SoftPWM_Knob”. If you have some issues doing so, you can always refer to the previous tutorial using the link below.

Create New Project With MPLAB IDE

Set the configuration bits to match the generic setting which we’ve stated earlier. And if you also find troubles creating this file, you can always refer to the previous tutorial using the link below.

Now, open the main.c file and let’s start developing the firmware for our project.

The full code listing for this LAB is as follows


Download Project Files


       2. Simulation       


Servo Motor Knob With SoftPWM


       3. Prototyping       


Here is the demo video for this LAB test. It turned out to be not as bad as it theoretically seems to be!

Why it should be bad in the first place? well, that’s a good question! This stems from the fact that our software PWM signal is very poor in resolution (only 100 levels). This can, in fact, can be solved by increasing it in software but a new issue would arise. This will be detailed in the concluding remarks section hereafter.


Play Video On YouTube


   Multiple Servo Motors Control – LAB5   


Lab Name Software PWM – Multiple Servo Motors Control
Lab Number 42
Lab Level Intermediate
Lab Objectives Learn how to use CCP modules to generate PWM signals @ 50Hz and control the position of a servo motor. And add many other servos!


       1. Coding       


Nothing is particularly useful in this LAB, On the technical/informational side of things. However, it looks very cool and it actually is a key strength point of the software PWM technique that I had to show you in such a way or another!

Here is the code listing for this project. I’ve kept everything as organized as possible so you can get the idea and maybe do a little bit of tweaking around.


Download Project Files


       2. Prototyping       


Play Video On YouTube


   Concluding Remarks   



Good News: It Does Work! Bad News: Too Many Limitations!

The software PWM technique does work and it could easily do the business. The strength point that I must highlight before getting into limitations is that we can use this technique to control, theoretically, any number of servo motors. And that’s a huge upside for many projects.

However, there exist many limitations to this technique. First of which is the resolution! OMG, it did work soooo well compared to the poor resolution of our PWM signal. Yes, we couldn’t get precise angle positioning with it. But it got as close as possible.

Despite have a poor resolution (100 levels or 6.64bits) @ very-low-frequency 50Hz, but the Timer interrupts are overwhelming to the CPU. At this configuration, our CPU receives 5000 interrupts per second just from the Timer1 module alone! can you imagine the amount of jitter this is adding to our system?

More resolution can be easily achieved for better control but get the CPU ready for receiving 10000 interrupts per second! And it’s obviously insane.

The last limitation that I see quite obvious is the necessity to pump up the Fosc frequency as high as possible. Reducing it a little bit will degrade the resolution a lot more. We had to crank the PLL up to get the maximum 48MHz output for the Fosc in order to achieve the “poor” resolution we’re using. This may not be good for power consumption and I had to mention that even while I know most of you wouldn’t mind using the CPU @ its maximum power.


Pay Attention To The Power Source

This technique makes you able to control many servo motors simultaneously. And you should know that small servo motors (cheap crap) can get stuck at some points which end up draining a crazy amount of current. Pay attention to this and use a separate power source for the microcontroller.


Better Solution

The next article (servo motor tutorial PART-3) will address another technique that has a significant advantage over the couple of ones we’ve seen so far. At least theoretically XD!

Stay tuned for that and part-3 may be the last part. I’d like to switch to another module or actuator (like RTC, or so). Let me know in the comments if you’d like to see other techniques for controlling servo motors, I’d really like to hear back from you!


Don’t forget to SHARE these articles/tutorials. And let me know in the comments what do you think? Do you have any other ideas? maybe questions or problems?

I’ll be always here for help!

Regards ^^

Khaled M.





Previous Tutorial Previous Tutorial Tutorial 31 Next Tutorial Next Tutorial
Share This Page With Your Network!
Join Our +25,000 Newsletter Subscribers!

Stay Updated With All New Content Releases. You Also Get Occasional FREE Coupon Codes For Courses & Other Stuff!

Photo of author
Khaled Magdy
Embedded systems engineer with several years of experience in embedded software and hardware design. I work as an embedded SW engineer in the Automotive & e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI/ML, and other fields I'm passionate about.
I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?

Leave a Comment