{"id":712,"date":"2025-10-19T11:03:16","date_gmt":"2025-10-19T09:03:16","guid":{"rendered":"https:\/\/avlos.gr\/wpress\/?p=712"},"modified":"2025-10-19T11:03:16","modified_gmt":"2025-10-19T09:03:16","slug":"pid-controller","status":"publish","type":"post","link":"https:\/\/avlos.gr\/wpress\/en\/pid-controller\/","title":{"rendered":"PID Controller"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The PID Controller is a Proportional \u2013 Integral \u2013 Derivative controller or three-term controller. It is a control loop mechanism that uses feedback and is widely used in industrial control systems and in a variety of other applications that require constantly configured control. A PID controller continuously calculates an error value e (t) as the difference between a desired setpoint (SetPoint -SP) and the current value of a measurable process variable (Process Variable PV) and applies a correction based on analog, integral and derivative term (denoted by P, I and D respectively), hence the name.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In practice, it automatically applies an accurate and responsive correction to a control function. An everyday example is cruise control in a car, where climbing a hill would reduce speed if there was only constant engine power. The controller PID algorithm restores the measured speed to the desired speed with minimal delay and exceedance by increasing the motor output power in a controlled manner.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Controller operation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The feature of the PID controller is the ability to use the three control terms of analog, integral and derivative influence on the controller output to implement accurate and optimal control. The controller block diagram shown below shows the principles of how these terms are created and applied. Displays a PID controller, which continuously calculates an error value e (t) as the difference between a desired setpoint SP = r (t) and a measured process variable PV = y (t) e (t) = r (t) -y (t) and applies a correction based on a proportional, integral and derivative term. The controller tries to minimize the error over time by adjusting a control variable u (t), such as e.g. opening a control valve,to a new value determined by a weighted sum of the control conditions.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"363\" height=\"134\" src=\"https:\/\/avlos.gr\/wpress\/wp-content\/uploads\/2025\/09\/\u0395\u03bb\u03b5\u03b3\u03ba\u03c4\u03ae\u03c2_PID_Opera.jpg\" alt=\"PID Controler\" class=\"wp-image-715\" style=\"width:303px;height:auto\" srcset=\"https:\/\/avlos.gr\/wpress\/wp-content\/uploads\/2025\/09\/\u0395\u03bb\u03b5\u03b3\u03ba\u03c4\u03ae\u03c2_PID_Opera.jpg 363w, https:\/\/avlos.gr\/wpress\/wp-content\/uploads\/2025\/09\/\u0395\u03bb\u03b5\u03b3\u03ba\u03c4\u03ae\u03c2_PID_Opera-300x111.jpg 300w\" sizes=\"auto, (max-width: 363px) 100vw, 363px\" \/><figcaption class=\"wp-element-caption\">PID Controler<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">How does the PID controller work?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The overall output of the PID controller is a combination of the three terms as shown in the figure above, P, I and D<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The term P is proportional to the current value of the error SP\u2212PV = e(t).<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"137\" height=\"29\" src=\"https:\/\/avlos.gr\/wpress\/wp-content\/uploads\/2025\/09\/Pout.jpg\" alt=\"\" class=\"wp-image-716\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For example, if the error is large and positive, the control output will be proportionally large and positive, taking into account the gain factor K<sub>p<\/sub>. Only P control (Proportional) is sufficient and a system works well when:<\/p>\n\n\n\n<p class=\"has-text-align-left wp-block-paragraph\">a. The system is simple and responds quickly.<br>b. Absolute accuracy in the final result is not required.<br>c. It is acceptable to have a little error in the steady-state (final state).<br>d. You have no problem with a constant deviation from the setpoint.<br>Thus, when only P control operates in a system, there are limitations:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li> Steady-state error:<br>a. P control cannot completely eliminate the error.<br>b. As you approach the desired value, the error decreases \u2192 so the correction also decreases \u2192 and stops before you reach the setpoint.<\/li>\n\n\n\n<li>Power limitation: <br>a. If you make the proportional coefficient Kp\u200b too large, to \u201cpush\u201d it harder, then: <br>     a1. The system becomes <strong>unstable<\/strong>. <br>     a2. You may have <strong>oscillations or overshoot.<\/strong><\/li>\n\n\n\n<li>Bad behavior in slow or complex systems: <br>a. In systems with inertia (such as thermal or mechanical), P control alone <strong>does not have time<\/strong> or is <strong>slow to react correctly<\/strong>.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">For example, let&#8217;s say you&#8217;re controlling a motor to reach a specific speed.<br>With <strong>P alone<\/strong>, it can get close to the target, but: <br>  a. It may stop at <strong>98%<\/strong> of the target and never go exactly to 100%.<br>  b. If you increase Kp, it may oscillate around 100% (overshoot \u2192 undershoot \u2192 overshoot\u2026).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Term I takes into account the previous values \u200b\u200bof the SP \u2212 PV error<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"133\" height=\"39\" src=\"https:\/\/avlos.gr\/wpress\/wp-content\/uploads\/2025\/09\/Iout.jpg\" alt=\"Iout\" class=\"wp-image-718\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">and integrates them over time to produce the term I. For example, if there is a residual error SP \u2212 PV after the analog control is applied, the term integral seeks to eliminate the residual error by adding a control result, weight K\u00a0<sub>i\u00a0<\/sub>\u00a0, due to the historical cumulative value of the error.\u00a0When the error is eliminated, the term will stop growing.\u00a0This will result in a reduction in the analog result as the error decreases, but this is offset by the increasing overall effect.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Term D is the best estimate of the future trend of the SP \u2212 PV error,<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"130\" height=\"44\" src=\"https:\/\/avlos.gr\/wpress\/wp-content\/uploads\/2025\/09\/Dout.jpg\" alt=\"Dout\" class=\"wp-image-717\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">ased on its current rate of change.\u00a0It is sometimes referred to as &#8220;prudential control&#8221;, as it essentially seeks to reduce the effect of the SP \u2212 PV error by exerting a control influence created by the rate of change of the error.\u00a0The faster the change, the greater the effect of control or damping.\u00a0The role of the constant K\u00a0<sub>d\u00a0<\/sub>\u00a0in the calculation of the correction D is important.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Application of PID controller in Code<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To implement a PID controller in code or an Arduino program, five parameters must be known:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>proportional constant K\u00a0<sub>p<\/sub><\/li>\n\n\n\n<li>integral constant K\u00a0<sub>i<\/sub><\/li>\n\n\n\n<li>and derivative constant K\u00a0<sub>d<\/sub><\/li>\n\n\n\n<li>entry price (PV)<\/li>\n\n\n\n<li>and set point value (SP)<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The PID calculation must be inside a loop function.\u00a0The first part of the function should be to determine the time elapsed.<br>In Arduino, the current time can be determined with the millis () function and the elapsed time is simply:<br>currentTime = millis ();<br>elapsedTime = currentTime &#8211; previousTime;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, the error must be identified:<br>error = setPoint &#8211; input;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Programming on an Arduino simplifies the calculations a lot by using the PID_v1 library.&nbsp;In the example I give you I used the PID_v1 library.<br>In any case it is necessary to determine the three constants P, I, D. This determination is usually done experimentally and is a laborious process.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Construction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This construction is a continuation of the previous one I did with the two servo motors. In this construction I have added the MPU-9250 sensor which will \u201cdrive\u201d the servo motors. See more <a href=\"https:\/\/avlos.gr\/wpress\/%CE%B1%CE%B9%CF%83%CE%B8%CE%B7%CF%84%CE%AE%CF%81%CE%B1%CF%82-%CE%BA%CE%AF%CE%BD%CE%B7%CF%83%CE%B7%CF%82\/\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<br>The most important thing for the construction is the software that we will write so that the movement of the servo motors is now controlled by the sensor and is done smoothly, without oscillations and brings the system to the desired (horizontal) position.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The code of the construction for Arduino UNO is shown below and can be downloaded from <a href=\"https:\/\/avlos.gr\/wpress\/download\/%CE%B5%CE%BB%CE%B5%CE%B3%CE%BA%CF%84%CE%AE%CF%82-pid-%CF%83%CE%B5-%CF%83%CE%B5%CF%81%CE%B2%CE%BF%CE%BA%CE%B9%CE%BD%CE%B7%CF%84%CE%AE%CF%81%CE%B5%CF%82\/\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>\/********************************************************\n* Author : Manolis Aristovoulidis\n* \u03a4\u03bf \u03c0\u03c1\u03cc\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1 \u03b1\u03c5\u03c4\u03cc \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b5\u03af \u03ad\u03bd\u03b1\u03bd \u03b1\u03b9\u03c3\u03b8\u03b7\u03c4\u03ae\u03c1\u03b1 \u03ba\u03af\u03bd\u03b7\u03c3\u03b7\u03c2 MPU-9250, \n* \u03b4\u03cd\u03bf \u03c3\u03b5\u03c1\u03b2\u03bf\u03ba\u03b9\u03bd\u03b7\u03c4\u03ae\u03c1\u03b5\u03c2 \u03ba\u03b1\u03b9 \u03ad\u03bb\u03b5\u03b3\u03c7\u03bf PID \u03c3\u03c4\u03b7\u03bd \u03ba\u03af\u03bd\u03b7\u03c3\u03b7 \u03c4\u03c9\u03bd \u03c3\u03b5\u03c1\u03b2\u03bf\u03ba\u03b9\u03bd\u03b7\u03c4\u03ae\u03c1\u03c9\u03bd.\n* \u039c\u03b5 \u03c4\u03b7 \u03bb\u03b5\u03b9\u03c4\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03c4\u03bf\u03c5 \u03c0\u03c1\u03bf\u03b3\u03c1\u03ac\u03bc\u03bc\u03b1\u03c4\u03bf\u03c2 \u03bf\u03b9\u03c3\u03b5\u03c1\u03b2\u03bf\u03ba\u03b9\u03bd\u03b7\u03c4\u03ae\u03c1\u03b5\u03c2 \u03ba\u03c1\u03b1\u03c4\u03bf\u03c5\u03bd \u03c0\u03ac\u03bd\u03c4\u03b1 \u03c3\u03b5\n* \u03bf\u03c1\u03b9\u03b6\u03cc\u03bd\u03c4\u03b9\u03b1 \u03b8\u03ad\u03c3\u03b7 \u03c4\u03bf\u03bd \u03b1\u03b9\u03c3\u03b8\u03b7\u03c4\u03ae\u03c1\u03b1 \u03cc\u03c0\u03c9\u03c2 \u03ba\u03b1\u03b9 \u03bd\u03b1 \u03c0\u03b5\u03c1\u03b9\u03c3\u03c4\u03c1\u03ad\u03c8\u03bf\u03c5\u03bc\u03b5 \u03c4\u03b7 \u03b2\u03ac\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03ba\u03b1\u03c4\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae\u03c2\n* \n* This program uses an MPU-9250 motion sensor,\n* two servomotors and PID control in servomotors.\n* With the operation of the program, motors always keep on\n* position the sensor horizontally as well as rotate the base of the construction\n* Date : 27\/11\/2021\n* \n ********************************************************\/\n#include &lt;Wire.h>\n#include &lt;MPU9250.h>\n#include &lt;Servo.h>\n#include &lt;PID_v1.h>\n\nServo servo_x;      \/\/ \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03b5\u03bd\u03cc\u03c2 servo object \u03b3\u03b9\u03b1 \u03c4\u03bf\u03bd \u03ad\u03bb\u03b5\u03b3\u03c7\u03bf \u03c4\u03bf\u03c5 servo\nServo servo_y;      \/\/ creating a servo object to control the servo\n\nint val_x = 100;     \/\/ \u0391\u03c1\u03c7\u03b9\u03ba\u03ae \u03b3\u03c9\u03bd\u03b9\u03b1 \u03b3\u03b9\u03b1 \u03c4\u03bf servo_x    Home corner for servo_x\nint val_y = 100;    \/\/ \u0391\u03c1\u03c7\u03b9\u03ba\u03ae \u03b3\u03c9\u03bd\u03b9\u03b1 \u03b3\u03b9\u03b1 \u03c4\u03bf servo_y    Home corner for servo_y\n\n \/\/ an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68\n MPU9250 IMU(Wire,0x68);\n \nint status;\n\n \/\/Acc Variables\n\nfloat rad_to_deg = 180\/3.141592654;           \/\/\u0391\u03c5\u03c4\u03ae \u03b7 \u03c4\u03b9\u03bc\u03ae \u03b5\u03af\u03bd\u03b1\u03b9 \u03b3\u03b9\u03b1 \u03c4\u03b7 \u03bc\u03b5\u03c4\u03b1\u03c4\u03c1\u03bf\u03c0\u03ae \u03b1\u03ba\u03c4\u03b9\u03bd\u03af\u03c9\u03bd \u03c3\u03b5 \u03bc\u03bf\u03af\u03c1\u03b5\u03c2\nfloat Acc_rawX, Acc_rawY, Acc_rawZ;           \/\/\u0395\u03b4\u03ce \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03bf\u03c5\u03bc\u03b5 \u03b1\u03bd\u03b5\u03c0\u03b5\u03be\u03ad\u03c1\u03b3\u03b1\u03c3\u03c4\u03b1 \u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03b1\u03c0\u03cc \u03c4\u03bf \u03b5\u03c0\u03b9\u03c4\u03b1\u03c7\u03c5\u03bd\u03c3\u03b9\u03cc\u03bc\u03b5\u03c4\u03c1\u03bf\nfloat Acc_angle_x, Acc_angle_y;               \/\/\u0395\u03b4\u03ce \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03bf\u03c5\u03bc\u03b5 \u03c4\u03b9\u03c2 \u03c4\u03b9\u03bc\u03ad\u03c2 \u03b3\u03c9\u03bd\u03af\u03b1\u03c2 \u03c0\u03bf\u03c5 \u03c5\u03c0\u03bf\u03bb\u03bf\u03b3\u03af\u03c3\u03b1\u03bc\u03b5 \u03b3\u03b9\u03b1 \u03c4\u03bf \u03b5\u03c0\u03b9\u03c4\u03b1\u03c7\u03c5\u03bd\u03c3\u03b9\u03cc\u03bc\u03b5\u03c4\u03c1\u03bf\nfloat SUp_Acc_angle_x, SUp_Acc_angle_y;        \/\/SetUp angles\nfloat Gyr_rawX, Gyr_rawY, Gyr_rawZ;           \/\/\u0395\u03b4\u03ce \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03bf\u03c5\u03bc\u03b5 \u03b1\u03bd\u03b5\u03c0\u03b5\u03be\u03ad\u03c1\u03b3\u03b1\u03c3\u03c4\u03b1 \u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03b1\u03c0\u03cc \u03c4\u03bf \u03b3\u03c5\u03c1\u03bf\u03c3\u03ba\u03cc\u03c0\u03b9\u03bf\nfloat Gyro_angle_x, Gyro_angle_y;             \/\/\u0395\u03b4\u03ce \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03bf\u03c5\u03bc\u03b5 \u03c4\u03b9\u03c2 \u03c4\u03b9\u03bc\u03ad\u03c2 \u03b3\u03c9\u03bd\u03af\u03b1\u03c2 \u03c0\u03bf\u03c5 \u03c5\u03c0\u03bf\u03bb\u03bf\u03b3\u03af\u03c3\u03b1\u03bc\u03b5 \u03b3\u03b9\u03b1 \u03c4\u03bf \u03b3\u03c5\u03c1\u03bf\u03c3\u03ba\u03cc\u03c0\u03b9\u03bf\n\nfloat Total_angle_x, Total_angle_y;           \/\/\u0395\u03b4\u03ce \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03bf\u03c5\u03bc\u03b5 \u03c4\u03b9\u03c2 \u03c4\u03b5\u03bb\u03b9\u03ba\u03b5\u03c2 \u03bf\u03bb\u03b9\u03ba\u03ad\u03c2 \u03b3\u03c9\u03bd\u03af\u03b5\u03c2\nfloat elapsedTime, timeNow, timePrev;         \/\/\u039c\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ad\u03c2 \u03b3\u03b9\u03b1 \u03c4\u03bf\u03bd \u03ad\u03bb\u03b5\u03b3\u03c7\u03bf \u03c7\u03c1\u03cc\u03bd\u03bf\u03c5\n\n\n\/\/\u039a\u03b1\u03b8\u03bf\u03c1\u03af\u03b6\u03bf\u03c5\u03bc\u03b5 \u03c4\u03b9\u03c2 \u03bc\u03b5\u03c4\u03b1\u03b2\u03bb\u03b7\u03c4\u03ad\u03c2 \u03c0\u03bf\u03c5 \u03b8\u03b1 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03bf\u03cd\u03bd \u03bc\u03b5 \u03c4\u03b1 \u03b1\u03bd\u03c4\u03b9\u03ba\u03b5\u03af\u03bc\u03b5\u03bd\u03b1 PID_x \u03ba\u03b1\u03b9 PID_y\ndouble Setpoint_x, Input_x, Output_x;\ndouble Setpoint_y, Input_y, Output_y;\n\n\/\/\u039a\u03b1\u03b8\u03bf\u03c1\u03af\u03b6\u03bf\u03c5\u03bc\u03b5 \u03c4\u03b9\u03c2 \u03b1\u03c1\u03c7\u03b9\u03ba\u03ad\u03c2 \u03c0\u03b1\u03c1\u03b1\u03bc\u03ad\u03c4\u03c1\u03bf\u03c5\u03c2 \u03c3\u03c5\u03bd\u03c4\u03bf\u03bd\u03b9\u03c3\u03bc\u03bf\u03cd\ndouble x_Kp=2.0, x_Ki=0.5, x_Kd=0.01;\ndouble y_Kp=2.0, y_Ki=0.5, y_Kd=0.01;\n\n\/\/\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03bf\u03cd\u03bc\u03b5 \u03c4\u03b1 \u03b1\u03bd\u03c4\u03b9\u03ba\u03b5\u03af\u03bc\u03b5\u03bd\u03b1 PID\nPID PID_x(&amp;Input_x, &amp;Output_x, &amp;Setpoint_x, x_Kp, x_Ki, x_Kd, DIRECT);\nPID PID_y(&amp;Input_y, &amp;Output_y, &amp;Setpoint_y, y_Kp, y_Ki, y_Kd, DIRECT);\n\nvoid setup()\n{\n  Serial.begin(115200);\n  while(!Serial) {}\n\n    servo_x.attach(4);    \/\/\u03ba\u03ac\u03bd\u03b5\u03b9 \u03c0\u03c1\u03bf\u03c3\u03ac\u03c1\u03c4\u03b7\u03c3\u03b7 \u03c4\u03bf\u03c5 servo \u03c3\u03c4\u03bf pin 4 \u03c4\u03bf\u03c5 servo object \/\/ attachs the servo to pin 4 of   the servo object\n    servo_y.attach(5);    \/\/\u03ba\u03ac\u03bd\u03b5\u03b9 \u03c0\u03c1\u03bf\u03c3\u03ac\u03c1\u03c4\u03b7\u03c3\u03b7 \u03c4\u03bf\u03c5 servo \u03c3\u03c4\u03bf pin 5 \u03c4\u03bf\u03c5 servo object \/\/ attachs the servo to pin 5 of the servo object\n  \n    \/\/\u03c0\u03b5\u03c1\u03b9\u03c3\u03c4\u03bf\u03c6\u03ae \u03c4\u03c9\u03bd \u03c3\u03b5\u03c1\u03b2\u03bf\u03ba\u03b9\u03bd\u03b7\u03c4\u03ae\u03c1\u03c9\u03bd\n    servo_x.write(val_x);   \/\/\u039c\u03b5\u03c4\u03ac \u03b1\u03c0\u03cc \u03c0\u03b5\u03b9\u03c1\u03b1\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03bf\u03cd\u03c2 \u03b1\u03c5\u03c4\u03ae \u03b5\u03af\u03bd\u03b1\u03b9 \u03b7      \/\/After experimentation this is\n    servo_y.write(val_y);   \/\/\u03bf\u03c1\u03b9\u03b6\u03cc\u03bd\u03c4\u03b9\u03b1 \u03b8\u03ad\u03c3\u03b7 \u03b3\u03b9\u03b1 \u03c4\u03b7 \u03b2\u03ac\u03c3\u03b7 \u03c4\u03bf\u03c5 MPU9250    \/\/ horizontal position for the MPU9250 base\n\n    delay(1000);\n\n    \/\/ start communication with IMU\n    status = IMU.begin();\n    if (status &lt; 0) {\n      Serial.println(\"IMU initialization unsuccessful\");\n      Serial.println(\"Check IMU wiring or try cycling power\");\n      Serial.print(\"Status: \");\n      Serial.println(status);\n      while(1) {}\n    }\n  \/* Default values of MPU9250\n   * accel range to 16G as default \n   * gyro range to 2000DPS as default\n   * bandwidth to 184Hz as default\n   * sample rate divider to 0 as default\n   *\n   *\/\n   delay(3000);\n\n    IMU.readSensor();\n    Acc_rawX = IMU.getAccelX_mss();\n    Acc_rawY = IMU.getAccelY_mss();\n    Acc_rawZ = IMU.getAccelZ_mss();\n\n    \n      \n    \/*---Y---*\/\n    SUp_Acc_angle_x = (atan((Acc_rawY)\/sqrt(pow((Acc_rawX),2) + pow((Acc_rawZ),2)))*rad_to_deg) ;\n    \/*---Y---*\/\n    SUp_Acc_angle_y = (atan(-1*(Acc_rawX)\/sqrt(pow((Acc_rawY),2) + pow((Acc_rawZ),2)))*rad_to_deg) ;  \n  \n  \/\/Input_x = 0.0;\n  Input_x = SUp_Acc_angle_x;\n  Setpoint_x = SUp_Acc_angle_x;\n  \/\/Setpoint_x = 0.0;\n\n  \/\/Input_y = 0.0;\n  \/\/Setpoint_y = 0.0;\n  Input_y = SUp_Acc_angle_y;\n  Setpoint_y = SUp_Acc_angle_y;\n\n  double mini = -90;\n  double maxi = 90;\n  PID_x.SetOutputLimits(mini, maxi);  \/\/\u03bf\u03c1\u03af\u03b6\u03bf\u03c5\u03bc\u03b5 \u03c4\u03b1 \u03cc\u03c1\u03b9\u03b1 \u03b5\u03bb\u03ac\u03c7\u03b9\u03c3\u03c4\u03b7\u03c2 - \u03bc\u03ad\u03b3\u03b9\u03c3\u03c4\u03b7\u03c2 \u03c4\u03b9\u03bc\u03ae\u03c2 \u03c0\u03bf\u03c5 \n  PID_y.SetOutputLimits(mini, maxi);  \/\/\u03b8\u03b1 \u03bc\u03b1\u03c2 \u03b5\u03c0\u03b9\u03c3\u03c4\u03c1\u03ad\u03c6\u03b5\u03b9 \u03bf \u03bc\u03b7\u03c7\u03b1\u03bd\u03b9\u03c3\u03bc\u03cc\u03c2 \u03b5\u03bb\u03ad\u03b3\u03c7\u03bf\u03c5 PID\n  \/\/turn the PID on\n  PID_x.SetMode(AUTOMATIC);\n  PID_y.SetMode(AUTOMATIC);\n}\n\nvoid loop()\n{\n  timePrev = timeNow;  \/\/ \u03b7 \u03c0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03b7 \u03ce\u03c1\u03b1 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03b5\u03c4\u03b1\u03b9 \u03c0\u03c1\u03b9\u03bd \u03b4\u03b9\u03b1\u03b2\u03ac\u03c3\u03bf\u03c5\u03bc\u03b5 \u03c4\u03b7\u03bd \u03c0\u03c1\u03b1\u03b3\u03bc\u03b1\u03c4\u03b9\u03ba\u03ae \u03ce\u03c1\u03b1\n  timeNow = millis();  \/\/ \u0391\u03bd\u03ac\u03b3\u03bd\u03c9\u03c3\u03b7 \u03c0\u03c1\u03b1\u03b3\u03bc\u03b1\u03c4\u03b9\u03ba\u03ae\u03c2 \u03ce\u03c1\u03b1\u03c2\n  elapsedTime = (timeNow - timePrev) \/ 1000;  \n  \n  IMU.readSensor();\n  Acc_rawX = IMU.getAccelX_mss();\n  Acc_rawY = IMU.getAccelY_mss();\n  Acc_rawZ = IMU.getAccelZ_mss();\n\n  Gyr_rawX=IMU.getGyroX_rads();     \n  Gyr_rawY=IMU.getGyroY_rads();\n\n  \/*---Y---*\/\n  Acc_angle_x = (atan((Acc_rawY)\/sqrt(pow((Acc_rawX),2) + pow((Acc_rawZ),2)))*rad_to_deg) ;\n  \/*---Y---*\/\n  Acc_angle_y = (atan(-1*(Acc_rawX)\/sqrt(pow((Acc_rawY),2) + pow((Acc_rawZ),2)))*rad_to_deg) ;  \n\n  Gyro_angle_x = Gyr_rawX*elapsedTime;\n  \/*---X---*\/\n  Gyro_angle_y = Gyr_rawY*elapsedTime;\n\n  \n  Total_angle_x = 0.98 *(Total_angle_x + Gyro_angle_x) + 0.02*Acc_angle_x;\n  Total_angle_y = 0.98 *(Total_angle_y + Gyro_angle_y) + 0.02*Acc_angle_y;\n  \n  Input_x = Total_angle_x;\n  Input_y = Total_angle_y;\n     \n  PID_x.Compute();\n  PID_y.Compute();\n  \n  servo_x.write(Output_x + val_x );        \/\/ \u03c1\u03c5\u03b8\u03bc\u03af\u03b6\u03b5\u03b9 \u03c4\u03b7 \u03b8\u03ad\u03c3\u03b7 \u03c4\u03bf\u03c5 servo \u03c3\u03c4\u03b7\u03bd \u03c4\u03b9\u03bc\u03ae \u03c4\u03b7\u03c2 \u03ba\u03bb\u03af\u03bc\u03b1\u03ba\u03b1\u03c2\n  servo_y.write(val_y - Output_y); \n  \/\/Serial.print(Input_x);                   \/\/ \u03b5\u03ba\u03c4\u03c5\u03c0\u03ce\u03c3\u03b5\u03b9\u03c2 \u03b3\u03b9\u03b1 \u03c4\u03b7\u03bd \u03c0\u03b1\u03c1\u03b1\u03ba\u03bf\u03bb\u03bf\u03cd\u03b8\u03b7\u03c3\u03b7 \u03c4\u03bf\u03c5 \u03bc\u03b7\u03c7\u03b1\u03bd\u03b9\u03c3\u03bc\u03bf\u03cd \u03c3\u03b5 \u03bb\u03b5\u03b9\u03c4\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \n  \/\/Serial.print(\",\");\n  \/\/Serial.println(Input_y);\n  delay(40);\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Introduction The PID Controller is a Proportional \u2013 Integral \u2013 Derivative controller or three-term controller. It is a control loop mechanism that uses feedback and is widely used in industrial control systems and in a variety of other applications that&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29,75],"tags":[73],"class_list":["post-712","post","type-post","status-publish","format-standard","hentry","category-home","category-robotics","tag-robotics"],"_links":{"self":[{"href":"https:\/\/avlos.gr\/wpress\/wp-json\/wp\/v2\/posts\/712","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/avlos.gr\/wpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/avlos.gr\/wpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/avlos.gr\/wpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/avlos.gr\/wpress\/wp-json\/wp\/v2\/comments?post=712"}],"version-history":[{"count":10,"href":"https:\/\/avlos.gr\/wpress\/wp-json\/wp\/v2\/posts\/712\/revisions"}],"predecessor-version":[{"id":726,"href":"https:\/\/avlos.gr\/wpress\/wp-json\/wp\/v2\/posts\/712\/revisions\/726"}],"wp:attachment":[{"href":"https:\/\/avlos.gr\/wpress\/wp-json\/wp\/v2\/media?parent=712"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/avlos.gr\/wpress\/wp-json\/wp\/v2\/categories?post=712"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/avlos.gr\/wpress\/wp-json\/wp\/v2\/tags?post=712"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}