<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>processamento de sinais - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/processamento-de-sinais/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Sun, 15 Feb 2026 14:26:27 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://mcu.tec.br/wp-content/uploads/2025/02/Robo-para-o-site-MCU.tec_.br-512x512-1-150x150.png</url>
	<title>processamento de sinais - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Filtro notch discreto (notch IIR) e média sincronizada (sync averaging)</title>
		<link>https://mcu.tec.br/algoritimos/filstros/filtro-notch-discreto-notch-iir-e-media-sincronizada-sync-averaging/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=filtro-notch-discreto-notch-iir-e-media-sincronizada-sync-averaging</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Tue, 24 Feb 2026 14:23:52 +0000</pubDate>
				<category><![CDATA[Filstros]]></category>
		<category><![CDATA[ADC DMA microcontrolador]]></category>
		<category><![CDATA[análise de sinais repetitivos]]></category>
		<category><![CDATA[Biquad]]></category>
		<category><![CDATA[biquad digital]]></category>
		<category><![CDATA[DSP em microcontroladores]]></category>
		<category><![CDATA[encoder sincronização]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[filtro digital]]></category>
		<category><![CDATA[filtro digital em C]]></category>
		<category><![CDATA[filtro notch IIR]]></category>
		<category><![CDATA[firmware tempo real]]></category>
		<category><![CDATA[média sincronizada]]></category>
		<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[processamento de sinais]]></category>
		<category><![CDATA[processamento digital de sinais embarcados]]></category>
		<category><![CDATA[remoção de 60Hz]]></category>
		<category><![CDATA[RP2040]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[SNR em sistemas embarcados]]></category>
		<category><![CDATA[stm32]]></category>
		<category><![CDATA[synchronous averaging]]></category>
		<category><![CDATA[tempo real]]></category>
		<category><![CDATA[zero crossing]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1356</guid>

					<description><![CDATA[<p>Fechando a ideia: o notch discreto e a média sincronizada resolvem problemas parecidos (melhorar a qualidade do sinal), mas por “mecanismos” bem diferentes, e isso muda totalmente quando cada um é a melhor escolha. O notch é a ferramenta certa quando você conhece uma frequência indesejada bem definida e relativamente estável e quer arrancá-la do sinal com o mínimo de impacto no restante do espectro. Em firmware, isso costuma ser “hum” de 50/60 Hz, tons de chaveamento, ou uma ressonância estreita que aparece como pico bem localizado. O ponto crítico é que o notch é tão bom quanto a precisão do seu (f_0) e a escolha de (Q): se a interferência varia de frequência, um notch muito estreito deixa passar; se você alarga demais, começa a “machucar” conteúdo útil perto de (f_0). Além disso, como é um IIR, você precisa cuidar de estabilidade numérica e do formato de implementação (a forma direta II transposta tende a ser mais robusta em ponto flutuante e também costuma ser a melhor porta de entrada para depois migrar para ponto fixo).</p>
<p>Já a média sincronizada não é “um filtro de frequência” no sentido clássico; ela é uma técnica de extração por coerência: tudo que está alinhado com o período de referência fica mais forte, e o que não está alinhado tende a desaparecer. Por isso ela é superior quando o sinal útil é repetitivo e você tem um marcador de fase confiável, como encoder em máquina rotativa, o próprio PWM em conversores/inversores, ou zero-cross da rede. O ganho prático é enorme porque ela aumenta SNR sem precisar “inventar” um modelo espectral do ruído, mas ela também tem uma fragilidade: se o sincronismo for ruim (jitter, período variável, marcador inconsistente) a média “borrará” a forma de onda e pode até criar artefatos que parecem sinal real. Em projetos de rede elétrica, por exemplo, se você fixa (N) como “amostras por ciclo” sem acompanhar a variação real da frequência, a média começa a perder fase ao longo dos ciclos; nesse caso, ou você mede o período e ajusta (N) dinamicamente, ou você reamostra o ciclo para um grid fixo antes de acumular.</p>
<p>Na prática, em pipeline embarcado, uma combinação muito comum é usar notch primeiro para remover uma interferência tonal forte e depois usar média sincronizada para revelar a forma repetitiva de interesse com ruído bem mais baixo. Isso funciona especialmente bem quando a interferência não é coerente com o período que você está usando para sincronizar; se for coerente, a média pode reforçar a interferência, e aí o notch vira praticamente obrigatório antes. Se o seu sistema estiver no limite de CPU, o notch custa um número fixo e pequeno de multiplicações por amostra, enquanto a média sincronizada pode custar pouco por amostra mas “cobra” um custo por período quando você atualiza a forma média; dá para manter determinismo atualizando médias de forma incremental, ou reduzindo taxa, ou usando buffers e processamento em tarefa de menor prioridade.</p>
<p>Se você me disser qual é o seu caso (por exemplo: remover 60 Hz do ADC de shunt, ou extrair assinatura de vibração sincronizada com encoder, ou limpar ripple de PWM), eu adapto os coeficientes, a estratégia de sincronismo e o código para um cenário mais “pé no chão” com ADC+DMA, saturação, e versão em ponto fixo (Q31) pronta para rodar liso em Cortex-M.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/filstros/filtro-notch-discreto-notch-iir-e-media-sincronizada-sync-averaging/">Filtro notch discreto (notch IIR) e média sincronizada (sync averaging)</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Em sistemas embarcados, “tirar uma frequência específica do sinal” costuma aparecer em dois cenários muito práticos: remover uma interferência estreita e persistente (por exemplo, 50/60 Hz de rede, ou um tom de comutação) e aumentar SNR (relação sinal-ruído) quando o fenômeno de interesse é repetitivo e existe uma referência de fase (por exemplo, rotação com encoder, comutação PWM, ou zero-cross da rede). O filtro notch discreto resolve muito bem o primeiro caso porque ele cria uma atenuação profunda numa frequência central (f_0) com pouca alteração do resto do espectro. Já a média sincronizada resolve muito bem o segundo porque ela soma ciclos “alinhados” no tempo/fase, reforçando o componente coerente e cancelando ruído não correlacionado e componentes que não encaixam exatamente naquele período.</p>



<p class="wp-block-paragraph">Quando o firmware precisa ser previsível (tempo real), o desenho do filtro não é só “matemático”: você escolhe estruturas e limites para garantir custo computacional constante, estado pequeno e estabilidade numérica, principalmente se você for para ponto fixo ou tiver ADC+DMA alimentando o pipeline. (Essa preocupação de arquitetura e previsibilidade é típica de projetos de tempo real.)</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">1) Notch discreto: o “biquad” que apaga uma frequência</h2>



<p class="wp-block-paragraph">Um notch digital clássico pode ser implementado como um biquad IIR (segunda ordem) com zeros exatamente na frequência que você quer cancelar e polos próximos, controlando a largura do “buraco” via fator de qualidade (Q). Quanto maior o (Q), mais estreito é o notch (ótimo para interferência tonal estável), mas maior a sensibilidade a variação de (f_0) e a quantização dos coeficientes. Em termos práticos: para hum de rede em 60 Hz, se o sinal tiver variação de frequência (rede oscilando, ou a interferência “escorregando”), um (Q) alto demais pode deixar “vazar” parte do ruído. Para tom de comutação de um inversor ou fonte chaveada, se o clock for estável, dá para usar (Q) alto e atacar de forma cirúrgica.</p>



<p class="wp-block-paragraph">O biquad notch mais comum pode ser escrito como:</p>



<p class="wp-block-paragraph">\[<br>H(z)=\frac{1 &#8211; 2\cos(\omega_0)z^{-1} + z^{-2}}{1 &#8211; 2r\cos(\omega_0)z^{-1} + r^2 z^{-2}}<br>\]



<p class="wp-block-paragraph">onde \(\omega_0=2\pi f_0/F_s\) e (r) controla a “proximidade” dos polos aos zeros (quanto mais perto de 1, mais estreito e mais profundo). Uma ligação prática entre (r) e (Q) é aproximar a largura de banda por \(BW \approx f_0/Q\) e usar \(r \approx e^{-\pi BW/F_s}\). Isso funciona muito bem para firmware porque você calcula coeficientes uma vez (ou quando \(f_0\) muda) e o processamento por amostra fica constante.</p>



<h3 class="wp-block-heading">Código em C: biquad notch (float) com inicialização por \(F_s, f_0, Q\)</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" 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;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;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>#include &lt;math.h>
#include &lt;stdint.h>

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

typedef struct {
    // Coeficientes normalizados (a0 = 1)
    float b0, b1, b2;
    float a1, a2;

    // Estados (forma direta II transposta)
    float z1, z2;
} NotchBiquad;

/**
 * @brief Inicializa um filtro notch IIR (biquad) em forma direta II transposta.
 * @param f     Ponteiro para a estrutura do filtro.
 * @param Fs    Frequência de amostragem (Hz).
 * @param f0    Frequência central do notch (Hz).
 * @param Q     Fator de qualidade (adimensional). Ex.: 10..50 típicos.
 *
 * Observação prática:
 *  - Q maior => notch mais estreito, mais sensível a variações de f0 e quantização.
 *  - Q menor => notch mais largo, remove mais “vizinhança” de frequências.
 */
static inline void notch_init(NotchBiquad *f, float Fs, float f0, float Q)
{
    const float w0 = 2.0f * (float)M_PI * (f0 / Fs);

    // Largura de banda aproximada (Hz)
    const float BW = f0 / Q;

    // Polo raio r (aprox.) -> define a largura do notch
    const float r = expf(-(float)M_PI * (BW / Fs));

    const float c = cosf(w0);

    // Numerador (zeros no círculo unitário em ±w0)
    const float b0 = 1.0f;
    const float b1 = -2.0f * c;
    const float b2 = 1.0f;

    // Denominador (polos em raio r)
    const float a0 = 1.0f;
    const float a1 = -2.0f * r * c;
    const float a2 = r * r;

    // Normaliza por a0 (a0=1 aqui, mas mantemos o padrão)
    f->b0 = b0 / a0;
    f->b1 = b1 / a0;
    f->b2 = b2 / a0;
    f->a1 = a1 / a0;
    f->a2 = a2 / a0;

    f->z1 = 0.0f;
    f->z2 = 0.0f;
}

/**
 * @brief Processa 1 amostra pelo biquad notch (DF-II Transposta).
 * @param f Estrutura do filtro.
 * @param x Amostra de entrada.
 * @return  Amostra filtrada.
 */
static inline float notch_process(NotchBiquad *f, float x)
{
    // DF-II transposta:
    // y = b0*x + z1
    // z1 = b1*x - a1*y + z2
    // z2 = b2*x - a2*y
    const float y = (f->b0 * x) + f->z1;
    const float z1 = (f->b1 * x) - (f->a1 * y) + f->z2;
    const float z2 = (f->b2 * x) - (f->a2 * y);

    f->z1 = z1;
    f->z2 = z2;
    return y;
}
</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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">math</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">stdint</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">ifndef</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">M_PI</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3.14159265358979323846</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">endif</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Coeficientes normalizados (a0 = 1)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b2</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a2</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Estados (forma direta II transposta)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z2</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NotchBiquad</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Inicializa um filtro notch IIR (biquad) em forma direta II transposta.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">f</span><span style="color: #616E88">     Ponteiro para a estrutura do filtro.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">Fs</span><span style="color: #616E88">    Frequência de amostragem (Hz).</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">f0</span><span style="color: #616E88">    Frequência central do notch (Hz).</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">Q</span><span style="color: #616E88">     Fator de qualidade (adimensional). Ex.: 10..50 típicos.</span></span>
<span class="line"><span style="color: #616E88"> *</span></span>
<span class="line"><span style="color: #616E88"> * Observação prática:</span></span>
<span class="line"><span style="color: #616E88"> *  - Q maior =&gt; notch mais estreito, mais sensível a variações de f0 e quantização.</span></span>
<span class="line"><span style="color: #616E88"> *  - Q menor =&gt; notch mais largo, remove mais “vizinhança” de frequências.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">notch_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">NotchBiquad</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Fs</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">f0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Q</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> w0 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Fs</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Largura de banda aproximada (Hz)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> BW </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">f0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Q</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Polo raio r (aprox.) -&gt; define a largura do notch</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> r </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">expf</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">BW</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Fs</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> c </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">cosf</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">w0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Numerador (zeros no círculo unitário em ±w0)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> b0 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> b1 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">c</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> b2 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Denominador (polos em raio r)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> a0 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> a1 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">r</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">c</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> a2 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">r</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">r</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Normaliza por a0 (a0=1 aqui, mas mantemos o padrão)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">a1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">a2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a0</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Processa 1 amostra pelo biquad notch (DF-II Transposta).</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">f</span><span style="color: #616E88"> Estrutura do filtro.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">x</span><span style="color: #616E88"> Amostra de entrada.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">return</span><span style="color: #616E88">  Amostra filtrada.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">notch_process</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">NotchBiquad</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// DF-II transposta:</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// y = b0*x + z1</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// z1 = b1*x - a1*y + z2</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// z2 = b2*x - a2*y</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> y </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z1</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> z1 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">a1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z2</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> z2 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">a2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z1</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z2</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"><strong>Melhores usos do notch:</strong> quando você conhece (ou mede) a frequência indesejada e ela é estreita, relativamente estável e você quer preservar quase tudo ao redor. Em instrumentação, isso aparece em leitura de shunt/ADC contaminada por rede; em áudio, hum; em controle, ressonância mecânica estreita (desde que não destrua margem de fase indevidamente); em eletrônica de potência, uma componente tonal em corrente/tensão.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2) Média sincronizada: “soma coerente” alinhada à fase</h2>



<p class="wp-block-paragraph">A média sincronizada (às vezes chamada de synchronous averaging, time synchronous averaging) não é “só uma média móvel”. A sacada é que você escolhe uma janela exatamente igual a um período do fenômeno repetitivo (ou múltiplos inteiros) e reinicia/alinha essa janela usando um evento de referência: um zero-cross, um pulso de encoder, um índice, ou um marcador derivado do PWM. Se você tem (N) amostras por período e faz uma média sobre (K) períodos alinhados, o componente que se repete com a mesma fase soma e cresce proporcionalmente, enquanto ruído aleatório cai como (\sqrt{K}) no RMS. Além disso, componentes que não “encaixam” naquele período tendem a se cancelar.</p>



<p class="wp-block-paragraph">Em termos de filtro, isso se comporta como um filtro tipo comb (pente) extremamente eficiente para rejeitar tudo que não é coerente com o período escolhido. A diferença para um notch é que você não está mirando uma única frequência: você está favorecendo toda a forma de onda repetitiva no domínio do tempo, desde que sincronizada.</p>



<h3 class="wp-block-heading">Código em C: média sincronizada por períodos (com referência externa)</h3>



<p class="wp-block-paragraph">A seguir vai uma implementação simples (e bem útil) para firmware: você acumula amostras de cada posição dentro do período e, a cada período completo, você atualiza a média. Isso é perfeito quando você tem um “gatilho de início de período” (por exemplo, interrupção de índice do encoder ou zero-cross).</p>



<div class="wp-block-kevinbatdorf-code-block-pro" 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;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;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>#include &lt;stdint.h>
#include &lt;string.h>

typedef struct {
    uint16_t N;          // amostras por período
    uint16_t idx;        // posição atual no período &#91;0..N-1&#93;
    uint32_t K;          // quantos períodos já acumulados (limite/controle externo)

    // Buffers de acumulação (use int64 se seu range for grande)
    int64_t *acc;        // soma por posição
    int32_t *avg;        // média por posição (resultado)
} SyncAvg;

/**
 * @brief Inicializa a média sincronizada.
 * @param s       Estrutura.
 * @param acc     Buffer de acumulação de tamanho N (int64_t).
 * @param avg     Buffer de saída média de tamanho N (int32_t).
 * @param N       Amostras por período.
 */
static inline void syncavg_init(SyncAvg *s, int64_t *acc, int32_t *avg, uint16_t N)
{
    s->N = N;
    s->idx = 0;
    s->K = 0;
    s->acc = acc;
    s->avg = avg;

    memset(s->acc, 0, (size_t)N * sizeof(int64_t));
    memset(s->avg, 0, (size_t)N * sizeof(int32_t));
}

/**
 * @brief Deve ser chamado quando ocorre o "marcador" de início de período (ex.: zero-cross ou índice do encoder).
 *        Isso força alinhamento de fase.
 */
static inline void syncavg_period_reset(SyncAvg *s)
{
    s->idx = 0;
}

/**
 * @brief Alimenta a média sincronizada com uma amostra do ADC já alinhada ao relógio de amostragem.
 * @param s Estrutura.
 * @param x Amostra (ex.: ADC já convertido para int32).
 *
 * Funcionamento:
 *  - A cada amostra, acumula na posição idx.
 *  - Ao completar N amostras, fecha um período e atualiza avg[].
 *  - A referência de fase vem de syncavg_period_reset() (externa).
 */
static inline void syncavg_push_sample(SyncAvg *s, int32_t x)
{
    s->acc&#91;s->idx&#93; += (int64_t)x;
    s->idx++;

    if (s->idx >= s->N) {
        s->idx = 0;
        s->K++;

        // Atualiza a média inteira por posição (custo O(N) por período).
        // Se N for grande e seu MCU for apertado, dá para atualizar de forma incremental.
        for (uint16_t i = 0; i &lt; s->N; i++) {
            s->avg&#91;i&#93; = (int32_t)(s->acc&#91;i&#93; / (int64_t)s->K);
        }
    }
}
</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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">stdint</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">string</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">          </span><span style="color: #616E88">// amostras por período</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">idx</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// posição atual no período &#91;0..N-1&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">K</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">          </span><span style="color: #616E88">// quantos períodos já acumulados (limite/controle externo)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Buffers de acumulação (use int64 se seu range for grande)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">acc</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// soma por posição</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">avg</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// média por posição (resultado)</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SyncAvg</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Inicializa a média sincronizada.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">s</span><span style="color: #616E88">       Estrutura.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">acc</span><span style="color: #616E88">     Buffer de acumulação de tamanho N (int64_t).</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">avg</span><span style="color: #616E88">     Buffer de saída média de tamanho N (int32_t).</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">N</span><span style="color: #616E88">       Amostras por período.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">syncavg_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">SyncAvg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">acc</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">avg</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">K</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">avg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">avg</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">memset</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">acc</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sizeof</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">memset</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">avg</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sizeof</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Deve ser chamado quando ocorre o &quot;marcador&quot; de início de período (ex.: zero-cross ou índice do encoder).</span></span>
<span class="line"><span style="color: #616E88"> *        Isso força alinhamento de fase.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">syncavg_period_reset</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">SyncAvg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">s</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Alimenta a média sincronizada com uma amostra do ADC já alinhada ao relógio de amostragem.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">s</span><span style="color: #616E88"> Estrutura.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">x</span><span style="color: #616E88"> Amostra (ex.: ADC já convertido para int32).</span></span>
<span class="line"><span style="color: #616E88"> *</span></span>
<span class="line"><span style="color: #616E88"> * Funcionamento:</span></span>
<span class="line"><span style="color: #616E88"> *  - A cada amostra, acumula na posição idx.</span></span>
<span class="line"><span style="color: #616E88"> *  - Ao completar N amostras, fecha um período e atualiza avg[].</span></span>
<span class="line"><span style="color: #616E88"> *  - A referência de fase vem de syncavg_period_reset() (externa).</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">syncavg_push_sample</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">SyncAvg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">x</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #81A1C1">++;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">K</span><span style="color: #81A1C1">++;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Atualiza a média inteira por posição (custo O(N) por período).</span></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Se N for grande e seu MCU for apertado, dá para atualizar de forma incremental.</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">avg</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF">)(</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">K</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"><strong>Melhores usos da média sincronizada:</strong> quando existe um evento/clock de referência que define o período do fenômeno e você quer extrair o comportamento repetitivo com máxima imunidade a ruído. Isso aparece em análise vibroacústica sincronizada com rotação (encoder), em medição de ripple sincronizada com PWM, em leitura de sinais biomédicos quando há marcador, e em sistemas de potência quando você quer “ver” a forma média ao longo de ciclos de rede sem ser enganado por ruído ou eventos transientes fora de fase.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3) Exemplo prático combinando os dois: remover hum e depois reforçar a forma repetitiva</h2>



<p class="wp-block-paragraph">Em pipeline real, é comum usar notch primeiro para derrubar uma interferência tonal forte e, em seguida, média sincronizada para aumentar SNR do que restou (principalmente se o sinal útil é repetitivo e você tem referência). A ordem pode inverter dependendo do caso: se a interferência também for coerente com o mesmo período, a média pode reforçá-la, então o notch antes costuma ser mais seguro.</p>



<p class="wp-block-paragraph">Abaixo, um esqueleto de uso. Imagine ADC a 4 kHz, hum em 60 Hz, e você quer fazer média sincronizada por ciclo de 60 Hz usando zero-cross (logo \(N \approx 4000/60 \approx 66\) amostras por ciclo; na prática você ajusta para manter N inteiro e usar PLL/medição de período se a rede variar).</p>



<div class="wp-block-kevinbatdorf-code-block-pro" 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;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;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>#include &lt;stdio.h>

// Reaproveita NotchBiquad e SyncAvg já definidos acima.

#define FS_HZ        4000.0f
#define NOTCH_F0_HZ  60.0f
#define NOTCH_Q      25.0f

#define N_SAMPLES_PER_PERIOD  66  // exemplo (depende do seu sincronismo real)

static int64_t acc_buf&#91;N_SAMPLES_PER_PERIOD&#93;;
static int32_t avg_buf&#91;N_SAMPLES_PER_PERIOD&#93;;

int main(void)
{
    NotchBiquad notch;
    notch_init(&amp;notch, FS_HZ, NOTCH_F0_HZ, NOTCH_Q);

    SyncAvg s;
    syncavg_init(&amp;s, acc_buf, avg_buf, N_SAMPLES_PER_PERIOD);

    // Exemplo: loop de aquisição (mock)
    for (int n = 0; n &lt; 20000; n++) {
        // Em firmware real: x_raw vem do ADC (DMA buffer), e zero-cross chama syncavg_period_reset(&amp;s)
        int32_t x_raw = (int32_t)(1000 * sinf(2.0f * (float)M_PI * 10.0f * (n / FS_HZ))); // sinal útil 10 Hz
        x_raw += (int32_t)(300 * sinf(2.0f * (float)M_PI * 60.0f * (n / FS_HZ)));        // hum 60 Hz

        // Notch (float) -> converte de volta para int32
        float y_notch = notch_process(&amp;notch, (float)x_raw);
        int32_t y = (int32_t)y_notch;

        // Evento externo de sincronismo: aqui é só demonstração (a cada N amostras)
        if ((n % N_SAMPLES_PER_PERIOD) == 0) {
            syncavg_period_reset(&amp;s);
        }

        // Média sincronizada
        syncavg_push_sample(&amp;s, y);

        // Quando s.K aumenta, avg_buf contém a forma média por período
        if (s.K > 0 &amp;&amp; (n % (N_SAMPLES_PER_PERIOD * 20)) == 0) {
            printf("K=%lu, avg&#91;0&#93;=%ld, avg&#91;10&#93;=%ld\n",
                   (unsigned long)s.K, (long)avg_buf&#91;0&#93;, (long)avg_buf&#91;10&#93;);
        }
    }

    return 0;
}
</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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">stdio</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Reaproveita NotchBiquad e SyncAvg já definidos acima.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FS_HZ</span><span style="color: #D8DEE9FF">        4000</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOTCH_F0_HZ</span><span style="color: #D8DEE9FF">  60</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOTCH_Q</span><span style="color: #D8DEE9FF">      25</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF">  </span><span style="color: #B48EAD">66</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">// exemplo (depende do seu sincronismo real)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">avg_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">main</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">NotchBiquad</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">notch</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">notch_init</span><span style="color: #D8DEE9FF">(¬</span><span style="color: #D8DEE9">ch</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FS_HZ</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOTCH_F0_HZ</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOTCH_Q</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">SyncAvg</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">syncavg_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc_buf</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">avg_buf</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Exemplo: loop de aquisição (mock)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">20000</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Em firmware real: x_raw vem do ADC (DMA buffer), e zero-cross chama syncavg_period_reset(&amp;s)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x_raw</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF">)(</span><span style="color: #B48EAD">1000</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sinf</span><span style="color: #D8DEE9FF">(2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> 10</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FS_HZ</span><span style="color: #D8DEE9FF">)))</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// sinal útil 10 Hz</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">x_raw</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF">)(</span><span style="color: #B48EAD">300</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sinf</span><span style="color: #D8DEE9FF">(2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> 60</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FS_HZ</span><span style="color: #D8DEE9FF">)))</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// hum 60 Hz</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Notch (float) -&gt; converte de volta para int32</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y_notch</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">notch_process</span><span style="color: #D8DEE9FF">(¬</span><span style="color: #D8DEE9">ch</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">x_raw</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">y_notch</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Evento externo de sincronismo: aqui é só demonstração (a cada N amostras)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> ((</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">%</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">syncavg_period_reset</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">s</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Média sincronizada</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">syncavg_push_sample</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Quando s.K aumenta, avg_buf contém a forma média por período</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">K</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">%</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">20</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">K=%lu, avg&#91;0&#93;=%ld, avg&#91;10&#93;=%ld</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                   (</span><span style="color: #D8DEE9">unsigned</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">long</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">K</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">long</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">avg_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">long</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">avg_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">10</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Fechando a ideia: o notch discreto e a média sincronizada resolvem problemas parecidos (melhorar a qualidade do sinal), mas por “mecanismos” bem diferentes, e isso muda totalmente quando cada um é a melhor escolha. O notch é a ferramenta certa quando você conhece uma frequência indesejada bem definida e relativamente estável e quer arrancá-la do sinal com o mínimo de impacto no restante do espectro. Em firmware, isso costuma ser “hum” de 50/60 Hz, tons de chaveamento, ou uma ressonância estreita que aparece como pico bem localizado. O ponto crítico é que o notch é tão bom quanto a precisão do seu (f_0) e a escolha de (Q): se a interferência varia de frequência, um notch muito estreito deixa passar; se você alarga demais, começa a “machucar” conteúdo útil perto de (f_0). Além disso, como é um IIR, você precisa cuidar de estabilidade numérica e do formato de implementação (a forma direta II transposta tende a ser mais robusta em ponto flutuante e também costuma ser a melhor porta de entrada para depois migrar para ponto fixo).</p>



<p class="wp-block-paragraph">Já a média sincronizada não é “um filtro de frequência” no sentido clássico; ela é uma técnica de extração por coerência: tudo que está alinhado com o período de referência fica mais forte, e o que não está alinhado tende a desaparecer. Por isso ela é superior quando o sinal útil é repetitivo e você tem um marcador de fase confiável, como encoder em máquina rotativa, o próprio PWM em conversores/inversores, ou zero-cross da rede. O ganho prático é enorme porque ela aumenta SNR sem precisar “inventar” um modelo espectral do ruído, mas ela também tem uma fragilidade: se o sincronismo for ruim (jitter, período variável, marcador inconsistente) a média “borrará” a forma de onda e pode até criar artefatos que parecem sinal real. Em projetos de rede elétrica, por exemplo, se você fixa (N) como “amostras por ciclo” sem acompanhar a variação real da frequência, a média começa a perder fase ao longo dos ciclos; nesse caso, ou você mede o período e ajusta (N) dinamicamente, ou você reamostra o ciclo para um grid fixo antes de acumular.</p>



<p class="wp-block-paragraph">Na prática, em pipeline embarcado, uma combinação muito comum é usar notch primeiro para remover uma interferência tonal forte e depois usar média sincronizada para revelar a forma repetitiva de interesse com ruído bem mais baixo. Isso funciona especialmente bem quando a interferência não é coerente com o período que você está usando para sincronizar; se for coerente, a média pode reforçar a interferência, e aí o notch vira praticamente obrigatório antes. Se o seu sistema estiver no limite de CPU, o notch custa um número fixo e pequeno de multiplicações por amostra, enquanto a média sincronizada pode custar pouco por amostra mas “cobra” um custo por período quando você atualiza a forma média; dá para manter determinismo atualizando médias de forma incremental, ou reduzindo taxa, ou usando buffers e processamento em tarefa de menor prioridade.</p><p>The post <a href="https://mcu.tec.br/algoritimos/filstros/filtro-notch-discreto-notch-iir-e-media-sincronizada-sync-averaging/">Filtro notch discreto (notch IIR) e média sincronizada (sync averaging)</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1356</post-id>	</item>
		<item>
		<title>Participe em nossa comunidade no Whatsapp</title>
		<link>https://mcu.tec.br/geral/participe-em-nossa-comunidade-no-whatsapp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=participe-em-nossa-comunidade-no-whatsapp</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sun, 15 Feb 2026 12:53:41 +0000</pubDate>
				<category><![CDATA[geral]]></category>
		<category><![CDATA[AIoT]]></category>
		<category><![CDATA[arquitetura embarcada]]></category>
		<category><![CDATA[comunidade técnica]]></category>
		<category><![CDATA[desenvolvimento embarcado]]></category>
		<category><![CDATA[edge computing]]></category>
		<category><![CDATA[eletrônica digital]]></category>
		<category><![CDATA[firmware]]></category>
		<category><![CDATA[FPGA]]></category>
		<category><![CDATA[grupo WhatsApp engenharia]]></category>
		<category><![CDATA[hardware digital]]></category>
		<category><![CDATA[HDL]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[MCU]]></category>
		<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[processamento de sinais]]></category>
		<category><![CDATA[rtos]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[Verilog]]></category>
		<category><![CDATA[VHDL]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1344</guid>

					<description><![CDATA[<p>Participe da Comunidade MCU e FPGA no WhatsApp e conecte-se com desenvolvedores, engenheiros, estudantes e pesquisadores que atuam com microcontroladores, FPGAs e todo o ecossistema de sistemas embarcados. Um espaço colaborativo para troca de experiências, discussão técnica sobre firmware, hardware digital, IoT, AIoT, protocolos industriais, processamento de sinais, arquiteturas embarcadas, HDL, RTOS e muito mais. Compartilhe projetos, tire dúvidas, amplie seu networking técnico e evolua junto com profissionais que vivem a engenharia na prática. Entre agora e ajude a fortalecer o ecossistema brasileiro de tecnologia embarcada.</p>
<p>The post <a href="https://mcu.tec.br/geral/participe-em-nossa-comunidade-no-whatsapp/">Participe em nossa comunidade no Whatsapp</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Faça Parte da Nossa Comunidade MCU &amp; FPGA!</strong></p>



<p class="wp-block-paragraph">Se você é apaixonado por microcontroladores, FPGAs, sistemas embarcados, eletrônica digital, IoT, AIoT, protocolos industriais, processamento de sinais ou arquitetura de hardware, este é o seu lugar.</p>



<p class="wp-block-paragraph">Criamos um espaço colaborativo no WhatsApp para reunir desenvolvedores, estudantes, pesquisadores e entusiastas que desejam evoluir juntos no universo de <strong>MCU e FPGA e todo o seu ecossistema</strong> — do firmware ao hardware, do bare-metal ao RTOS, do HDL ao edge computing.</p>



<p class="wp-block-paragraph">Aqui você poderá:</p>



<p class="wp-block-paragraph">• Trocar experiências práticas<br>• Tirar dúvidas técnicas<br>• Compartilhar projetos e artigos<br>• Discutir arquiteturas e boas práticas<br>• Conhecer novas ferramentas e tecnologias<br>• Expandir sua rede profissional</p>



<p class="wp-block-paragraph">Nosso objetivo é construir uma comunidade técnica forte, colaborativa e orientada ao crescimento real.</p>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Entre agora pelo link:</strong><br><a href="https://chat.whatsapp.com/BYXrqPHsRO5FTP7ap7X5yq">https://chat.whatsapp.com/BYXrqPHsRO5FTP7ap7X5yq</a></p>



<p class="wp-block-paragraph">Se você acredita na força do conhecimento compartilhado, convide também seus amigos, colegas de trabalho e membros de outros grupos técnicos. Quanto mais mentes engajadas, mais rico será o aprendizado de todos.</p>



<p class="wp-block-paragraph">Vamos fortalecer o ecossistema de MCU &amp; FPGA juntos.</p><p>The post <a href="https://mcu.tec.br/geral/participe-em-nossa-comunidade-no-whatsapp/">Participe em nossa comunidade no Whatsapp</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1344</post-id>	</item>
		<item>
		<title>Espectros Eletromagnéticos na Engenharia: UV, Visível, NIR e SWIR e Onde Usá-los</title>
		<link>https://mcu.tec.br/sensores/espectros-eletromagneticos-na-engenharia-uv-visivel-nir-e-swir-e-onde-usa-los/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=espectros-eletromagneticos-na-engenharia-uv-visivel-nir-e-swir-e-onde-usa-los</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 30 Jan 2026 13:28:21 +0000</pubDate>
				<category><![CDATA[Sensores]]></category>
		<category><![CDATA[agricultura de precisão]]></category>
		<category><![CDATA[câmeras multiespectrais]]></category>
		<category><![CDATA[edge computing]]></category>
		<category><![CDATA[engenharia eletrônica]]></category>
		<category><![CDATA[espectro eletromagnético]]></category>
		<category><![CDATA[espectro ultravioleta UV]]></category>
		<category><![CDATA[espectro visível]]></category>
		<category><![CDATA[identificação de materiais]]></category>
		<category><![CDATA[imageamento multiespectral]]></category>
		<category><![CDATA[infravermelho de onda curta SWIR]]></category>
		<category><![CDATA[infravermelho próximo NIR]]></category>
		<category><![CDATA[inspeção industrial]]></category>
		<category><![CDATA[iot industrial]]></category>
		<category><![CDATA[processamento de sinais]]></category>
		<category><![CDATA[sensores ópticos]]></category>
		<category><![CDATA[sensoriamento óptico]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[visão computacional]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1240</guid>

					<description><![CDATA[<p>Entenda o que são os espectros eletromagnéticos e como eles são aplicados na engenharia moderna. Este artigo apresenta, de forma técnica e didática, as principais faixas espectrais utilizadas em sistemas embarcados, visão computacional, IoT e inspeção industrial, incluindo ultravioleta (UV), espectro visível, infravermelho próximo (NIR) e infravermelho de onda curta (SWIR). O texto explica os fundamentos físicos de cada espectro, suas interações com os materiais, limitações técnicas, tipos de sensores envolvidos e critérios práticos de escolha para projetos reais. Também são discutidas combinações espectrais, impactos no processamento de sinais e na inteligência artificial embarcada, além de diretrizes de engenharia que ajudam a decidir qual espectro utilizar em aplicações como agricultura de precisão, inspeção industrial, robótica, monitoramento ambiental e identificação de materiais. Um guia essencial para engenheiros, desenvolvedores e pesquisadores que desejam projetar sistemas mais eficientes, robustos e fisicamente fundamentados.</p>
<p>The post <a href="https://mcu.tec.br/sensores/espectros-eletromagneticos-na-engenharia-uv-visivel-nir-e-swir-e-onde-usa-los/">Espectros Eletromagnéticos na Engenharia: UV, Visível, NIR e SWIR e Onde Usá-los</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-hd1kz wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-hd1kz "><div class="eb-toc-container eb-toc-hd1kz  eb-toc-is-not-sticky eb-toc-not-collapsible eb-toc-initially-not-collapsed eb-toc-scrollToTop style-1 list-style-none" data-scroll-top="false" data-scroll-top-icon="fas fa-angle-up" data-collapsible="false" data-sticky-hide-mobile="false" data-sticky="false" data-scroll-target="scroll_to_toc" data-copy-link="false" data-editor-type="" data-hide-desktop="false" data-hide-tab="false" data-hide-mobile="false" data-itemcollapsed="false" data-highlight-scroll="false"><div class="eb-toc-header"><h2 class="eb-toc-title">Table of Contents</h2></div><div class="eb-toc-wrapper " data-headers="[{&quot;level&quot;:2,&quot;content&quot;:&quot;1 \u2014 Espectro Ultravioleta (UV): fundamentos f\u00edsicos e aplica\u00e7\u00f5es&quot;,&quot;text&quot;:&quot;1 \u2014 Espectro Ultravioleta (UV): fundamentos f\u00edsicos e aplica\u00e7\u00f5es&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;2 \u2014 Espectro Vis\u00edvel: percep\u00e7\u00e3o humana, limites f\u00edsicos e aplica\u00e7\u00f5es&quot;,&quot;text&quot;:&quot;2 \u2014 Espectro Vis\u00edvel: percep\u00e7\u00e3o humana, limites f\u00edsicos e aplica\u00e7\u00f5es&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;3 \u2014 NIR (Infravermelho Pr\u00f3ximo): propriedades f\u00edsicas e aplica\u00e7\u00f5es estrat\u00e9gicas&quot;,&quot;text&quot;:&quot;3 \u2014 NIR (Infravermelho Pr\u00f3ximo): propriedades f\u00edsicas e aplica\u00e7\u00f5es estrat\u00e9gicas&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;4 \u2014 SWIR (Infravermelho de Onda Curta): identifica\u00e7\u00e3o de materiais e composi\u00e7\u00e3o qu\u00edmica&quot;,&quot;text&quot;:&quot;4 \u2014 SWIR (Infravermelho de Onda Curta): identifica\u00e7\u00e3o de materiais e composi\u00e7\u00e3o qu\u00edmica&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;5 \u2014 Combina\u00e7\u00f5es espectrais e crit\u00e9rios de escolha em projetos reais&quot;,&quot;text&quot;:&quot;5 \u2014 Combina\u00e7\u00f5es espectrais e crit\u00e9rios de escolha em projetos reais&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;6 \u2014 Diretrizes pr\u00e1ticas para escolha do espectro em sistemas embarcados, IoT e vis\u00e3o computacional&quot;,&quot;text&quot;:&quot;6 \u2014 Diretrizes pr\u00e1ticas para escolha do espectro em sistemas embarcados, IoT e vis\u00e3o computacional&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;7 \u2014 Impactos da escolha espectral em algoritmos, IA embarcada e processamento de sinais&quot;,&quot;text&quot;:&quot;7 \u2014 Impactos da escolha espectral em algoritmos, IA embarcada e processamento de sinais&quot;,&quot;link&quot;:&quot;7-impactos-da-escolha-espectral-em-algoritmos-ia-embarcada-e-processamento-de-sinais&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Conclus\u00e3o \u2014 Espectros como decis\u00e3o de engenharia, n\u00e3o como detalhe \u00f3ptico&quot;,&quot;text&quot;:&quot;Conclus\u00e3o \u2014 Espectros como decis\u00e3o de engenharia, n\u00e3o como detalhe \u00f3ptico&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;1 \u2014 Espectro Ultravioleta (UV): fundamentos f\u00edsicos e aplica\u00e7\u00f5es&quot;,&quot;value&quot;:&quot;1-espectro-ultravioleta-uv-fundamentos-f\u00edsicos-e-aplica\u00e7\u00f5es&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2 \u2014 Espectro Vis\u00edvel: percep\u00e7\u00e3o humana, limites f\u00edsicos e aplica\u00e7\u00f5es&quot;,&quot;value&quot;:&quot;2-espectro-vis\u00edvel-percep\u00e7\u00e3o-humana-limites-f\u00edsicos-e-aplica\u00e7\u00f5es&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3 \u2014 NIR (Infravermelho Pr\u00f3ximo): propriedades f\u00edsicas e aplica\u00e7\u00f5es estrat\u00e9gicas&quot;,&quot;value&quot;:&quot;3-nir-infravermelho-pr\u00f3ximo-propriedades-f\u00edsicas-e-aplica\u00e7\u00f5es-estrat\u00e9gicas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4 \u2014 SWIR (Infravermelho de Onda Curta): identifica\u00e7\u00e3o de materiais e composi\u00e7\u00e3o qu\u00edmica&quot;,&quot;value&quot;:&quot;4-swir-infravermelho-de-onda-curta-identifica\u00e7\u00e3o-de-materiais-e-composi\u00e7\u00e3o-qu\u00edmica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5 \u2014 Combina\u00e7\u00f5es espectrais e crit\u00e9rios de escolha em projetos reais&quot;,&quot;value&quot;:&quot;5-combina\u00e7\u00f5es-espectrais-e-crit\u00e9rios-de-escolha-em-projetos-reais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6 \u2014 Diretrizes pr\u00e1ticas para escolha do espectro em sistemas embarcados, IoT e vis\u00e3o computacional&quot;,&quot;value&quot;:&quot;6-diretrizes-pr\u00e1ticas-para-escolha-do-espectro-em-sistemas-embarcados-iot-e-vis\u00e3o-computacional&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7 \u2014 Impactos da escolha espectral em algoritmos, IA embarcada e processamento de sinais&quot;,&quot;value&quot;:&quot;7-impactos-da-escolha-espectral-em-algoritmos-ia-embarcada-e-processamento-de-sinais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conclus\u00e3o \u2014 Espectros como decis\u00e3o de engenharia, n\u00e3o como detalhe \u00f3ptico&quot;,&quot;value&quot;:&quot;conclus\u00e3o-espectros-como-decis\u00e3o-de-engenharia-n\u00e3o-como-detalhe-\u00f3ptico&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">1 — Espectro Ultravioleta (UV): fundamentos físicos e aplicações</a><li><a href="#eb-table-content-1">2 — Espectro Visível: percepção humana, limites físicos e aplicações</a><li><a href="#eb-table-content-2">3 — NIR (Infravermelho Próximo): propriedades físicas e aplicações estratégicas</a><li><a href="#eb-table-content-3">4 — SWIR (Infravermelho de Onda Curta): identificação de materiais e composição química</a><li><a href="#eb-table-content-4">5 — Combinações espectrais e critérios de escolha em projetos reais</a><li><a href="#eb-table-content-5">6 — Diretrizes práticas para escolha do espectro em sistemas embarcados, IoT e visão computacional</a><li><a href="#7-impactos-da-escolha-espectral-em-algoritmos-ia-embarcada-e-processamento-de-sinais">7 — Impactos da escolha espectral em algoritmos, IA embarcada e processamento de sinais</a><li><a href="#eb-table-content-7">Conclusão — Espectros como decisão de engenharia, não como detalhe óptico</a></ul></div></div></div></div></div>


<p class="wp-block-paragraph">O que são espectros e por que eles importam</p>



<p class="wp-block-paragraph">Quando falamos em <strong>espectros</strong>, estamos nos referindo às diferentes <strong>faixas do espectro eletromagnético</strong>, organizadas de acordo com o comprimento de onda (λ) ou frequência da radiação. Embora o ser humano esteja limitado à percepção do <strong>espectro visível</strong>, a física nos mostra que a luz é apenas uma pequena janela de um universo muito mais amplo de interações eletromagnéticas. Cada uma dessas faixas carrega informações físicas distintas sobre os materiais, o ambiente e os fenômenos observados.</p>



<p class="wp-block-paragraph">Do ponto de vista de engenharia — especialmente em <strong>sistemas embarcados, sensoriamento, visão computacional, IoT e instrumentação</strong> — compreender os espectros não é um luxo acadêmico, mas uma <strong>decisão de projeto</strong>. A escolha entre UV, Visível, NIR ou SWIR define diretamente o tipo de sensor, a óptica, o custo do sistema, o consumo energético e, principalmente, <strong>qual fenômeno físico será detectado</strong>. Em muitos casos, mudar a faixa espectral é mais eficiente do que aplicar algoritmos complexos sobre dados inadequados.</p>



<p class="wp-block-paragraph">Este artigo tem como objetivo apresentar, de forma <strong>didática e técnica</strong>, o que são os principais espectros usados em aplicações modernas — <strong>UV, Visível, NIR e SWIR</strong>, além de suas combinações — explicando <strong>onde e por que cada um deve ser utilizado</strong>. A proposta não é apenas descrever faixas de comprimento de onda, mas conectar cada espectro às <strong>aplicações reais</strong>, aos <strong>sensores disponíveis</strong> e às <strong>decisões de arquitetura</strong> em sistemas embarcados e industriais.</p><p>The post <a href="https://mcu.tec.br/sensores/espectros-eletromagneticos-na-engenharia-uv-visivel-nir-e-swir-e-onde-usa-los/">Espectros Eletromagnéticos na Engenharia: UV, Visível, NIR e SWIR e Onde Usá-los</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1240</post-id>	</item>
		<item>
		<title>Filtros para Processamento de Sinais em Sistemas Embarcados: Do Básico ao Avançado</title>
		<link>https://mcu.tec.br/algoritimos/filtros-para-processamento-de-sinais-em-sistemas-embarcados-do-basico-ao-avancado/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=filtros-para-processamento-de-sinais-em-sistemas-embarcados-do-basico-ao-avancado</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Tue, 06 May 2025 11:38:34 +0000</pubDate>
				<category><![CDATA[Algoritimos]]></category>
		<category><![CDATA[código C]]></category>
		<category><![CDATA[estimativa de estado]]></category>
		<category><![CDATA[filtragem de ruído]]></category>
		<category><![CDATA[filtragem em tempo real]]></category>
		<category><![CDATA[filtro de Kalman]]></category>
		<category><![CDATA[filtro de partículas]]></category>
		<category><![CDATA[filtro de Wiener]]></category>
		<category><![CDATA[filtro digital]]></category>
		<category><![CDATA[filtro exponencial]]></category>
		<category><![CDATA[filtro mediano]]></category>
		<category><![CDATA[média móvel]]></category>
		<category><![CDATA[processamento de sinais]]></category>
		<category><![CDATA[sensores ruidosos]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=485</guid>

					<description><![CDATA[<p>Aprenda como aplicar filtros digitais em sistemas embarcados com exemplos em C: média móvel, Kalman, filtros de partículas e mais.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/filtros-para-processamento-de-sinais-em-sistemas-embarcados-do-basico-ao-avancado/">Filtros para Processamento de Sinais em Sistemas Embarcados: Do Básico ao Avançado</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Em sistemas embarcados, o processamento de sinais é uma etapa fundamental para extrair informações úteis de sensores ruidosos ou sinais analógicos digitalizados. Um sistema de aquisição de dados, por exemplo, raramente trabalha com sinais puros: leituras de sensores sofrem interferências eletromagnéticas, ruídos térmicos ou distorções causadas por componentes eletrônicos. Filtros digitais são técnicas matemáticas e computacionais aplicadas para atenuar esses ruídos, isolar frequências específicas ou prever valores futuros com base em medições passadas.</p>



<p class="wp-block-paragraph">Este artigo abordará uma variedade de filtros, desde os mais simples e amplamente usados, como a Média Móvel (Moving Average), até técnicas mais sofisticadas como o Filtro de Kalman. Cada técnica será apresentada com sua motivação, estrutura matemática e exemplos de implementação prática em C ou pseudo-C para microcontroladores. O objetivo é tornar o tema acessível mesmo para quem está iniciando no campo do processamento digital de sinais, mas também útil a profissionais buscando soluções eficazes e eficientes para aplicações em tempo real.</p>



<h3 class="wp-block-heading">Filtro de Média Móvel</h3>



<p class="wp-block-paragraph">O filtro de média móvel é uma das técnicas mais simples e intuitivas para suavizar sinais ruidosos. Ele funciona como uma janela deslizante que calcula a média dos últimos N valores de entrada. Por sua simplicidade, é amplamente utilizado em sistemas embarcados com recursos computacionais limitados, como sensores de temperatura, pressão, ou leitura de sinais analógicos via ADC (Conversor Analógico-Digital).</p>



<h4 class="wp-block-heading">Problema Resolvido</h4>



<p class="wp-block-paragraph">Sinais adquiridos por sensores frequentemente contêm flutuações indesejadas — ruídos de alta frequência — que podem dificultar decisões ou controles baseados nesses dados. O filtro de média móvel reduz essas flutuações ao suavizar o sinal, permitindo uma resposta mais estável em aplicações como termostatos, sistemas de controle de motor, ou leitura de biossensores.</p>



<h4 class="wp-block-heading">Estrutura Matemática</h4>



<p class="wp-block-paragraph">A média móvel simples é definida pela fórmula: \[y[n] = \frac{1}{N} \sum_{i=0}^{N-1} x[n-i]\]



<p class="wp-block-paragraph">onde:</p>



<ul class="wp-block-list">
<li>y[n] é o valor filtrado no instante n,</li>



<li>x[n] é a amostra de entrada no instante n,</li>



<li>N é o tamanho da janela de média.</li>
</ul>



<h4 class="wp-block-heading">Exemplo de Código em C</h4>



<pre class="wp-block-preformatted"><code>#include &lt;stdint.h><br><br>#define WINDOW_SIZE 8<br><br>typedef struct {<br>    int16_t buffer[WINDOW_SIZE];<br>    uint8_t index;<br>    int32_t sum;<br>} MovingAverageFilter;<br><br>void initFilter(MovingAverageFilter *filter) {<br>    for (int i = 0; i &lt; WINDOW_SIZE; i++)<br>        filter->buffer[i] = 0;<br>    filter->index = 0;<br>    filter->sum = 0;<br>}<br><br>int16_t updateFilter(MovingAverageFilter *filter, int16_t newValue) {<br>    // Subtrai o valor mais antigo da soma<br>    filter->sum -= filter->buffer[filter->index];<br>    // Armazena o novo valor<br>    filter->buffer[filter->index] = newValue;<br>    // Adiciona o novo valor à soma<br>    filter->sum += newValue;<br>    // Move o índice circular<br>    filter->index = (filter->index + 1) % WINDOW_SIZE;<br>    // Retorna a média<br>    return (int16_t)(filter->sum / WINDOW_SIZE);<br>}<br></code></pre>



<h4 class="wp-block-heading">Análise</h4>



<p class="wp-block-paragraph">Este filtro apresenta desempenho estável e implementação eficiente, sem necessidade de operações complexas como multiplicações ou divisões em ponto flutuante (exceto pela divisão final, que pode ser otimizada via deslocamento quando NNN é potência de 2). Contudo, sua resposta a variações rápidas do sinal é lenta, pois ele tende a &#8220;amortecer&#8221; transientes, tornando-o inadequado para sistemas que exigem alta reatividade.</p>



<h4 class="wp-block-heading">Aplicações Típicas</h4>



<ul class="wp-block-list">
<li>Leitura de sensores analógicos com ruído ambiente</li>



<li>Suavização de variações de corrente em fontes chaveadas</li>



<li>Estabilização de sinais de entrada em filtros digitais mais complexos</li>
</ul>



<h3 class="wp-block-heading">Filtro Exponencial (Média Móvel Exponencial)</h3>



<p class="wp-block-paragraph">O filtro exponencial, também conhecido como <strong>filtro de primeira ordem</strong> ou <strong>filtro IIR de coeficiente simples</strong>, é uma alternativa ao filtro de média móvel que introduz uma ponderação decrescente nas amostras anteriores. Em vez de considerar todos os valores com o mesmo peso, como no filtro de média móvel simples, ele dá mais importância às amostras mais recentes, o que permite uma resposta mais ágil às variações do sinal.</p>



<h4 class="wp-block-heading">Problema Resolvido</h4>



<p class="wp-block-paragraph">O filtro de média móvel tradicional tende a atrasar a resposta do sistema quando a janela é grande. O filtro exponencial resolve esse problema permitindo um controle mais refinado sobre a “inércia” do filtro. Ele é particularmente útil quando é necessário suavizar sinais sem causar atrasos excessivos, como em leitura de sensores em tempo real, entrada de joysticks, ou medições de corrente em fontes chaveadas.</p>



<h4 class="wp-block-heading">Estrutura Matemática</h4>



<p class="wp-block-paragraph">O filtro exponencial é definido pela equação de diferença: \[y[n] = \alpha \cdot x[n] + (1 &#8211; \alpha) \cdot y[n-1]\]



<p class="wp-block-paragraph">onde:</p>



<ul class="wp-block-list">
<li>y[n] é a saída filtrada no tempo nnn,</li>



<li>x[n] é a entrada no tempo nnn,</li>



<li>\(\alpha \in (0, 1)\) é o coeficiente de suavização: quanto mais próximo de 1, mais peso a nova entrada terá (resposta rápida); quanto mais próximo de 0, mais lenta e suave será a resposta.</li>
</ul>



<h4 class="wp-block-heading">Exemplo de Código em C</h4>



<pre class="wp-block-preformatted">cCopiarEditar<code>#include &lt;stdint.h&gt;

typedef struct {
    float alpha;
    float output;
} ExponentialFilter;

void initExponentialFilter(ExponentialFilter *filter, float alpha) {
    filter-&gt;alpha = alpha;
    filter-&gt;output = 0.0f;
}

float updateExponentialFilter(ExponentialFilter *filter, float input) {
    filter-&gt;output = filter-&gt;alpha * input + (1.0f - filter-&gt;alpha) * filter-&gt;output;
    return filter-&gt;output;
}
</code></pre>



<h4 class="wp-block-heading">Versão para Inteiros (sem ponto flutuante)</h4>



<p class="wp-block-paragraph">Para microcontroladores sem FPU (Unidade de Ponto Flutuante), pode-se usar uma versão com inteiros, escalando os valores:</p>



<pre class="wp-block-preformatted">cCopiarEditar<code>#include &lt;stdint.h&gt;

#define ALPHA_FIXED 32  // Ex: 32 representa 0.125 se o fator de escala for 256
#define SCALE 256

typedef struct {
    int32_t output;
} ExpFilterFixed;

int16_t updateExpFilterFixed(ExpFilterFixed *filter, int16_t input) {
    filter-&gt;output = (ALPHA_FIXED * input + (SCALE - ALPHA_FIXED) * filter-&gt;output) / SCALE;
    return (int16_t)filter-&gt;output;
}
</code></pre>



<h4 class="wp-block-heading">Análise</h4>



<p class="wp-block-paragraph">O filtro exponencial possui resposta mais rápida do que a média móvel para o mesmo nível de suavização. Seu atraso de grupo é menor e o consumo de memória é reduzido, pois não é necessário armazenar buffers. Contudo, ele possui &#8220;memória infinita&#8221;, ou seja, o valor passado nunca desaparece completamente — o que pode ser uma desvantagem em alguns casos, como em detecção de transientes.</p>



<h4 class="wp-block-heading">Aplicações Típicas</h4>



<ul class="wp-block-list">
<li>Filtros de ruído para sinais de sensores IMU (Acelerômetro/Giroscópio)</li>



<li>Suavização de sinais de controle em robôs e drones</li>



<li>Filtros de corrente em fontes chaveadas com resposta rápida</li>



<li>Modelagem de resposta térmica em sistemas com controle PID</li>
</ul>



<h3 class="wp-block-heading">Filtro de Média Ponderada (Janela com Pesos Customizados)</h3>



<p class="wp-block-paragraph">O filtro de média ponderada é uma generalização do filtro de média móvel, onde cada amostra na janela recebe um peso diferente. Essa abordagem permite maior controle sobre quais partes do sinal têm maior influência na saída filtrada. O uso de pesos permite ajustar o filtro para atender a diferentes requisitos de resposta, como reduzir o ruído sem atenuar mudanças rápidas relevantes.</p>



<h4 class="wp-block-heading">Problema Resolvido</h4>



<p class="wp-block-paragraph">Sinais que contêm ruídos esporádicos ou picos indesejados (outliers) podem afetar significativamente a média simples. A média ponderada, ao atribuir menos peso a amostras mais antigas (ou potencialmente mais ruidosas), permite que o sistema reaja de forma mais eficiente a mudanças reais sem ser tão suscetível a ruídos momentâneos. É especialmente útil quando o sistema exige suavização, mas sem perder a capacidade de detectar transições.</p>



<h4 class="wp-block-heading">Estrutura Matemática</h4>



<p class="wp-block-paragraph">A média ponderada é definida como: \[y[n] = \frac{\sum_{i=0}^{N-1} w_i \cdot x[n-i]}{\sum_{i=0}^{N-1} w_i}\]



<p class="wp-block-paragraph">onde:</p>



<ul class="wp-block-list">
<li>\(w_i\)​ é o peso atribuído à iii-ésima amostra da janela,</li>



<li>x[n−i] é a iii-ésima amostra mais recente,</li>



<li>N é o tamanho da janela.</li>
</ul>



<p class="wp-block-paragraph">Exemplo de pesos com ênfase nas amostras mais recentes: w={1,2,3,4}w = \{1, 2, 3, 4\}w={1,2,3,4}</p>



<h4 class="wp-block-heading">Exemplo de Código em C</h4>



<pre class="wp-block-preformatted"><code>#include &lt;stdint.h><br><br>#define WINDOW_SIZE 4<br><br>typedef struct {<br>    int16_t buffer[WINDOW_SIZE];<br>    uint8_t index;<br>} WeightedAverageFilter;<br><br>const uint8_t weights[WINDOW_SIZE] = {1, 2, 3, 4}; // pesos: mais recente tem maior peso<br><br>int16_t updateWeightedFilter(WeightedAverageFilter *filter, int16_t newValue) {<br>    filter->buffer[filter->index] = newValue;<br>    filter->index = (filter->index + 1) % WINDOW_SIZE;<br><br>    int32_t weightedSum = 0;<br>    int32_t weightTotal = 0;<br>    uint8_t idx = filter->index;<br><br>    for (uint8_t i = 0; i &lt; WINDOW_SIZE; i++) {<br>        idx = (idx == 0) ? WINDOW_SIZE - 1 : idx - 1;<br>        weightedSum += filter->buffer[idx] * weights[i];<br>        weightTotal += weights[i];<br>    }<br><br>    return (int16_t)(weightedSum / weightTotal);<br>}<br></code></pre>



<h4 class="wp-block-heading">Análise</h4>



<p class="wp-block-paragraph">O filtro de média ponderada oferece maior flexibilidade que a média móvel simples, com custo computacional ligeiramente superior. Ele é eficaz para eliminar ruídos do tipo &#8220;espeto&#8221; (spike noise) e ao mesmo tempo manter a capacidade de rastrear tendências. Sua eficiência depende da escolha apropriada dos pesos — os quais podem ser lineares, exponenciais ou customizados para a aplicação.</p>



<h4 class="wp-block-heading">Aplicações Típicas</h4>



<ul class="wp-block-list">
<li>Suavização de sinais de sensores em ambientes ruidosos</li>



<li>Pré-processamento de sinais em sistemas de classificação (ex: ECG, EMG)</li>



<li>Estabilização de leituras em interfaces homem-máquina (joysticks, sliders, etc.)</li>



<li>Leitura de sinais analógicos sujeitos a distorções temporárias</li>
</ul>



<h3 class="wp-block-heading">Filtro Mediano (Median Filter)</h3>



<p class="wp-block-paragraph">O filtro mediano é uma técnica não linear de processamento de sinais especialmente eficaz na remoção de ruídos impulsivos, como picos isolados (outliers) que podem ocorrer em medições físicas. Diferentemente da média móvel, ele não suaviza gradualmente o sinal, mas substitui o valor central de uma janela de amostras pela mediana — o valor que está no meio quando os dados são ordenados. Isso o torna ideal para preservar bordas e transições bruscas enquanto elimina ruídos esporádicos.</p>



<h4 class="wp-block-heading">Problema Resolvido</h4>



<p class="wp-block-paragraph">Em sistemas embarcados que realizam medições sujeitas a interferências eletromagnéticas, conexões instáveis ou saltos ocasionais de leitura (por exemplo, sensores de distância ultrassônicos, sensores de corrente em ambientes industriais ou dados de visão computacional embarcada), a presença de picos pode prejudicar decisões e controles. O filtro mediano elimina essas perturbações preservando a integridade do sinal real.</p>



<h4 class="wp-block-heading">Estrutura Matemática</h4>



<p class="wp-block-paragraph">Para uma janela de tamanho NNN, o filtro ordena as amostras e seleciona a mediana: \[y[n] = \text{median}(x[n &#8211; (N-1)/2], &#8230;, x[n], &#8230;, x[n + (N-1)/2])\]



<p class="wp-block-paragraph">Onde:</p>



<ul class="wp-block-list">
<li>y[n] é a saída filtrada,</li>



<li>x[n] é a amostra no tempo nnn,</li>



<li>A mediana é o valor central da sequência ordenada.</li>
</ul>



<h4 class="wp-block-heading">Exemplo de Código em C (Janela de 5 Amostras)</h4>



<pre class="wp-block-preformatted"><code>#include &lt;stdint.h><br><br>#define WINDOW_SIZE 5<br><br>typedef struct {<br>    int16_t buffer[WINDOW_SIZE];<br>    uint8_t index;<br>} MedianFilter;<br><br>void insertValue(MedianFilter *filter, int16_t value) {<br>    filter->buffer[filter->index] = value;<br>    filter->index = (filter->index + 1) % WINDOW_SIZE;<br>}<br><br>int compare(const void *a, const void *b) {<br>    return (*(int16_t*)a - *(int16_t*)b);<br>}<br><br>int16_t getMedian(MedianFilter *filter) {<br>    int16_t temp[WINDOW_SIZE];<br>    for (int i = 0; i &lt; WINDOW_SIZE; i++)<br>        temp[i] = filter->buffer[i];<br><br>    qsort(temp, WINDOW_SIZE, sizeof(int16_t), compare);<br>    return temp[WINDOW_SIZE / 2];<br>}<br></code></pre>



<h4 class="wp-block-heading">Uso Típico</h4>



<pre class="wp-block-preformatted">cCopiarEditar<code>MedianFilter filter = {{0}, 0};

void loop() {
    int16_t newSample = read_adc();
    insertValue(&amp;filter, newSample);
    int16_t cleanValue = getMedian(&amp;filter);
    // Use cleanValue no controle ou visualização
}
</code></pre>



<h4 class="wp-block-heading">Análise</h4>



<p class="wp-block-paragraph">Embora seja mais robusto a ruídos extremos, o filtro mediano tem maior custo computacional do que os filtros baseados em média. O uso de <code>qsort()</code> pode ser otimizado com algoritmos específicos para mediana de 3, 5 ou 7 valores, comuns em sistemas embarcados. Ele não distorce o sinal original em regiões com variação suave e é muito eficaz para rejeitar ruídos impulsivos. No entanto, seu uso não é adequado para sistemas que exigem filtragem de ruído gaussiano ou precisão em pequenas variações.</p>



<h4 class="wp-block-heading">Aplicações Típicas</h4>



<ul class="wp-block-list">
<li>Sensores ultrassônicos ou infravermelhos com ruído espúrio</li>



<li>Processamento de imagem (eliminação de pixels corrompidos)</li>



<li>Sensores analógicos de baixo custo (temperatura, corrente, tensão)</li>



<li>Filtragem de sinais biológicos (ex: ECG, EMG) em sistemas embarcados</li>
</ul>



<h3 class="wp-block-heading">Filtro de Kalman</h3>



<p class="wp-block-paragraph">O Filtro de Kalman é um algoritmo matemático sofisticado para estimar o estado de um sistema dinâmico a partir de medições ruidosas. Ele é amplamente utilizado em sistemas embarcados para fusão sensorial (como em IMUs), navegação, robótica e controle adaptativo. Ao contrário dos filtros tradicionais, o Kalman considera não só os valores observados, mas também as incertezas associadas tanto ao modelo quanto às medições, fazendo previsões e correções iterativas.</p>



<h4 class="wp-block-heading">Problema Resolvido</h4>



<p class="wp-block-paragraph">Em muitos sistemas embarcados, as medições de sensores apresentam ruído, e o modelo do sistema também pode ser incerto. O filtro de Kalman resolve esse problema ao estimar o &#8220;verdadeiro estado&#8221; do sistema — mesmo que ele não seja diretamente observável — usando uma abordagem estatística baseada em modelos. É ideal para casos em que múltiplas fontes de dados devem ser integradas (por exemplo, acelerômetro + giroscópio) ou quando o sistema sofre variações lentas mas importantes.</p>



<h4 class="wp-block-heading">Estrutura Matemática (Kalman 1D)</h4>



<p class="wp-block-paragraph">O modelo básico de um sistema linear com ruído aditivo é:</p>



<p class="wp-block-paragraph"><strong>Modelo de estado:</strong> \[\hat{x}_{k|k-1} = \hat{x}_{k-1|k-1}\]



<p class="wp-block-paragraph"><strong>Atualização da incerteza:</strong> \[P_{k|k-1} = P_{k-1|k-1} + Q\]



<p class="wp-block-paragraph"><strong>Ganho de Kalman:</strong> \[K_k = \frac{P_{k|k-1}}{P_{k|k-1} + R}\]



<p class="wp-block-paragraph"><strong>Atualização com medição \(z_k\)​:</strong> \[\hat{x}_{k|k} = \hat{x}_{k|k-1} + K_k (z_k &#8211; \hat{x}_{k|k-1})\]\[P_{k|k} = (1 &#8211; K_k) P_{k|k-1}\]



<p class="wp-block-paragraph">Onde:</p>



<ul class="wp-block-list">
<li>\(\hat{x}\): estimativa do estado</li>



<li>P: incerteza da estimativa</li>



<li>Q: variância do ruído do processo</li>



<li>R: variância do ruído de medição</li>



<li>K: ganho de Kalman</li>
</ul>



<h4 class="wp-block-heading">Exemplo de Código em C (Kalman 1D)</h4>



<pre class="wp-block-preformatted"><code>typedef struct {<br>    float x;     // Estado estimado<br>    float p;     // Incerteza da estimativa<br>    float q;     // Variância do processo<br>    float r;     // Variância da medição<br>    float k;     // Ganho de Kalman<br>} KalmanFilter;<br><br>void initKalman(KalmanFilter *kf, float q, float r, float p, float initial_value) {<br>    kf->q = q;<br>    kf->r = r;<br>    kf->p = p;<br>    kf->x = initial_value;<br>}<br><br>float updateKalman(KalmanFilter *kf, float measurement) {<br>    // Predição<br>    kf->p = kf->p + kf->q;<br><br>    // Atualização<br>    kf->k = kf->p / (kf->p + kf->r);<br>    kf->x = kf->x + kf->k * (measurement - kf->x);<br>    kf->p = (1 - kf->k) * kf->p;<br><br>    return kf->x;<br>}<br></code></pre>



<h4 class="wp-block-heading">Análise</h4>



<p class="wp-block-paragraph">O filtro de Kalman é altamente eficiente, com custo computacional linear, sendo perfeitamente viável em microcontroladores de 32 bits (como Cortex-M). Sua força está em sua capacidade de combinar medições ruidosas com previsões baseadas em modelos, gerando uma estimativa mais precisa do que qualquer medição individual. Ele também pode ser estendido para sistemas multivariados (Kalman Multidimensional) e sistemas não-lineares (Filtro de Kalman Estendido).</p>



<h4 class="wp-block-heading">Aplicações Típicas</h4>



<ul class="wp-block-list">
<li>Fusão de sensores (Ex: acelerômetro + giroscópio + magnetômetro)</li>



<li>Rastreamento de posição e velocidade (GPS com odometria)</li>



<li>Controle de sistemas com estados não diretamente observáveis</li>



<li>Estimativas adaptativas de variáveis físicas em fontes chaveadas (tensão, corrente, temperatura)</li>
</ul>



<h3 class="wp-block-heading">Filtro de Kalman Estendido (Extended Kalman Filter &#8211; EKF)</h3>



<p class="wp-block-paragraph">O Filtro de Kalman Estendido (EKF) é uma extensão do Filtro de Kalman tradicional voltada a sistemas <strong>não-lineares</strong>. Em vez de assumir que o sistema e o modelo de medição são lineares, o EKF utiliza uma aproximação local por meio da linearização com séries de Taylor, aplicando a lógica do Kalman sobre uma versão linearizada do sistema.</p>



<h4 class="wp-block-heading">Problema Resolvido</h4>



<p class="wp-block-paragraph">Muitos sistemas físicos reais possuem comportamentos não-lineares: medição de ângulos, sensores de corrente baseados em campo magnético (como Hall), sistemas com dinâmica de rotação ou filtros para sensores de posição em robótica. O Filtro de Kalman tradicional não pode lidar corretamente com não-linearidades. O EKF permite aplicar as ideias do Kalman em sistemas que possuem modelos descritos por funções arbitrárias.</p>



<h4 class="wp-block-heading">Estrutura Matemática (Resumo)</h4>



<p class="wp-block-paragraph">Dado um sistema modelado por: \[x_k = f(x_{k-1}, u_{k-1}) + w_{k-1}\]\[z_k = h(x_k) + v_k\]



<p class="wp-block-paragraph">Onde:</p>



<ul class="wp-block-list">
<li>\(f(\cdot)\): modelo de transição de estado (não-linear)</li>



<li>\(h(\cdot)\): modelo de observação (não-linear)</li>



<li>w e v: ruídos de processo e medição (gaussianos)</li>
</ul>



<p class="wp-block-paragraph">A linearização é feita por meio das matrizes Jacobianas:</p>



<ul class="wp-block-list">
<li>\(F_k = \frac{\partial f}{\partial x}\)​, avaliada em \(\hat{x}_{k-1}\)</li>



<li>\(H_k = \frac{\partial h}{\partial x}\), avaliada em \(\hat{x}_{k|k-1}\)</li>
</ul>



<h4 class="wp-block-heading">Ciclo do EKF</h4>



<ol class="wp-block-list">
<li><strong>Predição:</strong> \[\hat{x}_{k|k-1} = f(\hat{x}_{k-1}, u_{k-1})\] \[\[P_{k|k-1} = F_k P_{k-1} F_k^T + Q\]</li>



<li><strong>Atualização:</strong> \[K_k = P_{k|k-1} H_k^T (H_k P_{k|k-1} H_k^T + R)^{-1}\]\[\hat{x}_{k} = \hat{x}_{k|k-1} + K_k (z_k &#8211; h(\hat{x}_{k|k-1}))\]\[P_k = (I &#8211; K_k H_k) P_{k|k-1}\]</li>
</ol>



<h4 class="wp-block-heading">Exemplo de Aplicação: Estimativa de Ângulo com Sensor de Giro</h4>



<pre class="wp-block-preformatted"><code>// Modelo simplificado do EKF aplicado a sensor de ângulo com giroscópio<br>float x = 0;   // ângulo estimado<br>float p = 1;<br>float q = 0.01; // ruído do processo<br>float r = 0.1;  // ruído da medição<br><br>float ekf_update(float z, float gyroRate, float dt) {<br>    // Predição<br>    x += gyroRate * dt;      // f(x) = x + w*dt<br>    p += q;<br><br>    // Jacobiano H = 1 para h(x) = x (medição direta)<br>    float k = p / (p + r);   // Kalman Gain<br>    x += k * (z - x);        // Atualização<br>    p = (1 - k) * p;<br><br>    return x;<br>}<br></code></pre>



<h4 class="wp-block-heading">Análise</h4>



<p class="wp-block-paragraph">O EKF é uma solução poderosa, mas exige maior capacidade computacional devido ao cálculo de derivadas (Jacobianas) e multiplicações matriciais. Sua precisão depende fortemente da qualidade das aproximações lineares — erros de modelagem ou suposições ruins podem degradar a estimativa. Ainda assim, o EKF é amplamente usado em sistemas embarcados modernos com suporte matemático básico (por exemplo, ARM Cortex-M4 com FPU).</p>



<h4 class="wp-block-heading">Aplicações Típicas</h4>



<ul class="wp-block-list">
<li>Navegação de robôs móveis (composição entre odometria e GPS)</li>



<li>Estimativa de atitude (roll/pitch/yaw) com IMU em drones</li>



<li>Rastreamento de posição em braços robóticos com sensores não-lineares</li>



<li>Previsão de corrente em inversores com sensores indutivos</li>
</ul>



<h3 class="wp-block-heading">Filtro de Partículas (Particle Filter)</h3>



<p class="wp-block-paragraph">O Filtro de Partículas, também conhecido como <strong>Filtro de Monte Carlo</strong>, é um método de estimação baseado em probabilidade que utiliza <strong>conjuntos de amostras (partículas)</strong> para representar a distribuição de probabilidade de um estado. Ele é especialmente útil para sistemas <strong>altamente não-lineares e não-gaussianos</strong>, onde técnicas como o Filtro de Kalman Estendido se tornam imprecisas ou instáveis.</p>



<h4 class="wp-block-heading">Problema Resolvido</h4>



<p class="wp-block-paragraph">Muitos sistemas embarcados modernos operam em ambientes ruidosos e incertos, com múltiplas fontes de erro e modelos complexos — como mapeamento e localização (SLAM), rastreamento visual ou fusão de sensores com ruídos assimétricos. Nesses casos, não é possível assumir uma única média e variância (como no Kalman), sendo necessário representar a estimativa como uma <strong>distribuição completa</strong>. O filtro de partículas resolve isso ao simular muitas hipóteses (partículas) e atualizá-las com base nas evidências.</p>



<h4 class="wp-block-heading">Princípio de Funcionamento</h4>



<p class="wp-block-paragraph">Cada partícula representa uma possível estimativa do estado. A cada iteração:</p>



<ol class="wp-block-list">
<li><strong>Propagação (Predição):</strong><br>Cada partícula é atualizada segundo o modelo de movimento (com ruído).</li>



<li><strong>Atualização de Peso:</strong><br>Cada partícula é ponderada com base na probabilidade de gerar a medição observada.</li>



<li><strong>Reamostragem:</strong><br>Partículas com maior peso têm mais chances de serem mantidas; partículas com baixo peso são descartadas.</li>
</ol>



<p class="wp-block-paragraph">O estado estimado é a <strong>média ponderada</strong> das partículas.</p>



<h4 class="wp-block-heading">Exemplo Simplificado (1D) em C</h4>



<pre class="wp-block-preformatted"><code>#include &lt;stdlib.h><br>#include &lt;math.h><br><br>#define NUM_PARTICLES 100<br><br>typedef struct {<br>    float x;<br>    float weight;<br>} Particle;<br><br>Particle particles[NUM_PARTICLES];<br><br>void init_particles(float initial_guess) {<br>    for (int i = 0; i &lt; NUM_PARTICLES; i++) {<br>        particles[i].x = initial_guess + ((rand() % 100) / 100.0f - 0.5f);  // ruído inicial<br>        particles[i].weight = 1.0f / NUM_PARTICLES;<br>    }<br>}<br><br>float gaussian(float mu, float sigma, float x) {<br>    float coeff = 1.0f / sqrtf(2.0f * M_PI * sigma * sigma);<br>    float expo = expf(-0.5f * ((x - mu) * (x - mu)) / (sigma * sigma));<br>    return coeff * expo;<br>}<br><br>void update_particles(float control_input, float measurement, float process_noise, float measurement_noise) {<br>    float weight_sum = 0.0f;<br><br>    // Predição e atualização de peso<br>    for (int i = 0; i &lt; NUM_PARTICLES; i++) {<br>        // modelo de movimento: x = x + u + ruído<br>        particles[i].x += control_input + ((rand() % 100) / 100.0f - 0.5f) * process_noise;<br><br>        // probabilidade da medição atual com base na posição da partícula<br>        particles[i].weight = gaussian(particles[i].x, measurement_noise, measurement);<br>        weight_sum += particles[i].weight;<br>    }<br><br>    // Normalização dos pesos<br>    for (int i = 0; i &lt; NUM_PARTICLES; i++) {<br>        particles[i].weight /= weight_sum;<br>    }<br><br>    // Reamostragem (simples)<br>    Particle new_particles[NUM_PARTICLES];<br>    for (int i = 0; i &lt; NUM_PARTICLES; i++) {<br>        float r = (float)rand() / RAND_MAX;<br>        float sum = 0.0f;<br>        for (int j = 0; j &lt; NUM_PARTICLES; j++) {<br>            sum += particles[j].weight;<br>            if (sum >= r) {<br>                new_particles[i] = particles[j];<br>                break;<br>            }<br>        }<br>    }<br><br>    // Atualiza o conjunto<br>    for (int i = 0; i &lt; NUM_PARTICLES; i++) {<br>        particles[i] = new_particles[i];<br>    }<br>}<br><br>float estimate() {<br>    float est = 0.0f;<br>    for (int i = 0; i &lt; NUM_PARTICLES; i++) {<br>        est += particles[i].x * particles[i].weight;<br>    }<br>    return est;<br>}<br></code></pre>



<h4 class="wp-block-heading">Análise</h4>



<p class="wp-block-paragraph">O Filtro de Partículas oferece uma capacidade superior de lidar com múltiplas hipóteses, ruídos não-gaussianos e observações ambíguas. Entretanto, seu custo computacional é elevado, exigindo muitas amostras e operações de reamostragem. Ainda assim, com otimizadores e simplificações, ele pode ser implementado em sistemas embarcados ARM Cortex-M com uso eficiente de memória e tempo. O principal desafio é o ajuste correto da modelagem probabilística.</p>



<h4 class="wp-block-heading">Aplicações Típicas</h4>



<ul class="wp-block-list">
<li>Navegação e Localização (SLAM) em robótica e drones</li>



<li>Rastreamento visual de objetos com câmeras embarcadas</li>



<li>Sistemas biomédicos com sinais altamente ruidosos</li>



<li>Inferência probabilística em dispositivos IoT com múltiplos sensores</li>
</ul>



<h3 class="wp-block-heading">Filtro de Wiener</h3>



<p class="wp-block-paragraph">O Filtro de Wiener é uma técnica de filtragem estatística projetada para produzir uma <strong>estimativa ótima</strong> de um sinal desejado com base em suas correlações com o ruído e com o próprio sinal. É amplamente usado em aplicações que exigem restauração de sinais, como recuperação de áudio, imagem e sinais digitais degradados por canais ruidosos. No contexto embarcado, pode ser aplicado a sinais de sensores em que a estatística do ruído é relativamente conhecida ou estimável.</p>



<h4 class="wp-block-heading">Problema Resolvido</h4>



<p class="wp-block-paragraph">Sinais reais são frequentemente corrompidos por ruído aditivo que pode ser modelado estocasticamente. Enquanto os filtros de média móvel e Kalman trabalham com aproximações pontuais ou suposições simplificadas, o Filtro de Wiener é <strong>ótimo no sentido de minimizar o erro quadrático médio (MSE)</strong> entre o sinal real e a saída filtrada. Ele é ideal para situações onde se conhece ou pode estimar a estatística (auto e cruz-correlações) do sinal e do ruído.</p>



<h4 class="wp-block-heading">Estrutura Matemática (Wiener 1D)</h4>



<p class="wp-block-paragraph">O filtro de Wiener tem como solução ótima (discreta e causal): \[H(\omega) = \frac{S_{xx}(\omega)}{S_{xx}(\omega) + S_{nn}(\omega)}\]



<p class="wp-block-paragraph">onde:</p>



<ul class="wp-block-list">
<li>\(H(\omega)\): resposta em frequência do filtro</li>



<li>\(S_{xx}(\omega)\): densidade espectral de potência do sinal</li>



<li>\(S_{nn}(\omega)\): densidade espectral de potência do ruído</li>
</ul>



<p class="wp-block-paragraph">Na forma discreta e implementável, pode ser expresso como: \[y[n] = \sum_{k=0}^{N-1} h[k] \cdot x[n &#8211; k]\]



<p class="wp-block-paragraph">Os coeficientes h[k] são obtidos resolvendo um sistema de equações baseado nas autocorrelações do sinal e na função cruzada entre entrada e saída desejada.</p>



<h4 class="wp-block-heading">Exemplo de Código em C (Forma simplificada com estimativa empírica)</h4>



<pre class="wp-block-preformatted"><code>#include &lt;stdint.h><br>#include &lt;string.h><br><br>#define N 8 // tamanho do filtro<br><br>void estimate_wiener_coeffs(const float *signal, const float *desired, float *coeffs, int len) {<br>    float R[N][N] = {0}; // matriz de autocorrelação<br>    float P[N] = {0};    // vetor de correlação cruzada<br><br>    // Construir R e P<br>    for (int i = 0; i &lt; len - N; i++) {<br>        for (int j = 0; j &lt; N; j++) {<br>            for (int k = 0; k &lt; N; k++) {<br>                R[j][k] += signal[i + j] * signal[i + k];<br>            }<br>            P[j] += desired[i] * signal[i + j];<br>        }<br>    }<br><br>    // Resolver sistema linear R * h = P (poderia usar Gauss-Jordan ou LU)<br>    // Aqui simplificado como uma solução direta apenas para casos didáticos<br>    for (int i = 0; i &lt; N; i++) {<br>        coeffs[i] = P[i] / (R[i][i] + 1e-6f); // simplificação para exemplo<br>    }<br>}<br><br>float apply_wiener_filter(const float *input, const float *coeffs) {<br>    float output = 0.0f;<br>    for (int i = 0; i &lt; N; i++) {<br>        output += coeffs[i] * input[i];<br>    }<br>    return output;<br>}<br></code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Nota:</strong> Este exemplo é didático. Em aplicações reais, o sistema R⋅h=PR \cdot h = PR⋅h=P deve ser resolvido com métodos numéricos estáveis (ex: decomposição de Cholesky ou métodos iterativos).</p>
</blockquote>



<h4 class="wp-block-heading">Análise</h4>



<p class="wp-block-paragraph">O Filtro de Wiener é ótimo em contextos onde se conhece a estatística do sinal e ruído, mas é limitado por sua dependência desses parâmetros. Sua implementação completa pode ser pesada para microcontroladores de baixo desempenho, mas versões simplificadas, ou estimativas precomputadas, são perfeitamente viáveis em sistemas embarcados com uso constante de sinais similares.</p>



<h4 class="wp-block-heading">Aplicações Típicas</h4>



<ul class="wp-block-list">
<li>Recuperação de áudio embarcado (remoção de ruído de fundo)</li>



<li>Filtragem de sinais digitais em telecomunicações embarcadas</li>



<li>Processamento de imagem embarcada (ex: remoção de borrões ou granulação)</li>



<li>Detecção de falhas em sensores com comportamento repetitivo (ex: sensores industriais)</li>
</ul>



<p class="wp-block-paragraph">Ao longo dos capítulos anteriores, exploramos uma ampla gama de filtros aplicáveis ao processamento de sinais em sistemas embarcados, desde técnicas simples baseadas em médias até algoritmos probabilísticos e estatísticos avançados. Cada filtro oferece vantagens e limitações, dependendo da natureza do sinal, do ruído presente e dos recursos computacionais disponíveis.</p>



<h4 class="wp-block-heading">Comparação Geral dos Filtros</h4>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Filtro</th><th>Complexidade</th><th>Tipo</th><th>Vantagem Principal</th><th>Limitação Principal</th><th>Aplicação Típica</th></tr></thead><tbody><tr><td>Média Móvel</td><td>Baixa</td><td>Linear</td><td>Simples e fácil de implementar</td><td>Suaviza transientes</td><td>Leitura de sensores analógicos simples</td></tr><tr><td>Exponencial</td><td>Muito baixa</td><td>Linear (IIR)</td><td>Pouco uso de memória, boa resposta</td><td>Menos eficaz com ruídos impulsivos</td><td>Filtragem de sinais em controle de motor</td></tr><tr><td>Média Ponderada</td><td>Baixa</td><td>Linear</td><td>Ajustável ao contexto</td><td>Precisa de cuidado na escolha dos pesos</td><td>Interfaces com usuário (joysticks, etc.)</td></tr><tr><td>Mediano</td><td>Média</td><td>Não-linear</td><td>Robusto a picos e outliers</td><td>Mais pesado, introduz atraso em sinais finos</td><td>Sensores ultrassônicos, visão embarcada</td></tr><tr><td>Kalman</td><td>Média</td><td>Probabilístico</td><td>Otimização estatística com baixo custo</td><td>Exige bom modelo de ruído</td><td>Estimativa de posição, velocidade, IMUs</td></tr><tr><td>Kalman Estendido (EKF)</td><td>Alta</td><td>Não-linear</td><td>Estima estados em sistemas não-lineares</td><td>Custo computacional, sensível a modelagem</td><td>Navegação robótica, fusão sensorial</td></tr><tr><td>Filtro de Partículas</td><td>Muito alta</td><td>Estocástico</td><td>Lida com múltiplas hipóteses e ambiguidade</td><td>Muito pesado computacionalmente</td><td>SLAM, rastreamento em visão embarcada</td></tr><tr><td>Filtro de Wiener</td><td>Alta</td><td>Ótimo estatístico</td><td>Minimiza erro quadrático médio</td><td>Requer estatísticas conhecidas</td><td>Restauração de sinais, áudio, imagem</td></tr></tbody></table></figure>



<h4 class="wp-block-heading">Recomendações Práticas</h4>



<ul class="wp-block-list">
<li><strong>Se o seu sistema embarcado for simples e tiver baixa potência computacional</strong>, comece com filtros como <strong>média móvel</strong>, <strong>exponencial</strong> ou <strong>mediano</strong>.</li>



<li><strong>Se você precisa de suavização adaptativa e preditiva</strong>, e possui sensores com ruído gaussiano, o <strong>Filtro de Kalman</strong> é altamente recomendado.</li>



<li><strong>Em sistemas com modelos não-lineares complexos</strong> (ex: giroscópio + acelerômetro), o <strong>Filtro de Kalman Estendido</strong> é a solução natural.</li>



<li><strong>Quando o sistema apresenta múltiplas hipóteses simultâneas ou incertezas complexas</strong>, como em navegação ou SLAM, o <strong>Filtro de Partículas</strong> se destaca, desde que haja recursos computacionais adequados.</li>



<li><strong>Para aplicações onde você conhece a estatística do ruído e sinal</strong>, e quer obter a melhor estimativa possível com base nessa modelagem, o <strong>Filtro de Wiener</strong> é a escolha teórica ideal.</li>
</ul>



<h4 class="wp-block-heading">Encerramento</h4>



<p class="wp-block-paragraph">Filtros são ferramentas essenciais no arsenal do engenheiro de sistemas embarcados. Dominar seus fundamentos, limitações e aplicações permite construir sistemas mais robustos, confiáveis e eficientes, independentemente da área de atuação — automação, robótica, IoT, biomédica ou aeroespacial.</p><p>The post <a href="https://mcu.tec.br/algoritimos/filtros-para-processamento-de-sinais-em-sistemas-embarcados-do-basico-ao-avancado/">Filtros para Processamento de Sinais em Sistemas Embarcados: Do Básico ao Avançado</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">485</post-id>	</item>
		<item>
		<title>A Transformada de Fourier: Fundamentos, Demonstração e Implementação em C</title>
		<link>https://mcu.tec.br/algoritimos/a-transformada-de-fourier-fundamentos-demonstracao-e-implementacao-em-c/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-transformada-de-fourier-fundamentos-demonstracao-e-implementacao-em-c</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 16:21:06 +0000</pubDate>
				<category><![CDATA[Algoritimos]]></category>
		<category><![CDATA[análise de vibração]]></category>
		<category><![CDATA[análise espectral]]></category>
		<category><![CDATA[código em C]]></category>
		<category><![CDATA[dft]]></category>
		<category><![CDATA[domínio da frequência]]></category>
		<category><![CDATA[engenharia elétrica]]></category>
		<category><![CDATA[espectro de frequência]]></category>
		<category><![CDATA[fft]]></category>
		<category><![CDATA[ifft]]></category>
		<category><![CDATA[implementação em C]]></category>
		<category><![CDATA[processamento de sinais]]></category>
		<category><![CDATA[processamento digital]]></category>
		<category><![CDATA[reconstrução de sinal]]></category>
		<category><![CDATA[sinais de áudio]]></category>
		<category><![CDATA[sinais de sensores]]></category>
		<category><![CDATA[sinais digitais]]></category>
		<category><![CDATA[sinal no tempo]]></category>
		<category><![CDATA[transformada de fourier]]></category>
		<category><![CDATA[transformada rápida de fourier]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=212</guid>

					<description><![CDATA[<p>Entenda a Transformada de Fourier e veja como implementá-la em C com exemplos práticos, FFT, iFFT e aplicação em sinais reais de sensores e áudio.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/a-transformada-de-fourier-fundamentos-demonstracao-e-implementacao-em-c/">A Transformada de Fourier: Fundamentos, Demonstração e Implementação em C</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2 class="wp-block-heading"><strong>Introdução</strong></h2>



<p class="wp-block-paragraph">A Transformada de Fourier (TF) é uma das ferramentas matemáticas mais poderosas na análise de sinais e sistemas. Ela permite converter um sinal do domínio do tempo para o domínio da frequência, revelando componentes espectrais que não são diretamente perceptíveis no tempo. Aplicações da TF vão desde o processamento digital de sinais (DSP) até física, telecomunicações, engenharia biomédica e eletrônica.</p>



<p class="wp-block-paragraph">Neste artigo, exploraremos a base teórica da Transformada de Fourier, sua demonstração matemática e uma implementação completa em linguagem C, focando em clareza e didática para leitores iniciantes.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>Fundamentos da Transformada de Fourier</strong></h2>



<p class="wp-block-paragraph">Imagine um sinal contínuo no tempo, como uma onda sonora. Esse sinal pode ser decomposto como a soma de muitas senóides (ondas senoidais) com diferentes frequências, amplitudes e fases. A Transformada de Fourier é o processo que encontra essas senóides componentes.</p>



<p class="wp-block-paragraph">Matematicamente, para um sinal contínuo x(t)x(t), a Transformada de Fourier é dada por: </p>



<p class="wp-block-paragraph">\[<br>X(f) = \int_{-\infty}^{\infty} x(t) e^{-j 2\pi f t} \, dt<br>\]



<p class="wp-block-paragraph">Onde:</p>



<ul class="wp-block-list">
<li>x(t): sinal no tempo contínuo.</li>



<li>X(f): espectro de frequências do sinal.</li>



<li>f: frequência.</li>



<li>j: unidade imaginária \((j^2 = -1)\).</li>
</ul>



<p class="wp-block-paragraph">A transformada inversa é dada por: </p>



<p class="wp-block-paragraph">\[<br>x(t) = \int_{-\infty}^{\infty} X(f) e^{j 2\pi f t} \, df<br>\]



<p class="wp-block-paragraph">Ou seja, é possível reconstruir o sinal original a partir de suas componentes de frequência.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>Transformada de Fourier Discreta (DFT)</strong></h2>



<p class="wp-block-paragraph">Na prática, lidamos com sinais amostrados digitalmente. Para isso, usamos a versão discreta da TF: a <strong>Transformada de Fourier Discreta (DFT)</strong>, definida por: </p>



<p class="wp-block-paragraph">\[<br>X_k = \sum_{n=0}^{N-1} x_n \cdot e^{-j \frac{2\pi}{N}kn}, \quad k = 0, 1, &#8230;, N-1<br>\]



<p class="wp-block-paragraph">E a transformada inversa: </p>



<p class="wp-block-paragraph">\[<br>x_n = \frac{1}{N} \sum_{k=0}^{N-1} X_k \cdot e^{j \frac{2\pi}{N}kn}<br>\]



<p class="wp-block-paragraph">Onde:</p>



<ul class="wp-block-list">
<li>\(x_n\): amostras no tempo.</li>



<li>\(X_k\): componente espectral da frequência kk.</li>



<li>N: número total de amostras.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>Implementação em C da DFT</strong></h2>



<p class="wp-block-paragraph">A seguir, apresentamos um código simples em linguagem C que calcula a DFT de um vetor de números reais. Para isso, usaremos números complexos representados por duas variáveis (parte real e imaginária).</p>



<h3 class="wp-block-heading"><strong>Código C:</strong></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" 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;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#include <stdio.h&gt;
#include <stdlib.h&gt;
#include <math.h&gt;

#define PI 3.141592653589793

typedef struct {
    double real;
    double imag;
} Complex;

void DFT(double* x, Complex* X, int N) {
    for (int k = 0; k < N; k++) {
        X[k].real = 0;
        X[k].imag = 0;
        for (int n = 0; n < N; n++) {
            double angle = -2.0 * PI * k * n / N;
            X[k].real += x[n] * cos(angle);
            X[k].imag += x[n] * sin(angle);
        }
    }
}

int main() {
    int N = 8;
    double x[8] = {1, 0, -1, 0, 1, 0, -1, 0}; // Sinal de teste

    Complex* X = (Complex*)malloc(N * sizeof(Complex));

    DFT(x, X, N);

    printf(&quot;DFT Result:\n&quot;);
    for (int k = 0; k < N; k++) {
        printf(&quot;X[%d] = %.2f + %.2fi\n&quot;, k, X[k].real, X[k].imag);
    }

    free(X);
    return 0;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">#include &lt;stdio.h&gt;</span></span>
<span class="line"><span style="color: #616E88">#include &lt;stdlib.h&gt;</span></span>
<span class="line"><span style="color: #616E88">#include &lt;math.h&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">#define PI 3.141592653589793</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">real</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">imag</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">} Complex;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">DFT</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">double*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Complex</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">X,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">X[k].real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">X[k].imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">n++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">angle</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-2.0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">X[k].real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x[n]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">cos</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">angle</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">X[k].imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x[n]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sin</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">angle</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">main</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x[</span><span style="color: #B48EAD">8</span><span style="color: #A3BE8C">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">1</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-1,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-1,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">}</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Sinal</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">teste</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">Complex*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">X</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> (Complex*)malloc</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sizeof</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">Complex</span><span style="color: #ECEFF4">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">DFT(x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">X,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">&quot;DFT Result:\n&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">&quot;X[%d] = %.2f + %.2fi\n&quot;</span><span style="color: #88C0D0">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">k,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">X[k].real,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">X[k].imag</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">free(X</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Esse código implementa diretamente a fórmula da DFT. Note que o tempo de execução cresce com \(N^2\), por isso para sinais muito longos recomenda-se usar a Transformada Rápida de Fourier (FFT), que veremos em outra seção.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>A Transformada Rápida de Fourier (FFT)</strong></h2>



<h3 class="wp-block-heading"><strong>Por que otimizar?</strong></h3>



<p class="wp-block-paragraph">Como vimos, a DFT exige N2N^2 operações para calcular todas as NN frequências de um sinal com NN amostras. Isso pode ser extremamente lento para sinais grandes. A <strong>Transformada Rápida de Fourier (FFT)</strong> resolve esse problema ao reduzir a complexidade para Nlog⁡2NN \log_2 N, um ganho <strong>drástico</strong> em eficiência.</p>



<p class="wp-block-paragraph">A FFT é uma maneira inteligente de reorganizar os cálculos da DFT, explorando simetrias matemáticas para evitar repetições desnecessárias.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>Ideia por trás da FFT</strong></h2>



<p class="wp-block-paragraph">A FFT mais conhecida é o algoritmo de <strong>Cooley-Tukey</strong>, que se baseia em dividir o sinal original em duas partes:</p>



<ul class="wp-block-list">
<li>Amostras de índices pares: \(x_0, x_2, x_4, \ldots\)</li>



<li>Amostras de índices ímpares: \(x_1, x_3, x_5, \ldots\)</li>
</ul>



<p class="wp-block-paragraph">Essa divisão é aplicada recursivamente, até que reste apenas DFTs de tamanho 2, cuja solução é trivial.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>Implementação em C da FFT (Radix-2, Recursiva)</strong></h2>



<p class="wp-block-paragraph">Abaixo temos uma implementação simples e didática da FFT recursiva. Vamos assumir que o número de amostras NN seja uma potência de 2.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" 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;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#include <stdio.h&gt;
#include <stdlib.h&gt;
#include <math.h&gt;

#define PI 3.141592653589793

typedef struct {
    double real;
    double imag;
} Complex;

void fft(Complex* x, int N) {
    if (N <= 1) return;

    // Divide: cria vetores para pares e ímpares
    Complex* even = (Complex*)malloc(N/2 * sizeof(Complex));
    Complex* odd  = (Complex*)malloc(N/2 * sizeof(Complex));

    for (int i = 0; i < N/2; i++) {
        even[i] = x[2*i];
        odd[i]  = x[2*i + 1];
    }

    // Conquista: aplica FFT recursivamente
    fft(even, N/2);
    fft(odd, N/2);

    // Combina: calcula FFT final com os pares e ímpares
    for (int k = 0; k < N/2; k++) {
        double angle = -2 * PI * k / N;
        Complex twiddle = {cos(angle), sin(angle)};
        Complex t = {
            twiddle.real * odd[k].real - twiddle.imag * odd[k].imag,
            twiddle.real * odd[k].imag + twiddle.imag * odd[k].real
        };
        x[k].real       = even[k].real + t.real;
        x[k].imag       = even[k].imag + t.imag;
        x[k + N/2].real = even[k].real - t.real;
        x[k + N/2].imag = even[k].imag - t.imag;
    }

    free(even);
    free(odd);
}

int main() {
    int N = 8;

    // Sinal de entrada (parte imaginária zero)
    Complex x[8] = {
        {1,0}, {0,0}, {-1,0}, {0,0},
        {1,0}, {0,0}, {-1,0}, {0,0}
    };

    fft(x, N);

    printf(&quot;FFT Result:\n&quot;);
    for (int i = 0; i < N; i++) {
        printf(&quot;X[%d] = %.2f + %.2fi\n&quot;, i, x[i].real, x[i].imag);
    }

    return 0;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">#include &lt;stdio.h&gt;</span></span>
<span class="line"><span style="color: #616E88">#include &lt;stdlib.h&gt;</span></span>
<span class="line"><span style="color: #616E88">#include &lt;math.h&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">#define PI 3.141592653589793</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">real</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">imag</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">} Complex;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">fft</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">Complex*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">return;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Divide:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">cria</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">vetores</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pares</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ímpares</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">Complex*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">even</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> (Complex*)malloc</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">N/2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sizeof</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">Complex</span><span style="color: #ECEFF4">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">Complex*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">odd</span><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> (Complex*)malloc</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">N/2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sizeof</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">Complex</span><span style="color: #ECEFF4">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N/2</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">even[i]</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x[</span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">*</span><span style="color: #A3BE8C">i]</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">odd[i]</span><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x[</span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">*</span><span style="color: #A3BE8C">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #A3BE8C">]</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Conquista:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">aplica</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">FFT</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">recursivamente</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">fft(even,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N/2</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">fft(odd,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N/2</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Combina:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">calcula</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">FFT</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">final</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">com</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">os</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pares</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ímpares</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N/2</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">angle</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">Complex</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">twiddle</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{cos</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">angle</span><span style="color: #ECEFF4">)</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sin</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">angle</span><span style="color: #ECEFF4">)</span><span style="color: #A3BE8C">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">Complex</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">twiddle.real</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">odd[k].real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">twiddle.imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">odd[k].imag,</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">twiddle.real</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">odd[k].imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">twiddle.imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">odd[k].real</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">x[k].real</span><span style="color: #D8DEE9FF">       </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">even[k].real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">t.real</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">x[k].imag</span><span style="color: #D8DEE9FF">       </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">even[k].imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">t.imag</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">x[k</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N/2].real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">even[k].real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">t.real</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">x[k</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N/2].imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">even[k].imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">t.imag</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">free(even</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">free(odd</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">main</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Sinal</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">entrada</span><span style="color: #D8DEE9FF"> (parte </span><span style="color: #A3BE8C">imaginária</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">zero</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">Complex</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x[</span><span style="color: #B48EAD">8</span><span style="color: #A3BE8C">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">{</span><span style="color: #88C0D0">1,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">-1</span><span style="color: #A3BE8C">,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,0},</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">{</span><span style="color: #88C0D0">1,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">-1</span><span style="color: #A3BE8C">,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,0}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">fft(x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">&quot;FFT Result:\n&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">&quot;X[%d] = %.2f + %.2fi\n&quot;</span><span style="color: #88C0D0">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">i,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x[i].real,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x[i].imag</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>Comparando FFT e DFT</strong></h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Característica</th><th>DFT</th><th>FFT</th></tr></thead><tbody><tr><td>Complexidade</td><td>\(O(N^2)\)</td><td>\(O(N \log_2 N)\)</td></tr><tr><td>Requisitos</td><td>Nenhum</td><td>NN deve ser potência de 2</td></tr><tr><td>Código</td><td>Simples, direto</td><td>Recursivo, mais eficiente</td></tr><tr><td>Uso prático</td><td>Pequenos sinais</td><td>Sinais grandes (áudio, imagem, etc.)</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>Aplicando a FFT a Sinais Reais de Sensores ou Áudio</strong></h2>



<h3 class="wp-block-heading"><strong>Captura e amostragem de sinais reais</strong></h3>



<p class="wp-block-paragraph">Sensores — como acelerômetros, termistores ou microfones — produzem sinais analógicos contínuos no tempo. Para aplicar a FFT, é necessário amostrar esses sinais com um conversor analógico-digital (ADC), obtendo um vetor de amostras igualmente espaçadas no tempo.</p>



<p class="wp-block-paragraph">Esse processo gera um vetor \(x[n]\) com N amostras igualmente espaçadas por um intervalo de tempo \(T_s\), definido pela taxa de amostragem \(f_s: T_s = \frac{1}{f_s}\)</p>



<p class="wp-block-paragraph">Por exemplo, uma taxa de 1000 Hz implica em uma amostra a cada 1 ms.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Pré-processamento</strong></h3>



<p class="wp-block-paragraph">Antes de aplicar a FFT em um sinal real, recomenda-se:</p>



<ol class="wp-block-list">
<li><strong>Remover a média (DC)</strong>: \(x[n] := x[n] &#8211; \frac{1}{N} \sum_{i=0}^{N-1} x[i]\) Isso evita picos indesejados na frequência zero (DC offset).</li>



<li><strong>Aplicar janela (windowing)</strong>: Sinais reais nem sempre são periódicos no intervalo analisado. O uso de uma janela como a de Hanning, Hamming ou Blackman suaviza as bordas do sinal e reduz o vazamento espectral (aliasing).</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo prático com FFT</strong></h3>



<p class="wp-block-paragraph">A seguir, adaptamos nosso código para aplicar FFT a um sinal real simulado — representando, por exemplo, a vibração medida por um acelerômetro.</p>



<h4 class="wp-block-heading"><strong>Sinal de teste</strong>:</h4>



<p class="wp-block-paragraph">Simularemos um sinal real com duas senóides: uma de 50 Hz e outra de 120 Hz, amostradas a 1000 Hz: </p>



<p class="wp-block-paragraph">\[<br>x[n] = \sin(2\pi 50 n T_s) + 0.5 \cdot \sin(2\pi 120 n T_s)<br>\]



<h4 class="wp-block-heading"><strong>Código em C:</strong></h4>



<div class="wp-block-kevinbatdorf-code-block-pro" 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;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#include <stdio.h&gt;
#include <stdlib.h&gt;
#include <math.h&gt;

#define PI 3.141592653589793
#define FS 1000  // taxa de amostragem (Hz)
#define N 1024   // número de amostras (potência de 2)

typedef struct {
    double real;
    double imag;
} Complex;

// Mesma função FFT da seção anterior (recursiva)
void fft(Complex* x, int N);

// Gera um sinal real composto por duas senóides
void gerar_sinal(Complex* x) {
    for (int n = 0; n < N; n++) {
        double t = (double)n / FS;
        double s = sin(2 * PI * 50 * t) + 0.5 * sin(2 * PI * 120 * t);
        x[n].real = s;
        x[n].imag = 0;
    }
}

// Calcula módulo da FFT
double modulo(Complex c) {
    return sqrt(c.real * c.real + c.imag * c.imag);
}

int main() {
    Complex x[N];
    gerar_sinal(x);

    fft(x, N);

    printf(&quot;Frequência (Hz)\tMagnitude\n&quot;);
    for (int i = 0; i < N/2; i++) {
        double freq = (double)i * FS / N;
        double mag = modulo(x[i]) * 2.0 / N; // normaliza e dobra por ser simétrica
        printf(&quot;%.1f\t\t%.4f\n&quot;, freq, mag);
    }

    return 0;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">#include &lt;stdio.h&gt;</span></span>
<span class="line"><span style="color: #616E88">#include &lt;stdlib.h&gt;</span></span>
<span class="line"><span style="color: #616E88">#include &lt;math.h&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">#define PI 3.141592653589793</span></span>
<span class="line"><span style="color: #616E88">#define FS 1000  // taxa de amostragem (Hz)</span></span>
<span class="line"><span style="color: #616E88">#define N 1024   // número de amostras (potência de 2)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">real</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">imag</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">} Complex;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Mesma</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">função</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">FFT</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">da</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">seção</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">anterior</span><span style="color: #D8DEE9FF"> (recursiva)</span></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">fft</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">Complex*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Gera</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">um</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sinal</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">composto</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">por</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">duas</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">senóides</span></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">gerar_sinal</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">Complex*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">n++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> (double)n / FS</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">s</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sin</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">50</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">t</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.5</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sin</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">120</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">t</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">x[n].real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">s</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">x[n].imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Calcula</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">módulo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">da</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">FFT</span></span>
<span class="line"><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">modulo</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">Complex</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">c</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sqrt</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">c.real</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">c.real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">c.imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">c.imag</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">main</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">Complex</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x[N]</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">gerar_sinal(x</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">fft(x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">&quot;Frequência (Hz)\tMagnitude\n&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N/2</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">freq</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> (double)i </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> FS / N</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mag</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">modulo</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">x[i]</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2.0</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">normaliza</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dobra</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">por</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ser</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">simétrica</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">&quot;%.1f\t\t%.4f\n&quot;</span><span style="color: #88C0D0">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">freq,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mag</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Interpretando o resultado</strong></h3>



<ul class="wp-block-list">
<li>O vetor FFT possui NN valores complexos.</li>



<li>Para sinais reais, os valores são simétricos: basta analisar os primeiros N/2 pontos.</li>



<li>Cada índice ii corresponde a uma frequência:\(f_i = \frac{i \cdot f_s}{N}\)</li>



<li>A magnitude |X[i]| representa a “força” (amplitude) do sinal naquela frequência.</li>



<li>Os picos na magnitude indicam quais frequências dominam o sinal.</li>
</ul>



<h4 class="wp-block-heading"><strong>Saída esperada (parcial):</strong></h4>



<pre class="wp-block-code"><code>Frequência (Hz)	Magnitude
...
50.0		    1.0000
...
120.0		    0.5000
...
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>A Transformada Inversa de Fourier (iFFT)</strong></h2>



<h3 class="wp-block-heading"><strong>O que é a iFFT?</strong></h3>



<p class="wp-block-paragraph">A Transformada Inversa de Fourier, ou <strong>iFFT</strong>, permite reconstruir um sinal no tempo a partir de suas componentes de frequência.</p>



<p class="wp-block-paragraph">Ela é definida como: x[n]=1N∑k=0N−1X[k]⋅ej2πNknx[n] = \frac{1}{N} \sum_{k=0}^{N-1} X[k] \cdot e^{j \frac{2\pi}{N}kn}</p>



<p class="wp-block-paragraph">Ou seja, usamos os mesmos valores complexos X[k]X[k] da FFT e, com uma fórmula semelhante, obtemos novamente as amostras originais do sinal.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Quando a iFFT é usada?</strong></h3>



<ul class="wp-block-list">
<li>Após aplicar filtros no domínio da frequência.</li>



<li>Na decodificação de sinais comprimidos (ex: MP3, JPEG).</li>



<li>Para criar sons ou sinais com componentes espectrais específicas.</li>



<li>Para análise de sistemas (ex: resposta impulsiva via FFT/iFFT).</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Implementação em C da iFFT</strong></h3>



<p class="wp-block-paragraph">A iFFT é quase idêntica à FFT — a diferença está no sinal do expoente (usa +j+j ao invés de −j-j) e na normalização final por NN.</p>



<h4 class="wp-block-heading"><strong>Código: iFFT em C</strong></h4>



<div class="wp-block-kevinbatdorf-code-block-pro" 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;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#include <stdio.h&gt;
#include <stdlib.h&gt;
#include <math.h&gt;

#define PI 3.141592653589793
#define N 8

typedef struct {
    double real;
    double imag;
} Complex;

// Função auxiliar para inverter os sinais do imaginário
void conjugar(Complex* x, int N) {
    for (int i = 0; i < N; i++)
        x[i].imag = -x[i].imag;
}

// Reaproveitamos a mesma FFT, trocando o sinal antes e depois
void fft(Complex* x, int N);  // Assume-se definida (como antes)

// iFFT com normalização
void ifft(Complex* x, int N) {
    // Conjuga
    conjugar(x, N);

    // Aplica FFT &quot;espelhada&quot;
    fft(x, N);

    // Conjuga novamente e divide por N
    conjugar(x, N);
    for (int i = 0; i < N; i++) {
        x[i].real /= N;
        x[i].imag /= N;
    }
}

int main() {
    Complex X[N] = {
        {0,0}, {4,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}
    };

    ifft(X, N);

    printf(&quot;Sinal reconstruído:\n&quot;);
    for (int i = 0; i < N; i++) {
        printf(&quot;x[%d] = %.4f\n&quot;, i, X[i].real);  // ignorando parte imaginária residual
    }

    return 0;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">#include &lt;stdio.h&gt;</span></span>
<span class="line"><span style="color: #616E88">#include &lt;stdlib.h&gt;</span></span>
<span class="line"><span style="color: #616E88">#include &lt;math.h&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">#define PI 3.141592653589793</span></span>
<span class="line"><span style="color: #616E88">#define N 8</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">real</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">imag</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">} Complex;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Função</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">auxiliar</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">inverter</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">os</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sinais</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">imaginário</span></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">conjugar</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">Complex*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i++</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">x[i].imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-x</span><span style="color: #ECEFF4">[</span><span style="color: #A3BE8C">i</span><span style="color: #ECEFF4">]</span><span style="color: #A3BE8C">.imag</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Reaproveitamos</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mesma</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">FFT,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">trocando</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">o</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sinal</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">antes</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">depois</span></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">fft</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">Complex*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Assume-se</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">definida</span><span style="color: #D8DEE9FF"> (como </span><span style="color: #A3BE8C">antes</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">iFFT</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">com</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">normalização</span></span>
<span class="line"><span style="color: #88C0D0">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ifft</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">Complex*</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Conjuga</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">conjugar(x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Aplica</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">FFT</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">espelhada</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">fft(x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Conjuga</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">novamente</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">divide</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">por</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">conjugar(x,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">x[i].real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">x[i].imag</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">main</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">Complex</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">X[N]</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">{</span><span style="color: #88C0D0">0,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">4</span><span style="color: #A3BE8C">,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,0},</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">{</span><span style="color: #B48EAD">0</span><span style="color: #A3BE8C">,0}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ifft(X,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">&quot;Sinal reconstruído:\n&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">&quot;x[%d] = %.4f\n&quot;</span><span style="color: #88C0D0">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">i,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">X[i].real</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">ignorando</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">parte</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">imaginária</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">residual</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Sobre a parte imaginária</strong></h3>



<p class="wp-block-paragraph">A parte imaginária <strong>após a iFFT de um sinal real</strong> deve ser próxima de zero (por erro numérico). Em aplicações práticas, ela é ignorada ou descartada:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" 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;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="double x_real = X[i].real; // Parte útil
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x_real</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">X[i].real</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">//</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Parte</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">útil</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Validação: FFT + iFFT</strong></h3>



<p class="wp-block-paragraph">Um teste típico para validar seu código de FFT/iFFT é:</p>



<ol class="wp-block-list">
<li>Criar um sinal x[n].</li>



<li>Aplicar FFT para obter X[k].</li>



<li>Aplicar iFFT em X[k].</li>



<li>Comparar os valores de x[n] com os reconstruídos.</li>
</ol>



<p class="wp-block-paragraph">Se os valores coincidirem (até erros mínimos), seu sistema está funcionando corretamente.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Aplicações avançadas</strong></h3>



<ul class="wp-block-list">
<li><strong>Equalização de áudio</strong>: ajustar frequências específicas e depois aplicar iFFT.</li>



<li><strong>Cancelamento de ruído</strong>: eliminar certas frequências antes da iFFT.</li>



<li><strong>Compressão</strong>: manter só os coeficientes mais relevantes (ex: JPEG).</li>



<li><strong>Síntese sonora</strong>: construir sons pela manipulação direta do espectro.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>11. Conclusão</strong></h2>



<p class="wp-block-paragraph">A Transformada de Fourier é uma ferramenta indispensável para engenheiros, programadores e cientistas que trabalham com sinais, vibrações, sons, imagens ou qualquer fenômeno periódico ou oscilatório. Ela permite revelar o conteúdo de frequência de um sinal, detectar padrões invisíveis no domínio do tempo e aplicar uma vasta gama de técnicas de processamento, filtragem e reconstrução.</p>



<p class="wp-block-paragraph">Neste artigo, vimos:</p>



<ul class="wp-block-list">
<li>A base teórica da Transformada de Fourier contínua e discreta;</li>



<li>A implementação direta da DFT em linguagem C;</li>



<li>A otimização via FFT (Fast Fourier Transform);</li>



<li>A aplicação prática da FFT em sinais reais de sensores ou áudio;</li>



<li>A reconstrução do sinal original usando a iFFT;</li>



<li>E a importância da interpretação correta dos resultados espectrais.</li>
</ul>



<p class="wp-block-paragraph">Tudo foi feito com um olhar didático e com exemplos práticos, prontos para adaptação em sistemas embarcados, análise de sinais em tempo real ou mesmo aplicações científicas mais robustas.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Próximos passos sugeridos</strong></h3>



<p class="wp-block-paragraph">Caso queira aprofundar ainda mais o estudo e uso da Transformada de Fourier, recomenda-se explorar:</p>



<ul class="wp-block-list">
<li>Implementações de FFT otimizadas para microcontroladores (ex: CMSIS-DSP para ARM Cortex-M);</li>



<li>Visualização gráfica com Python/Matplotlib para depuração e análise;</li>



<li>Filtragem digital (passa-baixas, passa-altas, notch) no domínio da frequência;</li>



<li>Algoritmos FFT para sinais de tamanho não potência de 2 (Bluestein ou Mixed-Radix);</li>



<li>Uso de janelas (Hamming, Blackman, etc.) para melhorar a resolução espectral.</li>
</ul>



<p class="wp-block-paragraph">Se quiser, posso te ajudar a gerar qualquer um desses tópicos em novas seções ou aplicações.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/algoritimos/a-transformada-de-fourier-fundamentos-demonstracao-e-implementacao-em-c/">A Transformada de Fourier: Fundamentos, Demonstração e Implementação em C</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">212</post-id>	</item>
	</channel>
</rss>
