{"id":763,"date":"2022-02-10T16:39:00","date_gmt":"2022-02-10T16:39:00","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=763"},"modified":"2022-02-10T16:39:04","modified_gmt":"2022-02-10T16:39:04","slug":"stm32-and-digital-filters-finite-impulse-response-filter-fir","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=763","title":{"rendered":"STM32 and digital filters: Finite Impulse Response Filter (FIR)"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/9\/9b\/FIR_Filter.svg\/2880px-FIR_Filter.svg.png\" alt=\"\" \/><\/figure>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=734\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=734\" target=\"_blank\">here<\/a>), we took a look at the IIR filter and how to implement it on STM32 and filter the output from HMC5883L. <\/p>\n\n\n\n<p>In this guide, we shall cover the Finite Impulse Response Filter.<\/p>\n\n\n\n<p>We shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Overview of FIR filter<\/li><li>Software implementation<\/li><li>Code<\/li><li>Demo<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Overview of FIR:<\/h2>\n\n\n\n<p>In\u00a0signal processing, a\u00a0<strong>finite impulse response<\/strong>\u00a0(<strong>FIR<\/strong>)\u00a0<strong>filter<\/strong>\u00a0is a\u00a0filter\u00a0whose\u00a0impulse response\u00a0(or response to any finite length input) is of\u00a0<em>finite<\/em>\u00a0duration, because it settles to zero in finite time. This is in contrast to\u00a0infinite impulse response\u00a0(IIR) filters, which may have internal feedback and may continue to respond indefinitely (usually decaying).<\/p>\n\n\n\n<p>The\u00a0impulse response\u00a0(that is, the output in response to a\u00a0Kronecker delta\u00a0input) of an N<sup>th<\/sup>-order discrete-time FIR filter lasts exactly\u00a0<img decoding=\"async\" src=\"https:\/\/wikimedia.org\/api\/rest_v1\/media\/math\/render\/svg\/fdf2b9cbfe9051fd4e7b50c8028866d497eac35b\" alt=\"N+1\">\u00a0samples (from first nonzero element through last nonzero element) before it then settles to zero.<\/p>\n\n\n\n<p>FIR filters can be\u00a0discrete-time\u00a0or\u00a0continuous-time, and\u00a0digital\u00a0or\u00a0analog.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Bellow is a block diagram of a 8 Tap FIR filter,&nbsp;Z\u22121&nbsp;is a delay of 1 sample and b[N] are the coefficients for each Tap:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/notblackmagic.com\/bitsnpieces\/digital-filters\/img\/FIR_Filter_Block_Diagram.png\" alt=\"\" \/><\/figure>\n\n\n\n<p>For in depth overview of FIR, please check this video (<a rel=\"noreferrer noopener\" href=\"https:\/\/www.youtube.com\/watch?v=n9Cy1xkEf1E\" data-type=\"URL\" data-id=\"https:\/\/www.youtube.com\/watch?v=n9Cy1xkEf1E\" target=\"_blank\">here<\/a>).<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Software implementation:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>We start off by creating new header file named FIRFilter.h.<\/p>\n\n\n\n<p>The contents of header is as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef FIR_FILTER_H\n#define FIR_FILTER_H\n\n#include &lt;stdint.h&gt;\n\n#define FIR_FILTER_LENGTH 10\n\ntypedef struct {\n\tfloat \tbuf[FIR_FILTER_LENGTH];\n\tuint8_t bufIndex;\n\n\tfloat out;\n} FIRFilter;\n\nvoid FIRFilter_Init(FIRFilter *fir);\nfloat FIRFilter_Update(FIRFilter *fir, float inp);\n\n#endif\n<\/pre><\/div>\n\n\n\n<p>And also, we create source file with name FIR.c.<\/p>\n\n\n\n<p>The code for the source file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;FIRFilter.h&quot;\n\nstatic float FIR_IMPULSE_RESPONSE[FIR_FILTER_LENGTH] = {0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f};\n\n\nvoid FIRFilter_Init(FIRFilter *fir) {\n\n\t\/* Clear filter buffer *\/\n\tfor (uint8_t n = 0; n &lt; FIR_FILTER_LENGTH; n++) {\n\n\t\tfir-&gt;buf[n] = 0.0f;\n\n\t}\n\n\t\/* Reset buffer index *\/\n\tfir-&gt;bufIndex = 0;\n\n\t\/* Clear filter output *\/\n\tfir-&gt;out = 0.0f;\n\n}\n\nfloat FIRFilter_Update(FIRFilter *fir, float inp) {\n\n\t\/* Store latest sample in buffer *\/\n\tfir-&gt;buf[fir-&gt;bufIndex] = inp;\n\n\t\/* Increment buffer index and wrap around if necessary *\/\n\tfir-&gt;bufIndex++;\n\n\tif (fir-&gt;bufIndex == FIR_FILTER_LENGTH) {\n\n\t\tfir-&gt;bufIndex = 0;\n\n\t}\n\n\t\/* Compute new output sample (via convolution) *\/\n\tfir-&gt;out = 0.0f;\n\n\tuint8_t sumIndex = fir-&gt;bufIndex;\n\n\tfor (uint8_t n = 0; n &lt; FIR_FILTER_LENGTH; n++) {\n\n\t\t\/* Decrement index and wrap if necessary *\/\n\t\tif (sumIndex &gt; 0) {\n\n\t\t\tsumIndex--;\n\n\t\t} else {\n\n\t\t\tsumIndex = FIR_FILTER_LENGTH - 1;\n\n\t\t}\n\n\t\t\/* Multiply impulse response with shifted input sample and add to output *\/\n\t\tfir-&gt;out += FIR_IMPULSE_RESPONSE[n] * fir-&gt;buf[sumIndex];\n\n\t}\n\n\t\/* Return filtered output *\/\n\treturn fir-&gt;out;\n\n}\n<\/pre><\/div>\n\n\n\n<p>In the main file, we start by including the filter library<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;FIRFilter.h&quot;<\/pre><\/div>\n\n\n\n<p>Then we declare the filter structure as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">FIRFilter FIR_Filter;<\/pre><\/div>\n\n\n\n<p>Also, we declare float to store the filtered output<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">float gx_fir;<\/pre><\/div>\n\n\n\n<p>Then we initialize the filter as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">FIRFilter_Init(&amp;FIR_Filter);<\/pre><\/div>\n\n\n\n<p>Then we can call the filter output as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">gx_fil=FIRFilter_Update(&amp;FIR_Filter,gx);<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">3. Code:<\/h2>\n\n\n\n<p>You may download the code from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/02\/FIR_Filter_STM32.zip\">FIR_Filter_STM32<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/02\/FIR_Filter_STM32.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Demo:<\/h2>\n\n\n\n<p>Since the filter is not tuned, the results are incorrect however, once it is tuned, the filter shall work without any issue<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/02\/Screen-Recording-2022-02-10-at-7.23.34-PM.mov\"><\/video><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42 <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we took a look at the IIR filter and how to implement it on STM32 and filter the output from HMC5883L. In this guide, we shall cover the Finite Impulse Response Filter. We shall cover the following: Overview of FIR filter Software implementation Code Demo 1. Overview of FIR: In\u00a0signal [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,2,11,12],"tags":[],"class_list":["post-763","post","type-post","status-publish","format-standard","hentry","category-data-structures","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/763"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=763"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/763\/revisions"}],"predecessor-version":[{"id":766,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/763\/revisions\/766"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=763"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=763"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=763"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}