{"id":40102,"date":"2025-12-15T10:48:00","date_gmt":"2025-12-15T15:48:00","guid":{"rendered":"https:\/\/www.dmcinfo.com\/?p=40102"},"modified":"2025-12-26T15:26:10","modified_gmt":"2025-12-26T20:26:10","slug":"simplifying-dsp-filters-for-embedded-systems","status":"publish","type":"post","link":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/","title":{"rendered":"Simplifying DSP Filters for Embedded Systems"},"content":{"rendered":"\n<p>Acronyms are generally scary, and DSP is no exception. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Digital_signal_processing\">Digital Signal Processing (DSP)<\/a> is the backbone of many embedded systems, yet it\u2019s often misunderstood or over-complicated. But it doesn\u2019t have to be, and in a few paragraphs, I\u2019ll show you how to implement an extremely simple but functional low-pass digital filter.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-low-pass-signal-filtering\">Low-Pass Signal Filtering<\/h2>\n\n\n\n<p>When working with embedded systems and reading data from sources prone to noisy measurements (e.g., temperature sensors), it\u2019s common to need a way to reduce high-frequency noise and reveal the slower, meaningful signal underneath. One effective approach is using a low-pass filter, which allows lower frequencies through while reducing higher frequencies. Low-pass filters are especially useful for cleaning up signals from ADCs (Analog-to-Digital Converters).<\/p>\n\n\n\n<p>Now, let&#8217;s explore how to implement a digital version of this filtering technique.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-low-pass-iir-filter\">Low-Pass IIR Filter<\/h2>\n\n\n\n<p>There are multiple types of digital filters available, but we\u2019ll focus on implementing an <a href=\"https:\/\/en.wikipedia.org\/wiki\/Infinite_impulse_response\">IIR (Infinite Impulse Response) filter<\/a>. Without diving too deeply into specifics, these filters incorporate feedback from the output into the input, effectively creating a recursive filter. Such filters are typically less complex, resulting in strong performance that is particularly valuable for embedded systems. It should be noted, however, that the feedback mechanism may impact stability, although we\u2019ll ignore this potential issue in this blog post.<\/p>\n\n\n\n<p>The actual filter calculation is very simple, we have to run this formula from <a href=\"https:\/\/en.wikipedia.org\/wiki\/Low-pass_filter#Simple_infinite_impulse_response_filter\">Wikipedia<\/a> on every input sample to calculate the output: y[i] = \u03b1 * x[i] + (1 \u2013 \u03b1) * y[i-1]<\/p>\n\n\n\n<p>Let\u2019s not get confused by all these variables yet, but simplify this formula by rearranging it a bit, primarily to minimize the number of operations to improve performance: \u200by[i] = y[i-1] + \u03b1 * (x[i] &#8211; y[i-1])<\/p>\n\n\n\n<p>We can now explain these variables:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>x[i]<\/strong> is the filter input. For example, a new sample&nbsp;we received from ADC. Remember that we must execute this calculation for each input sample<\/li>\n\n\n\n<li><strong>y[i]<\/strong> is the filter output (filtered signal)<\/li>\n\n\n\n<li><strong>y[i-1]<\/strong> is the previous output of the filter. This is the feedback I mentioned above, so the filter output considers the previous output\/state of the filter<\/li>\n\n\n\n<li><strong>a<\/strong>\u00a0is a magic coefficient that defines the filter &#8211; we\u2019ll talk about it in the next section<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-calculate-filter-coefficient\">Calculate Filter Coefficient<\/h2>\n\n\n\n<p>The magic coefficient <strong>a<\/strong> that I mentioned above determines the filter\u2019s <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cutoff_frequency\">cutoff frequency<\/a>. This means that signals above this frequency start to attenuate. At the cutoff frequency, the signal is already reduced to about 70% of its input voltage, so it is crucial to choose a cutoff frequency slightly higher than your maximum useful signal frequency.<\/p>\n\n\n\n<p>Besides the desire cutoff frequency, this coefficient also depends on the sample rate, which sounds pretty natural too.<\/p>\n\n\n\n<p>Knowing both the sampling frequency (Fs) and your desired cutoff frequency (fc), we can use an <a href=\"https:\/\/www.dmcinfo.com\/blog\/39232\/dsp-low-pass-iir-filter-calculator\/\">online calculator<\/a> to calculate this magic coefficient, <strong>a<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-filter-implementation-c\">Filter Implementation (C++)<\/h2>\n\n\n\n<p>Once you know the filter formula and the coefficient <strong>a<\/strong>, you can implement the filter easily: it&#8217;s just one line of code, which you might include, for example, in your ADC interrupt routine:<\/p>\n\n\n\n<p>    <strong>filter_output = filter_output + a * (new_sample &#8211; filter_output);&nbsp;<\/strong><\/p>\n\n\n\n<p>Note: remember that <strong>filter_output <\/strong>variable is also the previous filter state\/output, so this variable should persist between calls.<\/p>\n\n\n\n<p>It would also be nice if we could wrap the filter into a simple class and include the logic to calculate the coefficient <strong>a<\/strong>, so we don\u2019t have to think about calculating the coefficients online. This implementation is presented below.<\/p>\n\n\n\n<p><strong>Header File<\/strong><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e\"><span style=\"background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e\">C++<\/span><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/*\n* LowPassIIR.h\n*\n*  A very simple implementation of a basic low-pass IIR filter.\n*\/\n#ifndef INC_LOWPASSIIR_H_\n#define INC_LOWPASSIIR_H_\n\nclass LowPassIIR\n{\npublic:\n\t\/\/ Class constructor, calculates a coefficient based on the parameters:\n  \/\/   sample_frequency and desired cutoff frequency\n\tLowPassIIR(float sample_frequency, float cutoff_frequency);\n\n  \/\/ Call with method with each sample. It processes the sample and updates the filter\n\t\/\/   Returns filtered value\n\tfloat ProcessSample(float new_sample);\n\nprivate:\n\t\/\/ Calculated a coefficient\n\tfloat a;\n\n\t\/\/ Filter internal value\n  float y;\n};\n#endif \/* INC_LOWPASSIIR_H_ *\/<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/*<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">* LowPassIIR.h<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">*<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">*  A very simple implementation of a basic low-pass IIR filter.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">#ifndef<\/span><span style=\"color: #569CD6\"> INC_LOWPASSIIR_H_<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">#define<\/span><span style=\"color: #569CD6\"> INC_LOWPASSIIR_H_<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">LowPassIIR<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">public:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\/\/ Class constructor, calculates a coefficient based on the parameters:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">  \/\/   sample_frequency and desired cutoff frequency<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #DCDCAA\">LowPassIIR<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sample_frequency<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">cutoff_frequency<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">  \/\/ Call with method with each sample. It processes the sample and updates the filter<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\/\/   Returns filtered value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">ProcessSample<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">new_sample<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">private:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\/\/ Calculated a coefficient<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> a;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\/\/ Filter internal value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> y;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">};<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">#endif<\/span><span style=\"color: #6A9955\"> \/* INC_LOWPASSIIR_H_ *\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p><strong>C++ File<\/strong><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e\"><span style=\"background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e\">C++<\/span><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/*\n* LowPassIIR.cpp\n*  A very simple implementation of a basic low-pass IIR filter.\n*  It is based on this article: https:\/\/en.wikipedia.org\/wiki\/Low-pass_filter#Simple_infinite_impulse_response_filter\n*\tIt is important to note that the performance of this filter may not be optimal due to C++ and other overheads\n*\tTherefore, for performance-critical applications, it may make more sense to implement the core logic inside the\n* ADC interrupt for example\n*\/\n\n#include &lt;LowPassIIR.h>\n\n\/\/ Class constructor, calculates a coefficient based on the parameters: \n\/\/   sample rate and desired cutoff frequency\nLowPassIIR::LowPassIIR(float sample_frequency, float cutoff_frequency)\n{\n\t\/\/ Calculate a, based on the formula from wikipedia article\n  \/\/   https:\/\/en.wikipedia.org\/wiki\/Low-pass_filter#Simple_infinite_impulse_response_filter\n\tfloat dt = 1 \/ sample_frequency;\n\ta = 2 * 3.14159f * dt * cutoff_frequency \/ (2 * 3.14159f * dt * cutoff_frequency + 1);\n\n\t\/\/ Reset internal sum\n\ty = 0.0f;\n}\n\n\n\/\/ Call with method with each sample. It process the sample and updates the filter\n\/\/   Returns filtered value\nfloat LowPassIIR::ProcessSample(float new_sample)\n{\n\t\/\/ Update filtered value and return it\n\ty = y + a * (new_sample - y);\n\treturn y;\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/*<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">* LowPassIIR.cpp<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">*  A very simple implementation of a basic low-pass IIR filter.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">*  It is based on this article: https:\/\/en.wikipedia.org\/wiki\/Low-pass_filter#Simple_infinite_impulse_response_filter<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">*\tIt is important to note that the performance of this filter may not be optimal due to C++ and other overheads<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">*\tTherefore, for performance-critical applications, it may make more sense to implement the core logic inside the<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">* ADC interrupt for example<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">*\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">#include<\/span><span style=\"color: #569CD6\"> <\/span><span style=\"color: #CE9178\">&lt;LowPassIIR.h&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Class constructor, calculates a coefficient based on the parameters: <\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/   sample rate and desired cutoff frequency<\/span><\/span>\n<span class=\"line\"><span style=\"color: #4EC9B0\">LowPassIIR<\/span><span style=\"color: #D4D4D4\">::<\/span><span style=\"color: #DCDCAA\">LowPassIIR<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> sample_frequency, <\/span><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> cutoff_frequency)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\/\/ Calculate a, based on the formula from wikipedia article<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">  \/\/   https:\/\/en.wikipedia.org\/wiki\/Low-pass_filter#Simple_infinite_impulse_response_filter<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> dt = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> \/ sample_frequency;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\ta = <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #B5CEA8\">3.14159f<\/span><span style=\"color: #D4D4D4\"> * dt * cutoff_frequency \/ (<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\"> * <\/span><span style=\"color: #B5CEA8\">3.14159f<\/span><span style=\"color: #D4D4D4\"> * dt * cutoff_frequency + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\/\/ Reset internal sum<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\ty = <\/span><span style=\"color: #B5CEA8\">0.0f<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Call with method with each sample. It process the sample and updates the filter<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/   Returns filtered value<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">LowPassIIR<\/span><span style=\"color: #D4D4D4\">::<\/span><span style=\"color: #DCDCAA\">ProcessSample<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">float<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">new_sample<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\/\/ Update filtered value and return it<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\ty = y + a * (new_sample - y);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> y;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-will-the-dsp-filter-slow-down-my-embedded-device\">Will the DSP Filter Slow Down my Embedded Device?<\/h2>\n\n\n\n<p>DSP performance is always a concern with signal processing on embedded systems. Although this filter is so basic, it should not affect the performance too much. But let\u2019s test it.<\/p>\n\n\n\n<p>For demonstration, here is how the above class runs the STM32F429 Nucleo board with MCU configured at a modest 50MHz speed.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"780\" height=\"842\" src=\"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02160236\/dsp-filter.png\" alt=\"DSP Filter\" class=\"wp-image-40118\" srcset=\"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02160236\/dsp-filter.png 780w, https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02160236\/dsp-filter-278x300.png 278w, https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02160236\/dsp-filter-768x829.png 768w\" sizes=\"(max-width: 780px) 100vw, 780px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The first screenshot shows ADC interrupt time, without calling the filter\n<ul class=\"wp-block-list\">\n<li>\u200bThe total ADC interrupting handling time is ~3.7us\u200b<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>The second screenshot is when we are calling the <strong>ProcessSample<\/strong> method within the ADC interrupt.\n<ul class=\"wp-block-list\">\n<li>The total ADC interrupt handling time increased to ~4.3us<\/li>\n\n\n\n<li>It means that the filter adds 4.3us \u2013 3.7us = 0.6us per sample<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>This demonstrates that this low-pass filter introduces minimal overhead, making it an excellent choice for embedded systems.<\/p>\n\n\n\n<p><strong>This is a very simple illustration of DSP techniques. If you need support with DSP, whether basic or advanced, please <a href=\"https:\/\/www.dmcinfo.com\/contact#get-in-touch\">contact us today<\/a> to learn more about our solutions and how we can help you achieve your goals.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Acronyms are generally scary, and DSP is no exception. Digital Signal Processing (DSP) is the backbone of many embedded systems, yet it\u2019s often misunderstood or over-complicated. But it doesn\u2019t have to be, and in a few paragraphs, I\u2019ll show you how to implement an extremely simple but functional low-pass digital filter. Low-Pass Signal Filtering When [&hellip;]<\/p>\n","protected":false},"author":37,"featured_media":40122,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[754],"tags":[],"class_list":["post-40102","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded-development-programming"],"yoast_head":"<title>Simplifying DSP Filters for Embedded Systems | DMC, Inc.<\/title>\n<meta name=\"description\" content=\"Learn about DSP filters and how to implement an effective low-pass digital filter for cleaner signal processing.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Simplifying DSP Filters for Embedded Systems\" \/>\n<meta property=\"og:description\" content=\"Learn about DSP filters and how to implement an effective low-pass digital filter for cleaner signal processing.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/\" \/>\n<meta property=\"og:site_name\" content=\"DMC, Inc.\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/pages\/DMC-Inc\/107982009242929\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-15T15:48:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-12-26T20:26:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02171349\/dsp-filters-hero-image.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"925\" \/>\n\t<meta property=\"og:image:height\" content=\"400\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Boris Cherkasskiy\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Boris Cherkasskiy\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/\"},\"author\":{\"name\":\"Boris Cherkasskiy\",\"@id\":\"https:\/\/www.dmcinfo.com\/#\/schema\/person\/9312661578c1c0b92969c566935608f7\"},\"headline\":\"Simplifying DSP Filters for Embedded Systems\",\"datePublished\":\"2025-12-15T15:48:00+00:00\",\"dateModified\":\"2025-12-26T20:26:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/\"},\"wordCount\":769,\"publisher\":{\"@id\":\"https:\/\/www.dmcinfo.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02171349\/dsp-filters-hero-image.jpg\",\"articleSection\":[\"Embedded Development &amp; Programming\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/\",\"url\":\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/\",\"name\":\"Simplifying DSP Filters for Embedded Systems | DMC, Inc.\",\"isPartOf\":{\"@id\":\"https:\/\/www.dmcinfo.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02171349\/dsp-filters-hero-image.jpg\",\"datePublished\":\"2025-12-15T15:48:00+00:00\",\"dateModified\":\"2025-12-26T20:26:10+00:00\",\"description\":\"Learn about DSP filters and how to implement an effective low-pass digital filter for cleaner signal processing.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/#primaryimage\",\"url\":\"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02171349\/dsp-filters-hero-image.jpg\",\"contentUrl\":\"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02171349\/dsp-filters-hero-image.jpg\",\"width\":925,\"height\":400,\"caption\":\"DSP Filters\"},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dmcinfo.com\/#website\",\"url\":\"https:\/\/www.dmcinfo.com\/\",\"name\":\"DMC, Inc.\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.dmcinfo.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dmcinfo.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.dmcinfo.com\/#organization\",\"name\":\"DMC, Inc.\",\"url\":\"https:\/\/www.dmcinfo.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.dmcinfo.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/05\/27171146\/dmc-logo-1.png\",\"contentUrl\":\"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/05\/27171146\/dmc-logo-1.png\",\"width\":418,\"height\":167,\"caption\":\"DMC, Inc.\"},\"image\":{\"@id\":\"https:\/\/www.dmcinfo.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/pages\/DMC-Inc\/107982009242929\",\"https:\/\/www.instagram.com\/dmcengineering\",\"https:\/\/www.youtube.com\/DMCEngineering\",\"https:\/\/www.linkedin.com\/company\/dmc-engineering\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dmcinfo.com\/#\/schema\/person\/9312661578c1c0b92969c566935608f7\",\"name\":\"Boris Cherkasskiy\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.dmcinfo.com\/#\/schema\/person\/image\/\",\"url\":\"\/\/www.dmcinfo.com\/wp-content\/uploads\/wpo365\/profile-images\/37.png\",\"contentUrl\":\"\/\/www.dmcinfo.com\/wp-content\/uploads\/wpo365\/profile-images\/37.png\",\"caption\":\"Boris Cherkasskiy\"},\"url\":\"https:\/\/www.dmcinfo.com\/blog\/author\/borisc\/\"}]}<\/script>","yoast_head_json":{"title":"Simplifying DSP Filters for Embedded Systems | DMC, Inc.","description":"Learn about DSP filters and how to implement an effective low-pass digital filter for cleaner signal processing.","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:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/","og_locale":"en_US","og_type":"article","og_title":"Simplifying DSP Filters for Embedded Systems","og_description":"Learn about DSP filters and how to implement an effective low-pass digital filter for cleaner signal processing.","og_url":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/","og_site_name":"DMC, Inc.","article_publisher":"https:\/\/www.facebook.com\/pages\/DMC-Inc\/107982009242929","article_published_time":"2025-12-15T15:48:00+00:00","article_modified_time":"2025-12-26T20:26:10+00:00","og_image":[{"width":925,"height":400,"url":"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02171349\/dsp-filters-hero-image.jpg","type":"image\/jpeg"}],"author":"Boris Cherkasskiy","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Boris Cherkasskiy","Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/#article","isPartOf":{"@id":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/"},"author":{"name":"Boris Cherkasskiy","@id":"https:\/\/www.dmcinfo.com\/#\/schema\/person\/9312661578c1c0b92969c566935608f7"},"headline":"Simplifying DSP Filters for Embedded Systems","datePublished":"2025-12-15T15:48:00+00:00","dateModified":"2025-12-26T20:26:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/"},"wordCount":769,"publisher":{"@id":"https:\/\/www.dmcinfo.com\/#organization"},"image":{"@id":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/#primaryimage"},"thumbnailUrl":"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02171349\/dsp-filters-hero-image.jpg","articleSection":["Embedded Development &amp; Programming"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/","url":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/","name":"Simplifying DSP Filters for Embedded Systems | DMC, Inc.","isPartOf":{"@id":"https:\/\/www.dmcinfo.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/#primaryimage"},"image":{"@id":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/#primaryimage"},"thumbnailUrl":"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02171349\/dsp-filters-hero-image.jpg","datePublished":"2025-12-15T15:48:00+00:00","dateModified":"2025-12-26T20:26:10+00:00","description":"Learn about DSP filters and how to implement an effective low-pass digital filter for cleaner signal processing.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dmcinfo.com\/blog\/40102\/simplifying-dsp-filters-for-embedded-systems\/#primaryimage","url":"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02171349\/dsp-filters-hero-image.jpg","contentUrl":"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/12\/02171349\/dsp-filters-hero-image.jpg","width":925,"height":400,"caption":"DSP Filters"},{"@type":"WebSite","@id":"https:\/\/www.dmcinfo.com\/#website","url":"https:\/\/www.dmcinfo.com\/","name":"DMC, Inc.","description":"","publisher":{"@id":"https:\/\/www.dmcinfo.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dmcinfo.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.dmcinfo.com\/#organization","name":"DMC, Inc.","url":"https:\/\/www.dmcinfo.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dmcinfo.com\/#\/schema\/logo\/image\/","url":"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/05\/27171146\/dmc-logo-1.png","contentUrl":"https:\/\/cdn.dmcinfo.com\/wp-content\/uploads\/2025\/05\/27171146\/dmc-logo-1.png","width":418,"height":167,"caption":"DMC, Inc."},"image":{"@id":"https:\/\/www.dmcinfo.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/pages\/DMC-Inc\/107982009242929","https:\/\/www.instagram.com\/dmcengineering","https:\/\/www.youtube.com\/DMCEngineering","https:\/\/www.linkedin.com\/company\/dmc-engineering"]},{"@type":"Person","@id":"https:\/\/www.dmcinfo.com\/#\/schema\/person\/9312661578c1c0b92969c566935608f7","name":"Boris Cherkasskiy","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dmcinfo.com\/#\/schema\/person\/image\/","url":"\/\/www.dmcinfo.com\/wp-content\/uploads\/wpo365\/profile-images\/37.png","contentUrl":"\/\/www.dmcinfo.com\/wp-content\/uploads\/wpo365\/profile-images\/37.png","caption":"Boris Cherkasskiy"},"url":"https:\/\/www.dmcinfo.com\/blog\/author\/borisc\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/posts\/40102","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/users\/37"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/comments?post=40102"}],"version-history":[{"count":9,"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/posts\/40102\/revisions"}],"predecessor-version":[{"id":40565,"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/posts\/40102\/revisions\/40565"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/media\/40122"}],"wp:attachment":[{"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/media?parent=40102"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/categories?post=40102"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dmcinfo.com\/wp-json\/wp\/v2\/tags?post=40102"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}