{"id":2141,"date":"2013-04-21T16:49:06","date_gmt":"2013-04-21T21:49:06","guid":{"rendered":"https:\/\/blogs.mathworks.com\/seth\/?p=2141"},"modified":"2017-01-04T15:40:24","modified_gmt":"2017-01-04T20:40:24","slug":"implementing-a-pid-controller-on-an-arduino-board","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2013\/04\/21\/implementing-a-pid-controller-on-an-arduino-board\/","title":{"rendered":"Implementing a PID Controller on an Arduino Board"},"content":{"rendered":"<p><em>This week my colleague <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/answers\/contributors\/2963950-pravallika\">Pravallika<\/a> is back to continue her motor control story!<\/em><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/pvinnako_tn_large.jpg\" alt=\"Pravallikota Vinnakota, guest blogger\" \/><\/p>\n<p>In my <a title=\"Estimating Continuous-Time Transfer Functions with System Identification Toolbox\" href=\"https:\/\/blogs.mathworks.com\/seth\/2012\/03\/28\/estimating-continuous-time-transfer-functions-with-system-identification-toolbox\/\">previous post<\/a>, we saw how to estimate continuous transfer functions with <a href=\"https:\/\/www.mathworks.com\/products\/sysid\/\">System Identification Toolbox<\/a>. We estimated the following transfer function for a simple DC Motor using <a href=\"https:\/\/www.mathworks.com\/help\/ident\/ref\/tfest.html\"><tt>tfest<\/tt><\/a>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2013Q2\/theIdentifiedSystem.png\" alt=\"Transfer function identified from a DC Motor\" \/><\/p>\n<p>For this transfer function, we designed the following controller using <a title=\"https:\/\/www.mathworks.com\/help\/control\/ref\/pidtune.html (link no longer works)\"><tt>pidtune<\/tt><\/a>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2013Q2\/theController.png\" alt=\"Controller generated by pidtune\" \/><\/p>\n<p>We will now implement the controller on the Arduino Uno and see how the DC motor fares with this controller. To deploy the controller on the hardware, we will use Simulink\u2019s capability to generate an executable and run it on selected hardware.<\/p>\n<p><strong>Deploying controller to the Arduino board<\/strong><\/p>\n<p>You probably noticed that the controller shown above is in a continuous form. To use it on our target, the first thing to do is to discretize it using the <a title=\"https:\/\/www.mathworks.com\/help\/control\/ref\/c2d.html (link no longer works)\"><tt>c2d<\/tt><\/a> function:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2013Q2\/discreteController.png\" alt=\"Discretizing the controller generated by pidtune\" \/><\/p>\n<p>Then we grab the <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/slref\/pidcontroller.html\">PID block<\/a> from the Simulink Library and configure it.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2013Q2\/configuringPID.png\" alt=\"PID block configuration\" \/><\/p>\n<p>To keep the PID controller\u2019s output within the limits of the hardware, we go to the PID Advanced tab and enable output saturation along with anti-windup protection.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2013Q2\/pidAdvanced.png\" alt=\"Advanced PID block configuration\" \/><\/p>\n<p>To test the controller on the hardware, we created a Simulink model using blocks from the <a href=\"https:\/\/www.mathworks.com\/hardware-support\/arduino-simulink.html\">Arduino Support Package<\/a>.<\/p>\n<p>As you can see, we receive the desired motor position from the serial port and compare it to the measured position from the Analog Input. The position error goes through the PID block which generates a voltage to be sent to the motor. We also send the measured position through the serial port.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2013Q2\/controllerModel.png\" alt=\"Controller model to be used on the Arduino board\" \/><\/p>\n<p><strong>Hardware response<\/strong><\/p>\n<p>We ran the model on the target, sent it some commands and logged the data transmitted through the serial port. Here is what it looks like:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2013Q2\/hardware_results.png\" alt=\"Data logged from our controller\" \/><\/p>\n<p>So, it does a pretty good job of tracking the reference signal. When we compare the response from the hardware to that of the simulation, we observe that they are very close! The System Identification Toolbox model is quite good.<\/p>\n<p><strong>Now it is your turn<\/strong><\/p>\n<p>How are you designing controllers when a system is difficult to model? Have you tried the Run on Target Hardware capability in Simulink to run your models on the supported boards? Let us know by leaving a <a href=\"https:\/\/blogs.mathworks.com\/seth\/?p=2141&amp;#comment\">comment here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2013Q2\/hardware_results.png\" onError=\"this.style.display ='none';\" \/><\/div>\n<p>This week my colleague Pravallika is back to continue her motor control story!<\/p>\n<p>In my previous post, we saw how to estimate continuous transfer functions with System Identification Toolbox. We&#8230; <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2013\/04\/21\/implementing-a-pid-controller-on-an-arduino-board\/\">read more >><\/a><\/p>\n","protected":false},"author":41,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[115,65,30,181],"tags":[254,247,261,319],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/2141"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/comments?post=2141"}],"version-history":[{"count":28,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/2141\/revisions"}],"predecessor-version":[{"id":6251,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/2141\/revisions\/6251"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=2141"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=2141"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=2141"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}