PID ThumbDoing this project really turned me on to systems and controls theory. A friend and I implemented a fully functioning PID motor speed and positioning controller onto a PIC MCU. This is a pretty thorough guide to building this very hand robotics peripheral.


As part of the IEEE hardware team I’ve done a lot of projects, but I’m proudest of this one. This was a PIC based system that implemented a closed-loop PID controller for position and speed control of two DC motors. In addition, the control loop could be adjusted to induce arcs.

The system was designed as a peripheral for another processor so it also had an SPI command interface that allowed it to be communicated with on a high level while it controlled the motors on a low level. The peripheral had a serial console that allowed you to tune, test, and drive the robot.

The Board

Shout outs go to Dr. John Peatman and my esteemed partner in this endeavor Jacques Fortier.


In order to complete its task, the robot needed to have precise control of its speed and position. Because much of the way finding of this robot was accomplished through dead reckoning, it was also especially important to maintain accurate information regarding the distance traveled by the robot.

In order to give the robot all of these features, we designed a special sub-processor that was devoted to the low-level control of the two primary motors. We implemented this system on a Microchip PIC18F252. This processor was housed on the same board as the motor driver which took control signals from this controller and used them to actually drive the motors.

Our sub-processor monitored the motors, and applied an appropriate pulse width modulated (PWM) signals to allow them to reach their goal. This controller also had the ability to communicate with the primary controller to receive speed and distance commands as well as report accomplished speed and distance traveled back to the commanding processor.


In order to get speed and distance information from the motors, we purchased motors with built in encoders that output a quatrature encoder interface (QEI) signal. This signal is comprised of two pulse trains that tell when the wheel travels a part of a rotation, and the direction of motion. When channel A makes a low to high transition, the value of channel B is checked to determine the direction. A sample QEI output can be seen below.

Quatrature Encoder Interface (QEI)

The motion controller was able to interrupt on low to high transitions from the QEI on channel A and create an estimate of instantaneous speed and direction by monitoring the number of counts obtained during a specified time interval. We used this information as inputs to the control loop that determines and compensates for errors in speed or distance.

The Control Loop

We implemented a PID (Proportional, Integral, and Differential) control loop to control the speed of the motors. The speed of the motors is manipulated by altering the duty cycle of a PWM signal generated by the processor. The duty cycle of this signal is known as the control value. below is a functional diagram of the control loop.

PID Flow Chart

This algorithm first determines the difference between the commanded speed and the actual speed. This value is known as error. The integral error is determined by adding the error to an accumulator, and the derivative error is calculated by subtracting the error from the previous error.

Every time the control loop executes, each of these errors are multiplied by a gain constant that has been tuned to optimize response time and accuracy. These errors, multiplied by their gain constants are then be added to the control value to compute the new control value.

In this way, the control value is continuously updated based on the response of the motors. This ensured that the motors are moving at the desired speed despite drag, obstacles, or other unexpected track conditions.

A final compensation factor is summed along with the P, I, and D errors. This is an error generated by inconsistencies in the two wheels. This helps to ensure that the robot goes straight by compensating for factors that slow one wheel but not the other.

Position Control

This was accomplished by controlling the speed based on the robot’s proximity to the desired position. The motor controller could take commands from the main processor that told it how many ‘ticks’ to travel. This value corresponded exactly to the number of QEI pulses that the robot should move.

The exact distance represented by each tick was determined by the resolution of the encoders and the diameter of the wheel. Our control system was capable of responding to 2944 ticks per revolution. With wheels that were 2.2 inches in diameter, the total distance per tick was 2.346×10-3 inches. Thus, very detailed motor control was possible.

The position control algorithm allowed the robot to approach its target distance at any speed. Then, as the target approached, it would slow its speed so that it could stop accurately when desired. This was achieved with a simple algorithm diagramed below.

Position Control Flow Chart

The motors position was monitored and continuously updated in local variables. Once the motors reached a distance a certain threshold before the desired position, the position control section of the algorithm would command the motors to stop. This would ensure that as the motors slowed down and achieved a speed of zero the robot would be at the desired position. These two systems were independent for the left and right wheel so that they could be commanded to go different distances for turning purposes.


These abilities provided the robot with the tools needed to control the speed and distance of travel. However, in order to be truly useful, this sub processor needed to be able to receive commands from the master processor, and provide information regarding the motor status back.

We accomplished this by using an SPI (Serial Peripheral Interface) communication protocol. The communication was message-based. The main processor could send eight-byte messages to the PID controller. These messages began with a one byte op-code telling the sub processor what type of command the message contained. The next seven bytes held data such as the desired speed, or the desired distance to be traveled.

The sub processor could simultaneously send back eight bytes that held instantaneous speed, and total distance traveled information. With the ability to control speed, position, and communicate with the main processor completed, the motion control system was almost done.

Tuning the Control

The final step was to tune the PID control algorithm. This is accomplished by adjusting the gain constants by which each error is multiplied by before summing it with the previous control effort. This is a complicated process that is mostly achieved through trial and error.

Another tool that helped was using GNUplot to make graphs of debug data output by the PID controller. This allowed us to see the interaction of different errors. This interaction can be seen below.

Plots used to Tune Controller

The work of tuning the processor was simplified by developing a user interface on the PID controller that was separate from the main processor. This allowed the control system to be tuned over serial by adjusting gain constants stored in EEPROM.

With the motor controller fully tuned, it performed very well and provided excellent speed and position control for the robot without bothering the main processor with this low level task. Full code for this motion controller is below.

The Motor Driver

All of this fluffy code stuff is great, but you always need some good ol’ power electronics too. The motor driver was required to step up logic level PWM signals to 9.7V motor driving PWM at up to 3A. In order to accomplish this, we used an L298 H-bridge chip and some glue logic. In addition, it was a nice place to house the PIC chip that implemented the PID controller. We added some handy plugs for programming, connecting to other processors, and attaching motors and power. Just because I’m a nice guy, I’ve included a schematic and layout for the board as well as the code below.


PID C Code (8kb)
Motorboard Schematic (184kb)
Motorboard Layout (54kb)

Final Thoughts

I was really happy with this project. Below you can see me and Jacques giving our ‘gang sign.’ In case you can’t read it that says “PIC” … as in the PIC chip we wrote the PID controller on.

But more seriously, there were some valuable lessons learned. I really got the hang of SPI. It may have been better to use I2C for this, but I’ll have to save that for next time. I also got really turned on to systems and controls. The idea of a closed loop control system that uses its error to correct itself is very clever and elegant. I strongly recommend taking a class on systems and controls if you haven’t yet.

Another thing I’d like to share is *ALWAYS* program in C. Assembly is sooo much more annoying. We started the project in assembly and quickly realized that things were getting out of hand so we switched to C (God’s own language) and everything started going very smoothly.

If I had it to do over again, I might also make the position control better. As it was, you really needed to tweak constants every time you changed the default speed of the system. It was highly accurate, but it would be a little more robust if I had implemented a PID position control algorithm in addition to the PID speed control algorithm.

45 thoughts on “PIC PID Micro-Controller

  1. Hello!
    Nice to read your article, its very impressive, i want to simulate transf
    er function of the dc-motor in matlab. so could you please share the transfer function of your motor and its parameters. i would be obliged.


  2. Ahmad, For this project we used real-life motors and never needed to identify the transfer function. PID controllers are so versatile that they can be tuned rather quickly to work with a motor even if the transfer function is unknown.

  3. I’m trying to put PID into MCU and fortunately found your works. That’s all what I want. I’m tranfering the code to my AVR and my PCB. Thank you

  4. If you are willing, could you publish more information concerning your build environment(MPLAB, gnu, etc.)? I also noticed that there are two files(main.c and serial.c) but no reference to each other in the code (or did I just miss calls?). Nice work. Do you mind if I attempt to use this in a strictly home hobby project?

  5. Hi Shawn,
    Your project is very interesting to me but some part I don’t understand. Could you please explain to me. The part that look like flat ribbon cable, where is this cable connected to, and what is the purpose?
    The SV2, SV6, SV7, SV8 what are these used for? I see these ports left open.
    What motor did you use ? could you please show me how to connect the motor to the schematic?
    Thanks for your help.

  6. Hi Tony. The ribbon cable is a Serial cable used to communicate between the PC and the controller (over the open SV pins). This allowed nice tests while we were getting it working. Another cable connected the controller to the robot.

    I forget the motor, but this project will work with most DC motors that can be driven with PWM voltage. The controller needs to be tuned for every motor as described in the post.

    Hope that helps.

  7. hi shawn,

    thanks alot for your project its really helpful would you please tell me what enviroment did you use to build this this project?

  8. Your project is very interesting to me but some part I don’t understand. Could you please explain to me. The part that look like flat ribbon cable, where is this cable connected to, and what is the purpose?
    What motor did you use ? could you please show me how to connect the motor to the schematic? and can you show me the circuit….
    Thanks for your help.

  9. There were several cables:
    (1) connected the board to the computer for debugging
    (2) connected to the left motor
    (3) connected to the right motor
    (4) connected to the main controller to receive commands and transmit status updates.

    I’m not sure of the motor, but this should work for any DC motor with a quadrature encoder. You’ll have to tune the weights on the PID controller, of course.

    The schematic is linked above. The motors connect to MA1,2 and MB1,2.

  10. hi
    ? have a project about light sensitivity control with digital pid.Can someonehelp me .What can i do?

  11. Hi i want to ask a question(dumb), is it possible that the code of yours will work if I use it on a pic16f877a?

    Your answer is really much appreciated. Thanks

  12. I am doing a project on Closed loop speed control of a DC motor.

    I need some guide line on this PLEASE….

    I dont know which micro controller to use on that and the diver circuit.

    Kindly Help me with this…

  13. @Azam
    This post talks about using a PIC18F252 to implement a closed-loop PID controller of a DC motor based on QEI motor feedback. You can use the L298 chip to step up the voltage/current to drive the motors as stated in the post.

  14. Hi
    that is a masterpiece! you mentioned that u would do a better position control on this project, what is wrong with this one, i could not understand the position control part? i am working on a project so similar to this one, a generator excited by a speed and position controlled dc motor, do you think this project can be adopted to the one i am working on?

    your answers and advices are really appreciated

  15. The position control here is more like an AC or a cruise control than a legit PID control system. This means that it worked but it wasn’t as exact as I wanted.

    In terms of hooking this system up to your project, I don’t see why it wouldn’t work. The challenge will be in conditioning the inputs to the algorithm so they match approximately.

    If you finish your project and write it up online, send me a link and I’ll send some traffic your way.

  16. as a star i am trying to control the speed and the position of 2 dc motors with a pid bas pic microcontroller but i do not need it to communicate with the pc so, which parts should i ignore in source code and in the shmatic in order to do this?

  17. and i don’t understand the schematics where do you get the feedback from, i don’t see any connection between the pic and the driver and encoder, what are the sv1,sv2,sv3… connections under the pic and the unused logic?

  18. I am new to control systems and am experimenting with some of the basic theory that it encapsulates. I am about to embark on a project to control a DIY Servo (Brushless DC Motor/Optical Encoder/Hall Effect Sensor) through packets sent over P2P ZigBee Network (the commands initially read by a PIC Controller through via RS232 at one end and ultimately conveyed to the motor through a PWM output at the other end . Would I be correct in my assumption that the Integral part of the PID closed loop is missing in your example? Do you not need to monitor the torque using either back EMF or Hall Sensor Voltage?

  19. I am currently designing a motor control system for a small robot,I also plan to use a pic18 microcontroller for PID control.
    I’m pretty sure that I am on the right track, however I don’t fully understand how a PID is used to do this.
    If your document can help me to do that please send it to me
    thanks so much!!!

  20. Hi Shawn,

    How difficult would it be to let the chip accept direction and step signals ?
    (instead of spi signals)
    I would like to use these pid controllers for a cnc system…

  21. Hi, this is a master piece of work. I am working on a personal home research project. I am using multiple MCUs to separate concerns and have a better control of time based tasks. So I can easily introduce a separate MCU for PID using PIC which I am already familiar with. My question is how to modify the code to control Hitec servos instead of DC motors; I am using standard continuous rotation servos and Nubotics quadrature encoders. Thanks

  22. Mr. Shawn,

    Good afternoon!
    This is TJ Sarmiento, a Mechanical Engineering student from Manila, Philippines. I have a project wherein I need to control the speed of a small windmill/wind turbine in relation to changing wind speeds. My control system should involve PID control. I plan to make an air duct with controllable guide vanes inside, controlled by some servo motor. To maintain constant exit air speed from the air duct, the guides vanes should be controlled so that my windmill outside will rotate at constant speed.

    Sir, I’m starting from scratch, and I’m considering the use of PIC16F877A. Also, I still don’t have idea on the programming aspect. My proposed setup is shown on my attached PDF file (pls see attached file). Sir, please advise on what materials, components and accessories I should use.

    Looking forward to your favorable response. Thank you.


  23. I am interested
    IN “Micro PROCESSOR Based PID controller COMPLET WITH A/M Transfer station one Element System configuration Via Integral
    P:S 220 volt , 50HZ
    I/p Signal 4-20mA from pressure
    O/P signal: 4-20mA
    Alarm Contact
    24 VDC power supply for pressure Transmitter
    Dim: 96×96 or 172,×44
    With display for PV,S.P.,O/P.



  24. Hi Shawn,

    This is a great write. Down to the point.

    How did you manage to handle angles and arcs with this code ? This is one of the problems im facing and I have no idea how to handle it in a microcontroller with all the trignometry

  25. Shawn, just getting into a temperature controlled device using a PID controller.
    I was thinking of using a Microchip PIC (PIC16F1823) since I needed alot of I/O
    and not needing a SPI/I2C since I’m having the LED display on the same PCB.
    Parallel data sent (not 3 lines for SPI or 2 for I2C)…just keeping it simple for
    the display.
    The PIC16F1823 has a full H-bridge and wondered if this was the best choice since I wanted a PID controller interface. Your advice is greatly respected and appreciated.

  26. Shawn, just getting into a temperature controlled device using a PID controller.
    I was thinking of using a Microchip PIC (PIC16F1823) since I needed alot of I/O
    and not needing a SPI/I2C since I’m having the LED display on the same PCB.
    Parallel data sent (not 3 lines for SPI or 2 for I2C)…just keeping it simple for
    the display.
    The PIC16F1823 has a full H-bridge and wondered if this was the best choice since I wanted a PID controller interface. Your advice is greatly respected and appreciated.

  27. Definitely consider that which you said. Your favorite justification seemed to be at
    the web the easiest factor to take into account of.
    I say to you, I definitely get irked at the same time as other people consider worries that they just don’t recognise about. You controlled to hit the nail upon the highest as smartly as outlined out the whole thing without having side-effects , other folks could take a signal. Will likely be back to get more. Thank you

  28. “PIC PID Micro-Controller | Shawn Lankton Online” was indeed a quite nice article, .
    Keep posting and I’ll try to keep on reading through! Thank you -Dora

  29. Finding the right house for your family means finding the best nest will help
    you to take care of your kids better. You are the only one will be hurt
    by this, so there is no reason not to be honest. If you are not in the
    mood of spending much on moving, the moving service
    provides the facility of a trailer.

Leave a Reply

Your email address will not be published.