{"id":14806,"date":"2023-05-04T08:42:26","date_gmt":"2023-05-04T08:42:26","guid":{"rendered":"https:\/\/imperix.com\/doc\/?p=14806"},"modified":"2026-04-06T13:10:00","modified_gmt":"2026-04-06T13:10:00","slug":"pi-controller","status":"publish","type":"post","link":"https:\/\/imperix.com\/doc\/implementation\/pi-controller","title":{"rendered":"Discrete PI controller implementation"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 ez-toc-wrap-right-text counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#General-principles\" >General principles<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#PI-controller-structure\" >PI controller structure<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#Controller-type\" >Controller type<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#Controller-structure\" >Controller structure<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#Digital-implementation\" >Digital implementation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#PI-controller-tuning-strategies\" >PI controller tuning strategies<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#PI-controller-configuration\" >PI controller configuration<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#Integrator-wind-up-and-anti-windup-methods\" >Integrator wind-up and anti-windup methods<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#Reset\" >Reset<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#B-Box-B-Board-implementation\" >B-Box \/ B-Board implementation<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#Simulink-and-PLECS\" >Simulink and PLECS<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#CC-code\" >C\/C++ code<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\/#References\" >References<\/a><\/li><\/ul><\/nav><\/div>\n\n<p>This technical note addresses possible implementations for a discrete PI controller and provides general insight into PI tuning strategies. It also includes practical implementations for digital control, on <a href=\"https:\/\/imperix.com\/software\/acg-sdk\/simulink\/\">Simulink<\/a>, <a href=\"https:\/\/imperix.com\/software\/acg-sdk\/plecs\/\">PLECS<\/a> and <a href=\"https:\/\/imperix.com\/software\/cpp-sdk\">C\/C++<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-pi-controller-general-principle\"><span class=\"ez-toc-section\" id=\"General-principles\"><\/span>General principles<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>PI controllers certainly represent the most intuitive and widespread form of closed-loop (feedback) control. As such, they are frequently implemented in both continuous (analog) and discrete (digital) domains. This is notably due to their simple structure and implementation, relying on two steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The difference between the desired setpoint and the measured variable is computed. This value is considered as an error.<\/li>\n\n\n\n<li>The PI controller computes a control action that is proportional to this error (proportional part) and makes sure that the process output agrees with the setpoint in steady state (integral part).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-why-pi-and-not-pid\"><span class=\"ez-toc-section\" id=\"PI-controller-structure\"><\/span>PI controller structure<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-why-pi-and-not-pid\"><span class=\"ez-toc-section\" id=\"Controller-type\"><\/span>Controller type<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Imperix generally uses PI controllers and not PID controllers to avoid complexity and instability issues related to the derivative action. More precisely, the high-frequency gain of the derivative action can indeed cause amplification of measurement noise, which is undesirable. Also, PID controllers generally bring only little improvement when paired with first-order systems (which are very common in power electronics) <a href=\"#PI-refs\">[1]<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-pi-controller-structure\"><span class=\"ez-toc-section\" id=\"Controller-structure\"><\/span>Controller structure<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>PI controllers can be implemented either in parallel (also referred to as non-interacting), series (interacting), or mixed form <a href=\"#PI-refs\">[2]<\/a>. This article, will focus on the parallel structure of PI controllers as it allows for the full decoupling of the proportional and integral term which makes manual tuning easier. The block diagram below describes the implementation of a parallel PI controller.<\/p>\n\n\n<div class=\"wp-block-image is-resized\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"752\" height=\"284\" src=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/03\/General-principles.png\" alt=\"PI controller implementation, parallel form\" class=\"wp-image-83\" style=\"width:368px;height:auto\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/03\/General-principles.png 752w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/03\/General-principles-300x113.png 300w\" sizes=\"auto, (max-width: 752px) 100vw, 752px\" \/><figcaption class=\"wp-element-caption\">PI controller implementation, parallel form<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-pi-controller-digital-implementation\"><span class=\"ez-toc-section\" id=\"Digital-implementation\"><\/span>Digital implementation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The well-known continuous time transfer function of a PI controller, given below, should be discretized to be implemented in a digital controller. <\/p>\n\n\n\n<p>$$ (1) \\quad C(s) = k_p + \\frac{k_i}{s}$$<\/p>\n\n\n\n<p>Here, \\(k_p\\) and \\(k_i\\) are the proportional and integral gain of the controller, respectively.<\/p>\n\n\n\n<p>Usually, the main goals when discretizing a continuous function for a control system are to preserve its frequency behavior and stability characteristics. To this end, several possible discretization strategies exist, amongst which the three most common are Forward Euler, Backward Euler, and Tustin <a href=\"#PI-refs\">[3]<\/a>. Each method comes with its advantages and drawbacks, which can be summarized as follows in order to guide the choice of implementation <a href=\"#PI-refs\">[4]<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Forward Euler: Simple and computationally efficient, but suffers from poor stability.<br>$$ (2) \\quad s = \\frac{z-1}{T_s} $$<\/li>\n\n\n\n<li>Backward Euler: Unconditionally stable, but more computationally intensive than Forward Euler.<br>$$ (3) \\quad s = \\frac{z-1}{T_sz} $$<\/li>\n\n\n\n<li>Tustin: Preserves continuous-time stability and offers superior frequency accuracy compared to Euler methods, at the cost of higher implementation complexity.<br>$$ (4) \\quad s = \\frac{2}{T_s}\\frac{z-1}{z+1} $$<\/li>\n<\/ul>\n\n\n\n<p>Where \\(T_s\\) is the discrete time interval.<\/p>\n\n\n\n<p>Now, discretization methods being a broad topic and out of the scope of this article, the following section will focus on the forward Euler method. But a similar approach can be used for the other two aforementioned methods.<\/p>\n\n\n<style>.kt-accordion-id14806_dcd0df-d3 .kt-accordion-inner-wrap{column-gap:var(--global-kb-gap-md, 2rem);row-gap:10px;}.kt-accordion-id14806_dcd0df-d3 .kt-accordion-panel-inner{border-top:0px solid transparent;border-right:1px solid transparent;border-bottom:1px solid transparent;border-left:1px solid transparent;background:#ffffff;padding-top:var(--global-kb-spacing-sm, 1.5rem);padding-right:var(--global-kb-spacing-sm, 1.5rem);padding-bottom:var(--global-kb-spacing-sm, 1.5rem);padding-left:var(--global-kb-spacing-sm, 1.5rem);}.kt-accordion-id14806_dcd0df-d3 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #eeeeee;border-top-left-radius:0px;border-top-right-radius:0px;border-bottom-right-radius:0px;border-bottom-left-radius:0px;background:#ffffff;font-size:18px;line-height:24px;text-transform:capitalize;color:#444444;padding-top:14px;padding-right:16px;padding-bottom:14px;padding-left:16px;}.kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap .kt-blocks-accordion-icon-trigger:before{background:#444444;}.kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger{background:#444444;}.kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}.kt-accordion-id14806_dcd0df-d3 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id14806_dcd0df-d3 .kt-blocks-accordion-header:focus-visible{color:#444444;background:#ffffff;border-top:1px solid #d4d4d4;border-right:1px solid #d4d4d4;border-bottom:1px solid #d4d4d4;border-left:2px solid #d4d4d4;}.kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:before, body:not(.hide-focus-outline) .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-blocks-accordion--visible .kt-blocks-accordion-icon-trigger:after, body:not(.hide-focus-outline) .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:before{background:#444444;}.kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger, body:not(.hide-focus-outline) .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger{background:#444444;}.kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:before, body:not(.hide-focus-outline) .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:after, body:not(.hide-focus-outline) .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}.kt-accordion-id14806_dcd0df-d3 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id14806_dcd0df-d3 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{color:#444444;background:#ffffff;border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #0e9cd1;}.kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:before{background:#444444;}.kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger{background:#444444;}.kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_dcd0df-d3:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}@media all and (max-width: 1024px){.kt-accordion-id14806_dcd0df-d3 .kt-accordion-panel-inner{border-top:0px solid transparent;border-right:1px solid transparent;border-bottom:1px solid transparent;border-left:1px solid transparent;}}@media all and (max-width: 1024px){.kt-accordion-id14806_dcd0df-d3 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #eeeeee;}}@media all and (max-width: 1024px){.kt-accordion-id14806_dcd0df-d3 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id14806_dcd0df-d3 .kt-blocks-accordion-header:focus-visible{border-top:1px solid #d4d4d4;border-right:1px solid #d4d4d4;border-bottom:1px solid #d4d4d4;border-left:2px solid #d4d4d4;}}@media all and (max-width: 1024px){.kt-accordion-id14806_dcd0df-d3 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id14806_dcd0df-d3 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #0e9cd1;}}@media all and (max-width: 767px){.kt-accordion-id14806_dcd0df-d3 .kt-accordion-inner-wrap{display:block;}.kt-accordion-id14806_dcd0df-d3 .kt-accordion-inner-wrap .kt-accordion-pane:not(:first-child){margin-top:10px;}.kt-accordion-id14806_dcd0df-d3 .kt-accordion-panel-inner{border-top:0px solid transparent;border-right:1px solid transparent;border-bottom:1px solid transparent;border-left:1px solid transparent;}.kt-accordion-id14806_dcd0df-d3 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #eeeeee;}.kt-accordion-id14806_dcd0df-d3 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id14806_dcd0df-d3 .kt-blocks-accordion-header:focus-visible{border-top:1px solid #d4d4d4;border-right:1px solid #d4d4d4;border-bottom:1px solid #d4d4d4;border-left:2px solid #d4d4d4;}.kt-accordion-id14806_dcd0df-d3 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id14806_dcd0df-d3 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #0e9cd1;}}<\/style>\n<div class=\"wp-block-kadence-accordion alignnone\"><div class=\"kt-accordion-wrap kt-accordion-id14806_dcd0df-d3 kt-accordion-has-2-panes kt-active-pane-0 kt-accordion-block kt-pane-header-alignment-left kt-accodion-icon-style-arrow kt-accodion-icon-side-right\" style=\"max-width:none\"><div class=\"kt-accordion-inner-wrap\" data-allow-multiple-open=\"false\" data-start-open=\"none\">\n<div class=\"wp-block-kadence-pane kt-accordion-pane kt-accordion-pane-1 kt-pane14806_843455-a5\"><div class=\"kt-accordion-header-wrap\"><button class=\"kt-blocks-accordion-header kt-acccordion-button-label-show\" type=\"button\"><span class=\"kt-blocks-accordion-title-wrap\"><span class=\"kt-blocks-accordion-title\">An intuitive derivation of Discretization Functions<\/span><\/span><span class=\"kt-blocks-accordion-icon-trigger\"><\/span><\/button><\/div><div class=\"kt-accordion-panel kt-accordion-panel-hidden\"><div class=\"kt-accordion-panel-inner\">\n<p>To discretize a continuous-time system, we approximate derivatives using the Forward Euler method. The continuous time fonction: \\(\\frac{dx(t)}{dt}\\) is then approximated with the forward difference:<\/p>\n\n\n\n<p>$$ \\frac{dx(t)}{dt} \u2248 \\frac{x[n+1] &#8211; x[n]}{T_s} $$<\/p>\n\n\n\n<p>This estimates the rate of change using the next time step (hence the forward difference). <\/p>\n\n\n\n<p>Taking the Z-transform of the above leads to:<\/p>\n\n\n\n<p>$$Z\\{\\frac{x[n+1] &#8211; x[n]}{T_s}\\}= \\frac{zX(z) &#8211; X(z)}{T_s} = \\frac{z-1}{T_s}X(z) $$<\/p>\n\n\n\n<p>This results in mapping the continuous time derivation function \\(\\frac{d}{dt}\\) to \\(\\frac{z-1}{T_s}\\) in the z-domain.<\/p>\n\n\n\n<p>In the Laplace domain, differentiation corresponds to multiplication by \\(s\\). Using the forward Euler approximation, we substitute:<\/p>\n\n\n\n<p>$$ s \u2248 \\frac{z-1}{T_s} $$<\/p>\n\n\n\n<p>This allows us to translate a continuous-time model into a discrete-time one by replacing \\(s\\) with \\(s \u2248 \\frac{z-1}{T_s} \\)<\/p>\n<\/div><\/div><\/div>\n<\/div><\/div><\/div>\n\n\n\n<p>The discretized equation of the PI controller using the forward Euler method would then result in the following equation:<\/p>\n\n\n\n<p>$$ (5) \\quad C(z) = \\frac{Y(z)}{E(z)} = K_p + K_i T_s \\frac{1}{z-1} $$<\/p>\n\n\n\n<p>In the end, as the objective is to implement a PI controller inside of a digital control system, the discretized PI controller can then be translated into the following difference equations for run-time code generation:<\/p>\n\n\n\n<p>$$ (6) \\quad \\begin{aligned}<br>&amp; y(k) = P(k) + I(k) = k_p \\cdot e(k) + I(k)\\\\<br>&amp; I(k) = I(k-1) + k_i \\cdot T_s \\cdot e(k-1) \\\\<br>\\end{aligned}$$<\/p>\n\n\n\n<p>Where \\(e(k)\\) is the error input (the difference between the targeted setpoint and the measured value) and \\(y(k)\\) is the output of the PI controller.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-pi-controller-tuning-strategies\"><span class=\"ez-toc-section\" id=\"PI-controller-tuning-strategies\"><\/span>PI controller tuning strategies<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Many different strategies can be used for the tuning of PI controllers, such as Ziegler Nichols, loop shaping, optimization, pole placement, etc. Tuning should consider tradeoffs between tracking performance, load perturbance rejection, effect of measurement noise and other aspects, depending on the control requirements <a href=\"#PI-refs\">[2]<\/a>.<\/p>\n\n\n\n<p>This section will further detail a popular optimization method, the magnitude optimum, often chosen for its good tradeoff between simplicity and performance. This tuning strategy will aim for a good response to setpoint changes, with the potential drawback of poor perturbance rejection. Alternatively, the symmetric optimum criterion can be used when the focus is on disturbance rejection <a href=\"#PI-refs\">[5]<\/a>.<\/p>\n\n\n\n<p>The Magnitude (or Modulus) optimum tuning method&#8217;s objective is to design a controller so that the overall system\u2019s output (controller + plant) would exactly and instantaneously reproduce its input. That is, the overall system\u2019s transfer function would be unity <a href=\"#PI-refs\">[6]<\/a>.<\/p>\n\n\n\n<p>To derive the magnitude optimum&#8217;s parameters, a first-order plant model is considered, described in the Laplace domain, by the equation below:<\/p>\n\n\n\n<p>$$ (7) \\quad P_1(s) = \\frac{K_1}{1+s T_1}$$<\/p>\n\n\n\n<p>The PI controller transfer function is rewritten as:<\/p>\n\n\n\n<p>$$ (8) \\quad C(s) = \\frac{1+sT_n}{sT_i}$$<\/p>\n\n\n\n<p>The actuator delay is also taken into account and approximated by a first order model as well:<\/p>\n\n\n\n<p>$$ (9) \\quad D(s) = e^{(-sT_{d,tot})} \\approx \\frac{1}{1+s T_{d,tot}}$$<\/p>\n\n\n<style>.kt-accordion-id14806_fb32ee-47 .kt-accordion-inner-wrap{column-gap:var(--global-kb-gap-md, 2rem);row-gap:10px;}.kt-accordion-id14806_fb32ee-47 .kt-accordion-panel-inner{border-top:0px solid transparent;border-right:1px solid transparent;border-bottom:1px solid transparent;border-left:1px solid transparent;background:#ffffff;padding-top:var(--global-kb-spacing-sm, 1.5rem);padding-right:var(--global-kb-spacing-sm, 1.5rem);padding-bottom:var(--global-kb-spacing-sm, 1.5rem);padding-left:var(--global-kb-spacing-sm, 1.5rem);}.kt-accordion-id14806_fb32ee-47 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #eeeeee;border-top-left-radius:0px;border-top-right-radius:0px;border-bottom-right-radius:0px;border-bottom-left-radius:0px;background:#ffffff;font-size:18px;line-height:24px;color:#444444;padding-top:14px;padding-right:16px;padding-bottom:14px;padding-left:16px;}.kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap .kt-blocks-accordion-icon-trigger:before{background:#444444;}.kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger{background:#444444;}.kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}.kt-accordion-id14806_fb32ee-47 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id14806_fb32ee-47 .kt-blocks-accordion-header:focus-visible{color:#444444;background:#ffffff;border-top:1px solid #d4d4d4;border-right:1px solid #d4d4d4;border-bottom:1px solid #d4d4d4;border-left:2px solid #d4d4d4;}.kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:before, body:not(.hide-focus-outline) .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-blocks-accordion--visible .kt-blocks-accordion-icon-trigger:after, body:not(.hide-focus-outline) .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:before{background:#444444;}.kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger, body:not(.hide-focus-outline) .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger{background:#444444;}.kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:before, body:not(.hide-focus-outline) .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:after, body:not(.hide-focus-outline) .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}.kt-accordion-id14806_fb32ee-47 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id14806_fb32ee-47 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{color:#444444;background:#ffffff;border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #0e9cd1;}.kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:before{background:#444444;}.kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger{background:#444444;}.kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id14806_fb32ee-47:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}@media all and (max-width: 1024px){.kt-accordion-id14806_fb32ee-47 .kt-accordion-panel-inner{border-top:0px solid transparent;border-right:1px solid transparent;border-bottom:1px solid transparent;border-left:1px solid transparent;}}@media all and (max-width: 1024px){.kt-accordion-id14806_fb32ee-47 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #eeeeee;}}@media all and (max-width: 1024px){.kt-accordion-id14806_fb32ee-47 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id14806_fb32ee-47 .kt-blocks-accordion-header:focus-visible{border-top:1px solid #d4d4d4;border-right:1px solid #d4d4d4;border-bottom:1px solid #d4d4d4;border-left:2px solid #d4d4d4;}}@media all and (max-width: 1024px){.kt-accordion-id14806_fb32ee-47 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id14806_fb32ee-47 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #0e9cd1;}}@media all and (max-width: 767px){.kt-accordion-id14806_fb32ee-47 .kt-accordion-inner-wrap{display:block;}.kt-accordion-id14806_fb32ee-47 .kt-accordion-inner-wrap .kt-accordion-pane:not(:first-child){margin-top:10px;}.kt-accordion-id14806_fb32ee-47 .kt-accordion-panel-inner{border-top:0px solid transparent;border-right:1px solid transparent;border-bottom:1px solid transparent;border-left:1px solid transparent;}.kt-accordion-id14806_fb32ee-47 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #eeeeee;}.kt-accordion-id14806_fb32ee-47 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id14806_fb32ee-47 .kt-blocks-accordion-header:focus-visible{border-top:1px solid #d4d4d4;border-right:1px solid #d4d4d4;border-bottom:1px solid #d4d4d4;border-left:2px solid #d4d4d4;}.kt-accordion-id14806_fb32ee-47 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id14806_fb32ee-47 > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{border-top:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:1px solid #eeeeee;border-left:2px solid #0e9cd1;}}<\/style>\n<div class=\"wp-block-kadence-accordion alignnone\"><div class=\"kt-accordion-wrap kt-accordion-id14806_fb32ee-47 kt-accordion-has-3-panes kt-active-pane-0 kt-accordion-block kt-pane-header-alignment-left kt-accodion-icon-style-arrow kt-accodion-icon-side-right\" style=\"max-width:none\"><div class=\"kt-accordion-inner-wrap\" data-allow-multiple-open=\"false\" data-start-open=\"none\">\n<div class=\"wp-block-kadence-pane kt-accordion-pane kt-accordion-pane-1 kt-pane14806_695f5f-db\"><div class=\"kt-accordion-header-wrap\"><button class=\"kt-blocks-accordion-header kt-acccordion-button-label-show\" type=\"button\"><span class=\"kt-blocks-accordion-title-wrap\"><span class=\"kt-blocks-accordion-title\">Magnitude optimum criterion<\/span><\/span><span class=\"kt-blocks-accordion-icon-trigger\"><\/span><\/button><\/div><div class=\"kt-accordion-panel kt-accordion-panel-hidden\"><div class=\"kt-accordion-panel-inner\">\n<p>We then obtain the open loop transfer function for the whole system (PI controller, actuator delay, plant):<\/p>\n\n\n\n<p>$$H_{OL}(s) = C(s)D(s)P_1(s) = \\frac{1+sT_n}{sT_i} \\frac{1}{1+s T_{d,tot}} \\frac{K_1}{1+s T_1}$$<\/p>\n\n\n\n<p>Choosing the controller parameter \\(T_n = T_1\\) to eliminate the dominant time constant pole at \\(s = -1\/T_1\\), we can simplify the open loop transfer function to:<\/p>\n\n\n\n<p>$$H_{OL}(s) = \\frac{K_1}{sT_i(1+sT_{d,tot})}$$ <\/p>\n\n\n\n<p>Computing the closed loop transfer function yields:<\/p>\n\n\n\n<p>$$H_{CL}(s) = \\frac{1}{1+s\\frac{T_i}{K_1}+s^2\\frac{T_iT_{d,tot}}{K_1}}$$<\/p>\n\n\n\n<p>To compute the closed loop transfer function frequency gain, we can substitute \\(s\\) by \\(jw\\) and take the magnitude of the denominator:<\/p>\n\n\n\n<p>$$den|H_{CL}(jw)|^2 = w^4(\\frac{T_iT_{d,tot}}{K_1})^2 + w^2((\\frac{T_i}{K_1})^2-2\\frac{T_iT_{d,tot}}{K_1}) + 1$$<\/p>\n\n\n\n<p>The low-frequency term (multiplier of \\(w^2\\)) is set to 0 to get the remaining control parameter \\(T_i\\)<\/p>\n\n\n\n<p>$$(\\frac{T_i}{K_1})^2-2\\frac{T_iT_{d,tot}}{K_1} = 0 \\implies T_i = 2K_1T_{d,tot}$$<\/p>\n\n\n\n<p>This choice of \\(T_i\\) aims to keep the closed loop transfer function close to one for lower frequencies.<\/p>\n<\/div><\/div><\/div>\n<\/div><\/div><\/div>\n\n\n\n<p>The obtained generic formulas for magnitude optimum, shown below, can then be used for tuning PI controllers <a href=\"#PI-refs\">[5]<\/a>.<\/p>\n\n\n\n<p>$$ (10) \\quad \\begin{aligned}<br>&amp;T_n = T_1\\\\<br>&amp;T_i = 2 K_1 T_{d,tot}<br>\\end{aligned}$$<\/p>\n\n\n\n<p>For the symmetric optimum, the generic formulas are shown below <a href=\"#PI-refs\">[5]<\/a><\/p>\n\n\n\n<p>$$ (11) \\quad \\begin{aligned}<br>&amp;T_n = 4 T_{d,tot}\\\\<br>&amp;T_i = 8 K_1 T_{d,tot}^2<br>\\end{aligned}$$<\/p>\n\n\n\n<p>Rewriting (8) as in (1) results in the following equations for \\(K_p\\) and \\(K_i\\):<\/p>\n\n\n\n<p>$$ (12) \\quad \\begin{aligned}<br>&amp;K_p = T_n \/T_i\\\\<br>&amp;K_i = 1 \/ T_i<br>\\end{aligned}$$<\/p>\n\n\n\n<p>The parameter&nbsp;\\(T_{d,tot}\\)&nbsp;represents the sum of all the delays in the system (from the data acquisition to the control output). For a practical example of PI controller tuning, please refer to: <a href=\"https:\/\/imperix.com\/doc\/implementation\/pi-based-current-control\">PI based current control<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-pi-controller-improvements\"><span class=\"ez-toc-section\" id=\"PI-controller-configuration\"><\/span>PI controller configuration<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Several techniques are available to improve the behavior of PI controllers. For instance, anti-windup strategies, setpoint weighting, feedforward, <a href=\"https:\/\/imperix.com\/doc\/implementation\/cascaded-voltage-control\">cascaded control<\/a> are some of the improvements that can be made to conventional PI controllers <a href=\"#PI-refs\">[1]<\/a>. A strategy to limit integrator windup is given in the section below.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-integrator-wind-up-and-anti-windup-methods\"><span class=\"ez-toc-section\" id=\"Integrator-wind-up-and-anti-windup-methods\"><\/span>Integrator wind-up and anti-windup methods<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>When the control system has to adjust for a large disturbance or setpoint variation, the integrator will accumulate a significant error (wind-up) during the transient phase. This can also happen when a physical variable reaches its limits (in the case of a switched-mode power supply, the duty cycle is usually bounded between 0 and 1 for instance). So when the output finally reaches the reference, the large value accumulated by the integral term will create a significant, undesired overshoot of the output.<\/p>\n\n\n\n<p>To get rid of this unwanted effect, anti-windup algorithms can be implemented. Several techniques are commonly used such as <a href=\"#PI-refs\">[1]<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Conditional integration<\/li>\n\n\n\n<li>Back calculation <\/li>\n\n\n\n<li>Automatic reset<\/li>\n<\/ul>\n\n\n\n<p>The below illustration details the conditional integration algorithm, which will disable the integrator when the two following conditions are fulfilled:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The PI controller output saturates.<\/li>\n\n\n\n<li>The control and error signals have the same sign (When they don&#8217;t, the integrator can help push the controller&#8217;s output out of saturation).<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image is-resized\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"533\" height=\"196\" src=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/08\/Sat_algo-2.png\" alt=\"Conditional integration anti-windup algorithm for PI controllers\" class=\"wp-image-5559\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/08\/Sat_algo-2.png 533w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/08\/Sat_algo-2-300x110.png 300w\" sizes=\"auto, (max-width: 533px) 100vw, 533px\" \/><figcaption class=\"wp-element-caption\">Conditional integration anti-windup algorithm<\/figcaption><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-reset\"><span class=\"ez-toc-section\" id=\"Reset\"><\/span>Reset<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>While the control task is not actively running (during system initialization, shutdown, or when transitioning between control modes for instance) it is often necessary to prevent the integrator from accumulating error. PI controllers commonly provide an external reset mechanism to address this. As part of the imperix blockset, the <a href=\"https:\/\/imperix.com\/doc\/software\/core-state\">Core state<\/a> block outputs the appropriate reset signal which can directly be connected to the external reset input of PI controllers. Obviously, this signal is only relevant in an experimental setup and is of no use in simulation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-b-box-b-board-implementation\"><span class=\"ez-toc-section\" id=\"B-Box-B-Board-implementation\"><\/span>B-Box \/ B-Board implementation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-simulink-and-plecs\"><span class=\"ez-toc-section\" id=\"Simulink-and-PLECS\"><\/span>Simulink and PLECS<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The (discrete) PID controller blocks from Simulink and PLECS can generally be used for the implementation of control algorithms. Please refer to the page <a href=\"https:\/\/imperix.com\/doc\/implementation\/pi-based-current-control\">Current control with a PI controller<\/a> for configuration examples of both Simulink and PLECS PI controllers.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"CC-code\"><\/span>C\/C++ code<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p>The imperix IDE provides numerous pre-written and pre-optimized functions. Controllers such as P, PI, PID and PR are already available and can be found in the&nbsp;<code>controllers.h\/.cpp<\/code>&nbsp;files.<\/p>\n\n\n\n<p>As for all controllers, PI controllers are based on:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A pseudo-object&nbsp;<code>PIDcontroller<\/code>, which contains pre-computed parameters as well as state variables.<\/li>\n\n\n\n<li>A configuration function, meant to be called during&nbsp;<code>UserInit()<\/code>, named&nbsp;<code>ConfigPIDController()<\/code>.<\/li>\n\n\n\n<li>A run-time function meant to be called during the user-level ISR such as&nbsp;<code>UserInterrupt()<\/code>, named&nbsp;<code>RunPIController()<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>Note that this C\/C++ implementation of the PI controller is slightly different from the one described above. More information on this implementation can be found in [5]. <\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"253\" height=\"483\" src=\"https:\/\/cdn.imperix.com\/doc\/wp-content\/uploads\/2021\/03\/Imperix-Cpp-IDE.png\" alt=\"Imperix CPP IDE\" class=\"wp-image-101\" srcset=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/03\/Imperix-Cpp-IDE.png 253w, https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/03\/Imperix-Cpp-IDE-157x300.png 157w\" sizes=\"auto, (max-width: 253px) 100vw, 253px\" \/><figcaption class=\"wp-element-caption\">Project view in imperix CPP IDE<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"References\"><\/span>References<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p id=\"PI-refs\">[1] A. Visioli, &#8220;Practical PID Control&#8221;, 2006<br>[2] Karl J. \u00c5str\u00f6m and Tore H\u00e4gglund, \u201cAdvanced PID Control\u201d, 1995<br>[3] Buso, S. and Mattavelli, P., &#8220;Digital Control in Power Electronics: Second Edition&#8221;, 2015<br>[4] Franklin, G.F., Powell, J. and D.Workman, M.L., &#8220;Digital Control of Dynamic Systems&#8221;, 1998<br>[5] J. W. Umland and M. Safiuddin, &#8220;Magnitude and symmetric optimum criterion for the design of linear control systems: what is it and how does it compare with the others?,&#8221; in&nbsp;<em>IEEE Trans. on Industry Applications<\/em>, May-June 1990.<br>[6] Longchamp, R., &#8220;Commande num\u00e9rique de syst\u00e8mes dynamiques: cours d&#8217;automatique&#8221;, 2010<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This technical note addresses possible implementations for a discrete PI controller and provides general insight into PI tuning strategies. It also includes practical implementations for&#8230;<\/p>\n","protected":false},"author":11,"featured_media":34277,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[4],"tags":[53],"software-environments":[105,103,104],"provided-results":[],"related-products":[50,31,32,92,166,51,111,110],"guidedreadings":[],"tutorials":[126],"user-manuals":[],"coauthors":[64,65],"class_list":["post-14806","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-implementation","tag-current-control","software-environments-c-plus-plus","software-environments-matlab","software-environments-plecs","related-products-acg-sdk","related-products-b-board-pro","related-products-b-box-rcp","related-products-b-box-micro","related-products-b-box-rcp-3-0","related-products-cpp-sdk","related-products-pm","related-products-tpi","tutorials-current-controlled-buck-converter"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Discrete PI controller implementation - imperix<\/title>\n<meta name=\"description\" content=\"This article describes the general operating principle of PI controller. It also provides a discrete implementation for digital controllers.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Discrete PI controller implementation - imperix\" \/>\n<meta property=\"og:description\" content=\"This article describes the general operating principle of PI controller. It also provides a discrete implementation for digital controllers.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/imperix.com\/doc\/implementation\/pi-controller\" \/>\n<meta property=\"og:site_name\" content=\"imperix\" \/>\n<meta property=\"article:published_time\" content=\"2023-05-04T08:42:26+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-06T13:10:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2023\/05\/General-principles_500x350-02.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2084\" \/>\n\t<meta property=\"og:image:height\" content=\"1459\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Jessy An\u00e7ay, Gabriel Fernandez\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jessy An\u00e7ay, Gabriel Fernandez\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller\"},\"author\":{\"name\":\"Jessy An\u00e7ay\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#\\\/schema\\\/person\\\/53bdc49b53b03a52afee023feef62ea4\"},\"headline\":\"Discrete PI controller implementation\",\"datePublished\":\"2023-05-04T08:42:26+00:00\",\"dateModified\":\"2026-04-06T13:10:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller\"},\"wordCount\":1895,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2023\\\/05\\\/General-principles_500x350-02.png\",\"keywords\":[\"Current control\"],\"articleSection\":[\"Technical notes\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller\",\"name\":\"Discrete PI controller implementation - imperix\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2023\\\/05\\\/General-principles_500x350-02.png\",\"datePublished\":\"2023-05-04T08:42:26+00:00\",\"dateModified\":\"2026-04-06T13:10:00+00:00\",\"description\":\"This article describes the general operating principle of PI controller. It also provides a discrete implementation for digital controllers.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller#primaryimage\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2023\\\/05\\\/General-principles_500x350-02.png\",\"contentUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2023\\\/05\\\/General-principles_500x350-02.png\",\"width\":2084,\"height\":1459},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/implementation\\\/pi-controller#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Knowledge base\",\"item\":\"https:\\\/\\\/imperix.com\\\/doc\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Technical notes\",\"item\":\"https:\\\/\\\/imperix.com\\\/doc\\\/category\\\/implementation\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Discrete PI controller implementation\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#website\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/\",\"name\":\"imperix\",\"description\":\"power electronics\",\"publisher\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/imperix.com\\\/doc\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#organization\",\"name\":\"imperix\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/imperix_logo.png\",\"contentUrl\":\"https:\\\/\\\/imperix.com\\\/doc\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/imperix_logo.png\",\"width\":350,\"height\":120,\"caption\":\"imperix\"},\"image\":{\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/imperix.com\\\/doc\\\/#\\\/schema\\\/person\\\/53bdc49b53b03a52afee023feef62ea4\",\"name\":\"Jessy An\u00e7ay\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ee54f075f5969fcfd2bf6f348058cf40ca40d54a6472ac7c0a9855d036190d0a?s=96&d=mm&r=g3826f6cf12d7359812a917063d7db3c1\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ee54f075f5969fcfd2bf6f348058cf40ca40d54a6472ac7c0a9855d036190d0a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ee54f075f5969fcfd2bf6f348058cf40ca40d54a6472ac7c0a9855d036190d0a?s=96&d=mm&r=g\",\"caption\":\"Jessy An\u00e7ay\"},\"description\":\"Jessy is a power electronics engineer. At imperix, he is mostly involved with sales and project engineering. On the knowledge base, he is an active contributor to numerous notes and examples on a broad variety of topics.\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/jessy-ancay-a47615237\\\/\"],\"url\":\"https:\\\/\\\/imperix.com\\\/doc\\\/author\\\/ancay\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Discrete PI controller implementation - imperix","description":"This article describes the general operating principle of PI controller. It also provides a discrete implementation for digital controllers.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/imperix.com\/doc\/implementation\/pi-controller","og_locale":"en_US","og_type":"article","og_title":"Discrete PI controller implementation - imperix","og_description":"This article describes the general operating principle of PI controller. It also provides a discrete implementation for digital controllers.","og_url":"https:\/\/imperix.com\/doc\/implementation\/pi-controller","og_site_name":"imperix","article_published_time":"2023-05-04T08:42:26+00:00","article_modified_time":"2026-04-06T13:10:00+00:00","og_image":[{"width":2084,"height":1459,"url":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2023\/05\/General-principles_500x350-02.png","type":"image\/png"}],"author":"Jessy An\u00e7ay, Gabriel Fernandez","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jessy An\u00e7ay, Gabriel Fernandez","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/imperix.com\/doc\/implementation\/pi-controller#article","isPartOf":{"@id":"https:\/\/imperix.com\/doc\/implementation\/pi-controller"},"author":{"name":"Jessy An\u00e7ay","@id":"https:\/\/imperix.com\/doc\/#\/schema\/person\/53bdc49b53b03a52afee023feef62ea4"},"headline":"Discrete PI controller implementation","datePublished":"2023-05-04T08:42:26+00:00","dateModified":"2026-04-06T13:10:00+00:00","mainEntityOfPage":{"@id":"https:\/\/imperix.com\/doc\/implementation\/pi-controller"},"wordCount":1895,"commentCount":0,"publisher":{"@id":"https:\/\/imperix.com\/doc\/#organization"},"image":{"@id":"https:\/\/imperix.com\/doc\/implementation\/pi-controller#primaryimage"},"thumbnailUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2023\/05\/General-principles_500x350-02.png","keywords":["Current control"],"articleSection":["Technical notes"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/imperix.com\/doc\/implementation\/pi-controller#respond"]}]},{"@type":"WebPage","@id":"https:\/\/imperix.com\/doc\/implementation\/pi-controller","url":"https:\/\/imperix.com\/doc\/implementation\/pi-controller","name":"Discrete PI controller implementation - imperix","isPartOf":{"@id":"https:\/\/imperix.com\/doc\/#website"},"primaryImageOfPage":{"@id":"https:\/\/imperix.com\/doc\/implementation\/pi-controller#primaryimage"},"image":{"@id":"https:\/\/imperix.com\/doc\/implementation\/pi-controller#primaryimage"},"thumbnailUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2023\/05\/General-principles_500x350-02.png","datePublished":"2023-05-04T08:42:26+00:00","dateModified":"2026-04-06T13:10:00+00:00","description":"This article describes the general operating principle of PI controller. It also provides a discrete implementation for digital controllers.","breadcrumb":{"@id":"https:\/\/imperix.com\/doc\/implementation\/pi-controller#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/imperix.com\/doc\/implementation\/pi-controller"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/imperix.com\/doc\/implementation\/pi-controller#primaryimage","url":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2023\/05\/General-principles_500x350-02.png","contentUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2023\/05\/General-principles_500x350-02.png","width":2084,"height":1459},{"@type":"BreadcrumbList","@id":"https:\/\/imperix.com\/doc\/implementation\/pi-controller#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Knowledge base","item":"https:\/\/imperix.com\/doc\/"},{"@type":"ListItem","position":2,"name":"Technical notes","item":"https:\/\/imperix.com\/doc\/category\/implementation"},{"@type":"ListItem","position":3,"name":"Discrete PI controller implementation"}]},{"@type":"WebSite","@id":"https:\/\/imperix.com\/doc\/#website","url":"https:\/\/imperix.com\/doc\/","name":"imperix","description":"power electronics","publisher":{"@id":"https:\/\/imperix.com\/doc\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/imperix.com\/doc\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/imperix.com\/doc\/#organization","name":"imperix","url":"https:\/\/imperix.com\/doc\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/imperix.com\/doc\/#\/schema\/logo\/image\/","url":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/03\/imperix_logo.png","contentUrl":"https:\/\/imperix.com\/doc\/wp-content\/uploads\/2021\/03\/imperix_logo.png","width":350,"height":120,"caption":"imperix"},"image":{"@id":"https:\/\/imperix.com\/doc\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/imperix.com\/doc\/#\/schema\/person\/53bdc49b53b03a52afee023feef62ea4","name":"Jessy An\u00e7ay","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/ee54f075f5969fcfd2bf6f348058cf40ca40d54a6472ac7c0a9855d036190d0a?s=96&d=mm&r=g3826f6cf12d7359812a917063d7db3c1","url":"https:\/\/secure.gravatar.com\/avatar\/ee54f075f5969fcfd2bf6f348058cf40ca40d54a6472ac7c0a9855d036190d0a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ee54f075f5969fcfd2bf6f348058cf40ca40d54a6472ac7c0a9855d036190d0a?s=96&d=mm&r=g","caption":"Jessy An\u00e7ay"},"description":"Jessy is a power electronics engineer. At imperix, he is mostly involved with sales and project engineering. On the knowledge base, he is an active contributor to numerous notes and examples on a broad variety of topics.","sameAs":["https:\/\/www.linkedin.com\/in\/jessy-ancay-a47615237\/"],"url":"https:\/\/imperix.com\/doc\/author\/ancay"}]}},"_links":{"self":[{"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts\/14806","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/comments?post=14806"}],"version-history":[{"count":237,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts\/14806\/revisions"}],"predecessor-version":[{"id":44900,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/posts\/14806\/revisions\/44900"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/media\/34277"}],"wp:attachment":[{"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/media?parent=14806"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/categories?post=14806"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/tags?post=14806"},{"taxonomy":"software-environments","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/software-environments?post=14806"},{"taxonomy":"provided-results","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/provided-results?post=14806"},{"taxonomy":"related-products","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/related-products?post=14806"},{"taxonomy":"guidedreadings","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/guidedreadings?post=14806"},{"taxonomy":"tutorials","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/tutorials?post=14806"},{"taxonomy":"user-manuals","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/user-manuals?post=14806"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/imperix.com\/doc\/wp-json\/wp\/v2\/coauthors?post=14806"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}