Proportional-integral-derivative (PID) controllers are ubiquitous in industrial settings, used for such applications as temperature regulation, flow and level control, and motor control. Achieving optimal performance often requires careful manual tuning of the three PID parameters.
In this presentation, we demonstrate automated PID tuning using Bayesian optimization, applied to controlling the angular position of a DC motor shaft. The process begins with a small set of manually executed runs. For each run, the PID parameter values and the error between the measured and desired responses are recorded in a JMP data table. These data are used to initialize the JMP Bayesian Optimization platform, which then recommends a new set of PID parameter settings.
A JSL script automates the tuning process by sending the suggested PID parameters to the physical controller, acquiring the resulting error signal, and appending the new results to the same data table. JMP Bayesian Optimization is then rerun to find the parameters for the next run. This iterative cycle continues automatically until convergence is achieved.
Finally, we use Graph Builder to create displacement vs. time curves to visualize how the improvement occurred. This presentation is a practical example of combining experimentation, scripting, and Bayesian optimization in JMP to solve a real-world control problem.

Howdy. My name is Andrew Michelson.
I'm Matthew Keim.
This is our presentation on auto-tuning a PID controller using Bayesian optimization and JSL. The JMP Bayesian optimization platform is a powerful tool to quickly optimize a system or process. We employed it to find the optimal coefficients for a PID controller using JSL and Python. Our code is preloaded with a few seed values for the coefficients, which we run at the beginning of our experiment. After the seeds have completed, Bayesian optimization is then able to recommend the next set of values for the PID. These values are taken from the data table and installed onto the microcontroller for the next run. We record the response's settling time and overshoot. These values are then added back to the data table for the next run of the Bayesian optimization.
A PID controller uses the coefficients Kp, Ki, and Kd. It uses these coefficients in order to more accurately control and correct the errors in the system. In order to do this, it uses built-in equations. By changing each of these coefficients, we're able to tune the system to be more precise and fast. Common applications of a PID controller include thermostats, cruise control, and CNC motor controllers.
Our setup used a DC motor to control the position of an arm, while an encoder reads the position of the motor. The encoder is made of two Hall effect sensors, which are magnetic field sensors, and a magnet attached to the shaft of the motor. A quadrature is made from these sensors, allowing the speed and direction of the motor to be recorded. The motor receives PWM command signals from the Arduino and reads the information from the encoder. The information from the encoder is then sent back to JMP and the Bayesian optimization platform so it can recommend the next values for the coefficients.
For Bayesian optimization, we settled on two responses. The first one was settling time, how long the arm took to reach the home position. This was used to determine how quickly and therefore, how effective the PID controller was. A problem we ran into was sometimes the controller found it quicker to overshoot and come back. We also had a response for overshoot. How many degrees past home did the arm go? In order to model these two, we put them together as two responses in Bayesian optimization and developed a scoring system in order to more effectively use the PID controller.
The PID controller is made of three coefficients, the proportional, the integral, and the derivative. The proportional alters the signal based simply on the amount of error present. The integral tries to predict future error based on the previous data collected, and the derivative corrects the steady-state error found in the system. We have in the bottom left, a graphic showing different types of signals from a controller. The undamped blue case is uncontrolled and it's a simple oscillation. The red underdamped quickly reaches the zero displacement line, but overshoots it and then oscillates across it. The magenta strong damping takes a long time to reach the zero displacement, but it won't cross it. The green critically damped is the optimal target case where the displacement reaches zero as quickly as possible without overshooting.
To set up, we use a DC motor with an encoder, a motor driver board, an Arduino, and a power supply. What's not shown is the software used as well, in which we used basic Python scripting and JSL in order to communicate between everything. JSL ended up saving all the parameters and was our main source, and we just used the Python script in order to talk with the Arduino and then take from the Arduino and send it back to JMP.
Here we outline the process for our Bayesian optimization. We begin with calibrating the motor, which is setting its home position where it should return to during every run. We also have the seed runs at this time. Those are sent to the Arduino, which then runs its experiment. When the experiment is finished, the response data is then sent back to the Bayesian optimization platform, and Bayesian optimization is then run to recommend new coefficients. The cycle then repeats until we reach a satisfying point where our coefficients create a critically damped system. That's all we have.
Presenters
Skill level
- Beginner
- Intermediate
- Advanced