<?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>remoção de 60Hz - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/remocao-de-60hz/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.1.3</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>remoção de 60Hz - 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>
	</channel>
</rss>
