BOB PID Servo Controller

A VERY cheap, tested, working, PIC based P.I.D. PID servo controller, for stepper replacement e.g. RAMPS, Pololu plug compatible drop in.

Similar projects worth following
The goal here was to provide a basic but useful servo driver at very low cost (blank PIC 18F14k22's are under $2, the BOB PCB is $8, couple bucks misc parts) which could replace stepper motors in any standard application, such as 3D printers or CNC machines.

It accepts both serial and step / direction inputs. The serial interface allows for easy tuning of the P.I.D. constants and setting options like the polarity of the output direction signal. The step / direction input allows it's use in any application where a standard stepper driver was intended. It is a plug compatible drop in for the standard Pololu drivers found on e.g. RAMPS boards, and is PMinMO compatible for connection to e.g. Planet CNC and other USB motion controllers.

The output is PWM speed and direction which will drive most any standard H-Bridge or other motor driver.

See it running from a RAMPS / Marlin 3D printer controller here:

System Overview:
This is designed to work with a quadrature encoder and a motor driver of some kind. (e.g. DC, ESC, Stepper, etc...) It's the "Servo controller" part of this block diagram:

The "Motion Controller" could be a PC w/Mach3, LinuxCNC, etc... , or an Arduino w/ RAMPS/Marlin, GRBL, TinyG... basically anything that produces Step and Direction signals.

The "Motor Driver" could be a DC motor driver like this Low cost, 1 HP H-Bridge, or a SyRen 2 HP monster or an RC ESC, or Stepper driver... basically anything that accepts PWM pulses and Direction. Obviously, that will be whatever your motor needs as a driver.

The "Position Feedback" in this case needs to be a standard Quadrature Encoder like this Non-contact magnetic encoder, or any standard optical encoder.

Here it is working with a standard 3D printer board, replacing the little stepper drivers via an adapter cable.

Here is a sample session, getting the unit tuned and running:

  • 1 × PIC 18F14k22 (programmed with the source code)
  • 1 × BOB PID PCB (or breadboard, perfboard, your own design PCB, etc...
  • 2 × 10 pin 2x5 header Shrouded is best. 1 for Logic power, Ground, PWM, Direction, and Enable to Motor Driver, and 1 for Logic power, Ground, Step, Direction, Enable from Motion Controller (E.g. RAMPS, GRBL, etc...)
  • 1 × 1x5 header For TTL - USB connector.
  • 1 × 1x6 header To connect to the encoder Phase A, Phase B, Power, Ground.

View all 7 components

  • Firmware update

    James Newton02/21/2019 at 23:46 0 comments

    0.94 (not released)
    - BugFix: Actually save the step size parameter

    - Faster processing of step input, slightly faster encoder processing. Just track error, vs Setpoint - encoder_counter.  

    Note: Step/Direction input is now relative.  

    Calculation of Derivative and Integral terms changed. May need to re-tune

    0.95 Improved User Interface, Faster!
    - Just one "!" per encoder overrun; avoid buffer overrun

    - Add version / status / settings as "?" command

    - Let the user know they need to enter 321w to save

    - Past MAX_ERROR, disable and suggest other direction

    - Movements via serial command have a max velocity 'v'

    - Setpoint is now relative, always returns to 0, no wraparound jerk

    - Smaller data sizes (short long, 24 bits) used for most variables, faster

    - Derivative and Integral terms changed. May need to re-tune. EEPROM Version '4'

    0.96 Minor fixes
    - BugFix: 10 display digits exceeded precision. 9 works.

    - BugFix: Avoid PIDerror changing during calculations. Can cause small random jerks.

    I'm curious to hear if there are features people would be interested in... what would make you want to use BOB PID?

    // [ ] Faster!! Switch to assembly jump table in decoder?
    // [ ] MUCH faster!! Recover position via index pulse if available??
    // [ ] Set velocity and use PID to control that instead of position
    // [ ] Add LCD user interface?
    //     Problem with LCD interface: We don't control X DIR input
    //      which is also used by LCD as a data line.
    // [ ] Add demo mode
    // [ ] Add autotune mode with status output

View project log

  • 1
    Step 1

    for the most up to day instructions. Those listed here may be out of date.

    These instructions assume you are using the BOB PID PCB from the link above. You could also build this on a perfboard or whatever. I've added the PIC pin name to the tables for that reason.

    Note: Most components are installed on the underside of the PCB... The side with "U1 PIC"

  • 2
    Step 2
    Signal from BOB PCB
    All even pins are ground
    PIC Pin
    1 "E"/EnableRC7
    3 "D"PWM Drive (not direction)RC2
    5 "S"Direction (not step)RA4
    7 "-"GroundGND
    9 "+"+5 Logic power (if needed)VCC

    Motor Driver Output via Z Axis cable

    [ ] Install a 10 pin 2x5 header over the Z axis on JP3. On the boards underside, this is the 2nd from the right block of 2x5 pins in JP3 with "Z" just below it. Note that we swapped the standard functions of Step / Direction to support the PIC. For a PMinMO stepper driver, you must swap pins 2 and 3 in the cable. Our H-bridge driver will have those pin swapped, for a straight cable.
  • 3
    Step 3
    Signal from BOB PCB
    All even pins are ground
    PIC Pin
    1 "E"/EnableRB6
    3 "D"DirectionRC0
    5 "S"StepRA1
    7 "-"GroundGND
    9 "+"+5 Logic power (if needed)VCC

    Step / Direction input from motion controller via X Axis cable (if desired)

    [ ] Install a 10 pin 2x5 header over the X axis on JP3. On the boards underside, this is the far left block in JP3, starting from pin 1. This is PMinMO standard, so the Pololu adapter cable works nicely.

View all 14 instructions

Enjoy this project?



James Newton wrote 08/24/2016 at 20:14 point

Tested with SyRen 25 Amp Driver:

It should work the same with their 10 and 50 Amp versions.

SyRen 50 Amp Driver:

Their Sabertooth dual drivers don't appear to support PWM and direction as separate signals... they expect a single analog input which then drives forward above 2.5 volts and backwards below 2.5 volts. The BOB PID could probably be modified to support that if desired. Let me know.

For the single channel drivers, the mode switch needs to be set to "Option 3: Analog One-direction with forward/reverse select on S2" It's 1,2,3, on, 4,5, off, 6 on. Note that this mode is NOT listed in their "quick start" documentation, you have to look in the main manual. 

The connections are:

- S1 to Z axis pin 3 "D", the PWM Drive
- S2 to Z axis pin 5 "S", the Direction signal
- 0V to Z axis pin 7 "-", Ground

You can connect 5V to the + line if you want the SyRen to supply logic power to the BOB PID. The En signal isn't used and the motor will /always/ be enabled. (watchout!)

Works a treat! Video soon. 

  Are you sure? yes | no

James Newton wrote 03/31/2017 at 16:04 point

 Running from RAMPS/Marlin with a SyRen 25 Amp Driver or SyRen 50 Amp Driver: (NOT the Sabertooth dual units) The trick is to use Option 3 "Analog One-Direction with foward/reverse select on S2" That is, on the DIP switch 1,2,3 ON, 4,5 OFF, 6 ON. From the SyRen to our motor connector:
- S1 to Z axis pin 3 "D", the PWM Drive
- S2 to Z axis pin 5 "S", Direction signal
- 0V to Z axis pin 7 "-", Ground

  Are you sure? yes | no

lucio wrote 08/09/2016 at 11:13 point

You should check out the PIC16F1619! Those have a hardware PID peripheral (math accelerator with PID function) built in... orders of magnitude faster and probably cheaper too...

  Are you sure? yes | no

James Newton wrote 08/09/2016 at 18:22 point

Sounds like a great chip! I will look into that... thank you for the reference. 

  Are you sure? yes | no

James Newton wrote 03/31/2017 at 15:58 point

After looking into it, and some time spent playing with this thing in general, it turns out that the PID function is not the bottleneck... like... not at all. The hardest part is tracking the quadrature A and B phase signals from the encoder. So what it really needs is a chip with hardware for that job. As it happens, the encoder I'm using is a chip with a counter inside that keeps track of position, and you can ask it for position updates via I2C, so switching the firmware in the existing chip to do that instead of trying to keep up with the quadrature lines would resolve any speed issues. By my calculations, it could handle 10,000 RPM or higher. But... not everyone wants to use that sort of encoder... lots of people have a standard off the shelf encoder that only puts out quadrature. So I'm not at all sure there is a point in doing that work. I think it may just be better to find a chip that has quadrature decoding built in or at least some sort of programmable logic that a decoder could be built out of. Always open to suggestions.

  Are you sure? yes | no

Eric Hertz wrote 04/01/2017 at 09:34 point

There are definitely chips for that purpose... I've used the HCTL-2000 series in numerous projects. I hear there are uCs with quadrature-decoding peripherals, as well. Some of the PICs have programmable-logic, which could help.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates