<?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>Algoritimos - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/categorias/algoritimos/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Mon, 11 May 2026 16:08:46 +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>Algoritimos - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Conversor Analógico Delta-Sigma (ΔΣ ADC)</title>
		<link>https://mcu.tec.br/algoritimos/dsp/conversor-analogico-delta-sigma-%ce%b4%cf%83-adc/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=conversor-analogico-delta-sigma-%25ce%25b4%25cf%2583-adc</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Mon, 11 May 2026 16:07:50 +0000</pubDate>
				<category><![CDATA[ADC/DAC]]></category>
		<category><![CDATA[DSP]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1430</guid>

					<description><![CDATA[<p>Aprenda detalhadamente como funciona o conversor analógico Delta-Sigma (ΣΔ ADC), entendendo conceitos como oversampling, noise shaping, quantização, moduladores Sigma-Delta, filtros CIC, decimação, SNR, ENOB e DSD. Veja comparações entre ADC Flash, SAR e Pipeline, além de aplicações práticas em microcontroladores, FPGAs, áudio digital, instrumentação, sensores industriais, controle de potência e sistemas embarcados modernos. Um guia técnico e didático sobre a arquitetura Sigma-Delta aplicado ao universo MCU &#038; FPGA.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/dsp/conversor-analogico-delta-sigma-%ce%b4%cf%83-adc/">Conversor Analógico Delta-Sigma (ΔΣ ADC)</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-oj5nd wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-oj5nd "><div class="eb-toc-container eb-toc-oj5nd  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;O Problema da Quantiza\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;O Problema da Quantiza\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Superamostragem (Oversampling)&quot;,&quot;text&quot;:&quot;Superamostragem (Oversampling)&quot;,&quot;link&quot;:&quot;superamostragem-oversampling&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Estrutura Interna do Conversor Delta-Sigma&quot;,&quot;text&quot;:&quot;Estrutura Interna do Conversor Delta-Sigma&quot;,&quot;link&quot;:&quot;estrutura-interna-do-conversor-delta-sigma&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Vis\u00e3o Conceitual do Modulador&quot;,&quot;text&quot;:&quot;Vis\u00e3o Conceitual do Modulador&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;O Integrador&quot;,&quot;text&quot;:&quot;O Integrador&quot;,&quot;link&quot;:&quot;o-integrador&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Quantizador de 1 Bit&quot;,&quot;text&quot;:&quot;Quantizador de 1 Bit&quot;,&quot;link&quot;:&quot;quantizador-de-1-bit&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;DAC de Realimenta\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;DAC de Realimenta\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Fluxo de Bits (Bitstream)&quot;,&quot;text&quot;:&quot;Fluxo de Bits (Bitstream)&quot;,&quot;link&quot;:&quot;fluxo-de-bits-bitstream&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Noise Shaping&quot;,&quot;text&quot;:&quot;Noise Shaping&quot;,&quot;link&quot;:&quot;noise-shaping&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Filtro Digital de Decima\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Filtro Digital de Decima\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-9&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1. Filtrar ru\u00eddo de alta frequ\u00eancia&quot;,&quot;text&quot;:&quot;1. Filtrar ru\u00eddo de alta frequ\u00eancia&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2. Reduzir a taxa de amostragem&quot;,&quot;text&quot;:&quot;2. Reduzir a taxa de amostragem&quot;,&quot;link&quot;:&quot;2-reduzir-a-taxa-de-amostragem&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Rela\u00e7\u00e3o entre Oversampling e Resolu\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o entre Oversampling e Resolu\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-12&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Ordens do Modulador&quot;,&quot;text&quot;:&quot;Ordens do Modulador&quot;,&quot;link&quot;:&quot;ordens-do-modulador&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Compara\u00e7\u00e3o entre Delta-Sigma, SAR, Flash e Pipeline ADC&quot;,&quot;text&quot;:&quot;Compara\u00e7\u00e3o entre Delta-Sigma, SAR, Flash e Pipeline ADC&quot;,&quot;link&quot;:&quot;eb-table-content-14&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;ADC Flash&quot;,&quot;text&quot;:&quot;ADC Flash&quot;,&quot;link&quot;:&quot;adc-flash&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Estrutura&quot;,&quot;text&quot;:&quot;Estrutura&quot;,&quot;link&quot;:&quot;estrutura&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Compara\u00e7\u00e3o com Delta-Sigma&quot;,&quot;text&quot;:&quot;Compara\u00e7\u00e3o com Delta-Sigma&quot;,&quot;link&quot;:&quot;eb-table-content-17&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;ADC SAR (Successive Approximation Register)&quot;,&quot;text&quot;:&quot;ADC SAR (Successive Approximation Register)&quot;,&quot;link&quot;:&quot;adc-sar-successive-approximation-register&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Funcionamento&quot;,&quot;text&quot;:&quot;Funcionamento&quot;,&quot;link&quot;:&quot;funcionamento&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Tempo de Convers\u00e3o&quot;,&quot;text&quot;:&quot;Tempo de Convers\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-20&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Caracter\u00edsticas&quot;,&quot;text&quot;:&quot;Caracter\u00edsticas&quot;,&quot;link&quot;:&quot;eb-table-content-21&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Compara\u00e7\u00e3o com Delta-Sigma&quot;,&quot;text&quot;:&quot;Compara\u00e7\u00e3o com Delta-Sigma&quot;,&quot;link&quot;:&quot;eb-table-content-22&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;ADC Pipeline&quot;,&quot;text&quot;:&quot;ADC Pipeline&quot;,&quot;link&quot;:&quot;adc-pipeline&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Conceito&quot;,&quot;text&quot;:&quot;Conceito&quot;,&quot;link&quot;:&quot;conceito&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Caracter\u00edsticas&quot;,&quot;text&quot;:&quot;Caracter\u00edsticas&quot;,&quot;link&quot;:&quot;eb-table-content-25&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Compara\u00e7\u00e3o com Delta-Sigma&quot;,&quot;text&quot;:&quot;Compara\u00e7\u00e3o com Delta-Sigma&quot;,&quot;link&quot;:&quot;eb-table-content-26&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Por que o Delta-Sigma possui Alta Lat\u00eancia?&quot;,&quot;text&quot;:&quot;Por que o Delta-Sigma possui Alta Lat\u00eancia?&quot;,&quot;link&quot;:&quot;eb-table-content-27&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Aplica\u00e7\u00f5es Ideais para Delta-Sigma&quot;,&quot;text&quot;:&quot;Aplica\u00e7\u00f5es Ideais para Delta-Sigma&quot;,&quot;link&quot;:&quot;eb-table-content-28&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;\u00c1udio Digital&quot;,&quot;text&quot;:&quot;\u00c1udio Digital&quot;,&quot;link&quot;:&quot;eb-table-content-29&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Instrumenta\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Instrumenta\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-30&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Sensores de Precis\u00e3o&quot;,&quot;text&quot;:&quot;Sensores de Precis\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-31&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Microcontroladores Modernos&quot;,&quot;text&quot;:&quot;Microcontroladores Modernos&quot;,&quot;link&quot;:&quot;microcontroladores-modernos&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Uso em FPGAs&quot;,&quot;text&quot;:&quot;Uso em FPGAs&quot;,&quot;link&quot;:&quot;uso-em-fpgas&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Moduladores Delta-Sigma de Ordens Superiores&quot;,&quot;text&quot;:&quot;Moduladores Delta-Sigma de Ordens Superiores&quot;,&quot;link&quot;:&quot;moduladores-delta-sigma-de-ordens-superiores&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Noise Shaping em Diferentes Ordens&quot;,&quot;text&quot;:&quot;Noise Shaping em Diferentes Ordens&quot;,&quot;link&quot;:&quot;noise-shaping-em-diferentes-ordens&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Primeira Ordem&quot;,&quot;text&quot;:&quot;Primeira Ordem&quot;,&quot;link&quot;:&quot;primeira-ordem&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Segunda Ordem&quot;,&quot;text&quot;:&quot;Segunda Ordem&quot;,&quot;link&quot;:&quot;segunda-ordem&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Terceira Ordem&quot;,&quot;text&quot;:&quot;Terceira Ordem&quot;,&quot;link&quot;:&quot;terceira-ordem&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Rela\u00e7\u00e3o entre Ordem e SNR&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o entre Ordem e SNR&quot;,&quot;link&quot;:&quot;eb-table-content-39&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Primeira ordem&quot;,&quot;text&quot;:&quot;Primeira ordem&quot;,&quot;link&quot;:&quot;primeira-ordem&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Segunda ordem&quot;,&quot;text&quot;:&quot;Segunda ordem&quot;,&quot;link&quot;:&quot;segunda-ordem&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Terceira ordem&quot;,&quot;text&quot;:&quot;Terceira ordem&quot;,&quot;link&quot;:&quot;terceira-ordem&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Problema da Estabilidade&quot;,&quot;text&quot;:&quot;Problema da Estabilidade&quot;,&quot;link&quot;:&quot;problema-da-estabilidade&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Arquitetura MASH (Multi-Stage Noise Shaping)&quot;,&quot;text&quot;:&quot;Arquitetura MASH (Multi-Stage Noise Shaping)&quot;,&quot;link&quot;:&quot;arquitetura-mash-multi-stage-noise-shaping&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Quantizadores Multi-Bit&quot;,&quot;text&quot;:&quot;Quantizadores Multi-Bit&quot;,&quot;link&quot;:&quot;quantizadores-multi-bit&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Filtros de Decima\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Filtros de Decima\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-46&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Filtros CIC&quot;,&quot;text&quot;:&quot;Filtros CIC&quot;,&quot;link&quot;:&quot;filtros-cic&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;ENOB (Effective Number Of Bits)&quot;,&quot;text&quot;:&quot;ENOB (Effective Number Of Bits)&quot;,&quot;link&quot;:&quot;enob-effective-number-of-bits&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;THD e SINAD&quot;,&quot;text&quot;:&quot;THD e SINAD&quot;,&quot;link&quot;:&quot;thd-e-sinad&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;THD&quot;,&quot;text&quot;:&quot;THD&quot;,&quot;link&quot;:&quot;thd&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;SINAD&quot;,&quot;text&quot;:&quot;SINAD&quot;,&quot;link&quot;:&quot;sinad&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Problema do Clock Jitter&quot;,&quot;text&quot;:&quot;Problema do Clock Jitter&quot;,&quot;link&quot;:&quot;problema-do-clock-jitter&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;\u00c1udio Hi-Fi e Delta-Sigma&quot;,&quot;text&quot;:&quot;\u00c1udio Hi-Fi e Delta-Sigma&quot;,&quot;link&quot;:&quot;eb-table-content-53&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Limita\u00e7\u00f5es Fundamentais&quot;,&quot;text&quot;:&quot;Limita\u00e7\u00f5es Fundamentais&quot;,&quot;link&quot;:&quot;eb-table-content-54&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;N\u00e3o \u00e9 ideal para sinais ultrarr\u00e1pidos&quot;,&quot;text&quot;:&quot;N\u00e3o \u00e9 ideal para sinais ultrarr\u00e1pidos&quot;,&quot;link&quot;:&quot;eb-table-content-55&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Consumo Digital&quot;,&quot;text&quot;:&quot;Consumo Digital&quot;,&quot;link&quot;:&quot;consumo-digital&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Instabilidade&quot;,&quot;text&quot;:&quot;Instabilidade&quot;,&quot;link&quot;:&quot;instabilidade&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Clock extremamente cr\u00edtico&quot;,&quot;text&quot;:&quot;Clock extremamente cr\u00edtico&quot;,&quot;link&quot;:&quot;eb-table-content-58&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Delta-Sigma em Microcontroladores, FPGA e Sistemas Embarcados&quot;,&quot;text&quot;:&quot;Delta-Sigma em Microcontroladores, FPGA e Sistemas Embarcados&quot;,&quot;link&quot;:&quot;delta-sigma-em-microcontroladores-fpga-e-sistemas-embarcados&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;ADCs Delta-Sigma em Microcontroladores&quot;,&quot;text&quot;:&quot;ADCs Delta-Sigma em Microcontroladores&quot;,&quot;link&quot;:&quot;adcs-delta-sigma-em-microcontroladores&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Por que usar Delta-Sigma em Medi\u00e7\u00e3o de Corrente?&quot;,&quot;text&quot;:&quot;Por que usar Delta-Sigma em Medi\u00e7\u00e3o de Corrente?&quot;,&quot;link&quot;:&quot;eb-table-content-61&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Moduladores Externos Sigma-Delta&quot;,&quot;text&quot;:&quot;Moduladores Externos Sigma-Delta&quot;,&quot;link&quot;:&quot;moduladores-externos-sigma-delta&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Isola\u00e7\u00e3o Galv\u00e2nica Simplificada&quot;,&quot;text&quot;:&quot;Isola\u00e7\u00e3o Galv\u00e2nica Simplificada&quot;,&quot;link&quot;:&quot;eb-table-content-63&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Exemplo Real: Controle de Inversores&quot;,&quot;text&quot;:&quot;Exemplo Real: Controle de Inversores&quot;,&quot;link&quot;:&quot;exemplo-real-controle-de-inversores&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Filtros SINC&quot;,&quot;text&quot;:&quot;Filtros SINC&quot;,&quot;link&quot;:&quot;filtros-sinc&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Delta-Sigma em FPGA&quot;,&quot;text&quot;:&quot;Delta-Sigma em FPGA&quot;,&quot;link&quot;:&quot;delta-sigma-em-fpga&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;DAC Sigma-Delta em FPGA&quot;,&quot;text&quot;:&quot;DAC Sigma-Delta em FPGA&quot;,&quot;link&quot;:&quot;dac-sigma-delta-em-fpga&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Exemplo Conceitual em Verilog&quot;,&quot;text&quot;:&quot;Exemplo Conceitual em Verilog&quot;,&quot;link&quot;:&quot;exemplo-conceitual-em-verilog&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Delta-Sigma e PWM&quot;,&quot;text&quot;:&quot;Delta-Sigma e PWM&quot;,&quot;link&quot;:&quot;delta-sigma-e-pwm&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;PWM (Pulse Width Modulation)&quot;,&quot;text&quot;:&quot;PWM (Pulse Width Modulation)&quot;,&quot;link&quot;:&quot;pwm-pulse-width-modulation&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;PDM (Pulse Density Modulation)&quot;,&quot;text&quot;:&quot;PDM (Pulse Density Modulation)&quot;,&quot;link&quot;:&quot;pdm-pulse-density-modulation&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Aplica\u00e7\u00f5es em Fontes Chaveadas&quot;,&quot;text&quot;:&quot;Aplica\u00e7\u00f5es em Fontes Chaveadas&quot;,&quot;link&quot;:&quot;eb-table-content-72&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Sensores MEMS e Sigma-Delta&quot;,&quot;text&quot;:&quot;Sensores MEMS e Sigma-Delta&quot;,&quot;link&quot;:&quot;sensores-mems-e-sigma-delta&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Conversores de \u00c1udio MEMS&quot;,&quot;text&quot;:&quot;Conversores de \u00c1udio MEMS&quot;,&quot;link&quot;:&quot;eb-table-content-74&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Rela\u00e7\u00e3o com DSP Moderno&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o com DSP Moderno&quot;,&quot;link&quot;:&quot;eb-table-content-75&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Fundamentos Matem\u00e1ticos do Noise Shaping&quot;,&quot;text&quot;:&quot;Fundamentos Matem\u00e1ticos do Noise Shaping&quot;,&quot;link&quot;:&quot;eb-table-content-76&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Modelo Linear do Modulador&quot;,&quot;text&quot;:&quot;Modelo Linear do Modulador&quot;,&quot;link&quot;:&quot;modelo-linear-do-modulador&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Estrutura Linearizada&quot;,&quot;text&quot;:&quot;Estrutura Linearizada&quot;,&quot;link&quot;:&quot;estrutura-linearizada&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Signal Transfer Function (STF)&quot;,&quot;text&quot;:&quot;Signal Transfer Function (STF)&quot;,&quot;link&quot;:&quot;signal-transfer-function-stf&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Noise Transfer Function (NTF)&quot;,&quot;text&quot;:&quot;Noise Transfer Function (NTF)&quot;,&quot;link&quot;:&quot;noise-transfer-function-ntf&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Interpreta\u00e7\u00e3o F\u00edsica&quot;,&quot;text&quot;:&quot;Interpreta\u00e7\u00e3o F\u00edsica&quot;,&quot;link&quot;:&quot;eb-table-content-81&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Segunda Ordem&quot;,&quot;text&quot;:&quot;Segunda Ordem&quot;,&quot;link&quot;:&quot;segunda-ordem&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Ordem Superior&quot;,&quot;text&quot;:&quot;Ordem Superior&quot;,&quot;link&quot;:&quot;ordem-superior&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Ru\u00eddo de Quantiza\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Ru\u00eddo de Quantiza\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-84&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Oversampling e Ru\u00eddo&quot;,&quot;text&quot;:&quot;Oversampling e Ru\u00eddo&quot;,&quot;link&quot;:&quot;eb-table-content-85&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Rela\u00e7\u00e3o com OSR&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o com OSR&quot;,&quot;link&quot;:&quot;eb-table-content-86&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;SNR em Delta-Sigma&quot;,&quot;text&quot;:&quot;SNR em Delta-Sigma&quot;,&quot;link&quot;:&quot;snr-em-delta-sigma&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Zero da NTF em DC&quot;,&quot;text&quot;:&quot;Zero da NTF em DC&quot;,&quot;link&quot;:&quot;zero-da-ntf-em-dc&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Rela\u00e7\u00e3o com Sistemas de Controle&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o com Sistemas de Controle&quot;,&quot;link&quot;:&quot;eb-table-content-89&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Idle Tones&quot;,&quot;text&quot;:&quot;Idle Tones&quot;,&quot;link&quot;:&quot;idle-tones&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Dithering&quot;,&quot;text&quot;:&quot;Dithering&quot;,&quot;link&quot;:&quot;dithering&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Estabilidade Matem\u00e1tica&quot;,&quot;text&quot;:&quot;Estabilidade Matem\u00e1tica&quot;,&quot;link&quot;:&quot;eb-table-content-92&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Rela\u00e7\u00e3o com DSP Moderno&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o com DSP Moderno&quot;,&quot;link&quot;:&quot;eb-table-content-93&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;DAC Delta-Sigma (\u03a3\u0394 DAC)&quot;,&quot;text&quot;:&quot;DAC Delta-Sigma (\u03a3\u0394 DAC)&quot;,&quot;link&quot;:&quot;eb-table-content-94&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Diferen\u00e7a entre DAC Tradicional e Sigma-Delta&quot;,&quot;text&quot;:&quot;Diferen\u00e7a entre DAC Tradicional e Sigma-Delta&quot;,&quot;link&quot;:&quot;eb-table-content-95&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Estrat\u00e9gia do DAC Sigma-Delta&quot;,&quot;text&quot;:&quot;Estrat\u00e9gia do DAC Sigma-Delta&quot;,&quot;link&quot;:&quot;eb-table-content-96&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Estrutura B\u00e1sica&quot;,&quot;text&quot;:&quot;Estrutura B\u00e1sica&quot;,&quot;link&quot;:&quot;eb-table-content-97&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;PCM e Oversampling&quot;,&quot;text&quot;:&quot;PCM e Oversampling&quot;,&quot;link&quot;:&quot;pcm-e-oversampling&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;&quot;,&quot;text&quot;:&quot;&quot;,&quot;link&quot;:&quot;eb-table-content-99&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Modulador Sigma-Delta no DAC&quot;,&quot;text&quot;:&quot;Modulador Sigma-Delta no DAC&quot;,&quot;link&quot;:&quot;modulador-sigma-delta-no-dac&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Sa\u00edda de 1 Bit&quot;,&quot;text&quot;:&quot;Sa\u00edda de 1 Bit&quot;,&quot;link&quot;:&quot;eb-table-content-101&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Filtro Anal\u00f3gico de Sa\u00edda&quot;,&quot;text&quot;:&quot;Filtro Anal\u00f3gico de Sa\u00edda&quot;,&quot;link&quot;:&quot;eb-table-content-102&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Grande Vantagem do DAC Sigma-Delta&quot;,&quot;text&quot;:&quot;Grande Vantagem do DAC Sigma-Delta&quot;,&quot;link&quot;:&quot;grande-vantagem-do-dac-sigma-delta&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Rela\u00e7\u00e3o com PWM&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o com PWM&quot;,&quot;link&quot;:&quot;eb-table-content-104&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;PWM Tradicional&quot;,&quot;text&quot;:&quot;PWM Tradicional&quot;,&quot;link&quot;:&quot;pwm-tradicional&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Sigma-Delta&quot;,&quot;text&quot;:&quot;Sigma-Delta&quot;,&quot;link&quot;:&quot;sigma-delta&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Classe D e Sigma-Delta&quot;,&quot;text&quot;:&quot;Classe D e Sigma-Delta&quot;,&quot;link&quot;:&quot;classe-d-e-sigma-delta&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;DSD (Direct Stream Digital)&quot;,&quot;text&quot;:&quot;DSD (Direct Stream Digital)&quot;,&quot;link&quot;:&quot;dsd-direct-stream-digital&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;O que \u00e9 DSD?&quot;,&quot;text&quot;:&quot;O que \u00e9 DSD?&quot;,&quot;link&quot;:&quot;eb-table-content-109&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Filosofia do DSD&quot;,&quot;text&quot;:&quot;Filosofia do DSD&quot;,&quot;link&quot;:&quot;filosofia-do-dsd&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;SACD&quot;,&quot;text&quot;:&quot;SACD&quot;,&quot;link&quot;:&quot;sacd&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Vantagens do DSD&quot;,&quot;text&quot;:&quot;Vantagens do DSD&quot;,&quot;link&quot;:&quot;vantagens-do-dsd&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Problemas do DSD&quot;,&quot;text&quot;:&quot;Problemas do DSD&quot;,&quot;link&quot;:&quot;problemas-do-dsd&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Muito ru\u00eddo ultrass\u00f4nico&quot;,&quot;text&quot;:&quot;Muito ru\u00eddo ultrass\u00f4nico&quot;,&quot;link&quot;:&quot;eb-table-content-114&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Edi\u00e7\u00e3o complexa&quot;,&quot;text&quot;:&quot;Edi\u00e7\u00e3o complexa&quot;,&quot;link&quot;:&quot;eb-table-content-115&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Estabilidade e filtragem&quot;,&quot;text&quot;:&quot;Estabilidade e filtragem&quot;,&quot;link&quot;:&quot;estabilidade-e-filtragem&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;DACs Multi-Bit Sigma-Delta&quot;,&quot;text&quot;:&quot;DACs Multi-Bit Sigma-Delta&quot;,&quot;link&quot;:&quot;dacs-multi-bit-sigma-delta&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;DEM (Dynamic Element Matching)&quot;,&quot;text&quot;:&quot;DEM (Dynamic Element Matching)&quot;,&quot;link&quot;:&quot;dem-dynamic-element-matching&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Sigma-Delta em RF&quot;,&quot;text&quot;:&quot;Sigma-Delta em RF&quot;,&quot;link&quot;:&quot;sigma-delta-em-rf&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;PLL Fractional-N Sigma-Delta&quot;,&quot;text&quot;:&quot;PLL Fractional-N Sigma-Delta&quot;,&quot;link&quot;:&quot;pll-fractional-n-sigma-delta&quot;},{&quot;level&quot;:1,&quot;content&quot;:&quot;Sigma-Delta e CMOS Moderno&quot;,&quot;text&quot;:&quot;Sigma-Delta e CMOS Moderno&quot;,&quot;link&quot;:&quot;sigma-delta-e-cmos-moderno&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;O Problema da Quantiza\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;o-problema-da-quantiza\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Superamostragem (Oversampling)&quot;,&quot;value&quot;:&quot;superamostragem-oversampling&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estrutura Interna do Conversor Delta-Sigma&quot;,&quot;value&quot;:&quot;estrutura-interna-do-conversor-delta-sigma&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Vis\u00e3o Conceitual do Modulador&quot;,&quot;value&quot;:&quot;vis\u00e3o-conceitual-do-modulador&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O Integrador&quot;,&quot;value&quot;:&quot;o-integrador&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Quantizador de 1 Bit&quot;,&quot;value&quot;:&quot;quantizador-de-1-bit&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;DAC de Realimenta\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;dac-de-realimenta\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Fluxo de Bits (Bitstream)&quot;,&quot;value&quot;:&quot;fluxo-de-bits-bitstream&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Noise Shaping&quot;,&quot;value&quot;:&quot;noise-shaping&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Filtro Digital de Decima\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;filtro-digital-de-decima\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1. Filtrar ru\u00eddo de alta frequ\u00eancia&quot;,&quot;value&quot;:&quot;1-filtrar-ru\u00eddo-de-alta-frequ\u00eancia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2. Reduzir a taxa de amostragem&quot;,&quot;value&quot;:&quot;2-reduzir-a-taxa-de-amostragem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o entre Oversampling e Resolu\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-entre-oversampling-e-resolu\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Ordens do Modulador&quot;,&quot;value&quot;:&quot;ordens-do-modulador&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Compara\u00e7\u00e3o entre Delta-Sigma, SAR, Flash e Pipeline ADC&quot;,&quot;value&quot;:&quot;compara\u00e7\u00e3o-entre-delta-sigma-sar-flash-e-pipeline-adc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;ADC Flash&quot;,&quot;value&quot;:&quot;adc-flash&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estrutura&quot;,&quot;value&quot;:&quot;estrutura&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Compara\u00e7\u00e3o com Delta-Sigma&quot;,&quot;value&quot;:&quot;compara\u00e7\u00e3o-com-delta-sigma&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;ADC SAR (Successive Approximation Register)&quot;,&quot;value&quot;:&quot;adc-sar-successive-approximation-register&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Funcionamento&quot;,&quot;value&quot;:&quot;funcionamento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Tempo de Convers\u00e3o&quot;,&quot;value&quot;:&quot;tempo-de-convers\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Caracter\u00edsticas&quot;,&quot;value&quot;:&quot;caracter\u00edsticas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Compara\u00e7\u00e3o com Delta-Sigma&quot;,&quot;value&quot;:&quot;compara\u00e7\u00e3o-com-delta-sigma&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;ADC Pipeline&quot;,&quot;value&quot;:&quot;adc-pipeline&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conceito&quot;,&quot;value&quot;:&quot;conceito&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Caracter\u00edsticas&quot;,&quot;value&quot;:&quot;caracter\u00edsticas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Compara\u00e7\u00e3o com Delta-Sigma&quot;,&quot;value&quot;:&quot;compara\u00e7\u00e3o-com-delta-sigma&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Por que o Delta-Sigma possui Alta Lat\u00eancia?&quot;,&quot;value&quot;:&quot;por-que-o-delta-sigma-possui-alta-lat\u00eancia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Aplica\u00e7\u00f5es Ideais para Delta-Sigma&quot;,&quot;value&quot;:&quot;aplica\u00e7\u00f5es-ideais-para-delta-sigma&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;\u00c1udio Digital&quot;,&quot;value&quot;:&quot;\u00e1udio-digital&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Instrumenta\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;instrumenta\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Sensores de Precis\u00e3o&quot;,&quot;value&quot;:&quot;sensores-de-precis\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Microcontroladores Modernos&quot;,&quot;value&quot;:&quot;microcontroladores-modernos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Uso em FPGAs&quot;,&quot;value&quot;:&quot;uso-em-fpgas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Moduladores Delta-Sigma de Ordens Superiores&quot;,&quot;value&quot;:&quot;moduladores-delta-sigma-de-ordens-superiores&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Noise Shaping em Diferentes Ordens&quot;,&quot;value&quot;:&quot;noise-shaping-em-diferentes-ordens&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Primeira Ordem&quot;,&quot;value&quot;:&quot;primeira-ordem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Segunda Ordem&quot;,&quot;value&quot;:&quot;segunda-ordem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Terceira Ordem&quot;,&quot;value&quot;:&quot;terceira-ordem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o entre Ordem e SNR&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-entre-ordem-e-snr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Primeira ordem&quot;,&quot;value&quot;:&quot;primeira-ordem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Segunda ordem&quot;,&quot;value&quot;:&quot;segunda-ordem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Terceira ordem&quot;,&quot;value&quot;:&quot;terceira-ordem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Problema da Estabilidade&quot;,&quot;value&quot;:&quot;problema-da-estabilidade&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Arquitetura MASH (Multi-Stage Noise Shaping)&quot;,&quot;value&quot;:&quot;arquitetura-mash-multi-stage-noise-shaping&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Quantizadores Multi-Bit&quot;,&quot;value&quot;:&quot;quantizadores-multi-bit&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Filtros de Decima\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;filtros-de-decima\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Filtros CIC&quot;,&quot;value&quot;:&quot;filtros-cic&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;ENOB (Effective Number Of Bits)&quot;,&quot;value&quot;:&quot;enob-effective-number-of-bits&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;THD e SINAD&quot;,&quot;value&quot;:&quot;thd-e-sinad&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;THD&quot;,&quot;value&quot;:&quot;thd&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;SINAD&quot;,&quot;value&quot;:&quot;sinad&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Problema do Clock Jitter&quot;,&quot;value&quot;:&quot;problema-do-clock-jitter&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;\u00c1udio Hi-Fi e Delta-Sigma&quot;,&quot;value&quot;:&quot;\u00e1udio-hi-fi-e-delta-sigma&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Limita\u00e7\u00f5es Fundamentais&quot;,&quot;value&quot;:&quot;limita\u00e7\u00f5es-fundamentais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;N\u00e3o \u00e9 ideal para sinais ultrarr\u00e1pidos&quot;,&quot;value&quot;:&quot;n\u00e3o-\u00e9-ideal-para-sinais-ultrarr\u00e1pidos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Consumo Digital&quot;,&quot;value&quot;:&quot;consumo-digital&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Instabilidade&quot;,&quot;value&quot;:&quot;instabilidade&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Clock extremamente cr\u00edtico&quot;,&quot;value&quot;:&quot;clock-extremamente-cr\u00edtico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Delta-Sigma em Microcontroladores, FPGA e Sistemas Embarcados&quot;,&quot;value&quot;:&quot;delta-sigma-em-microcontroladores-fpga-e-sistemas-embarcados&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;ADCs Delta-Sigma em Microcontroladores&quot;,&quot;value&quot;:&quot;adcs-delta-sigma-em-microcontroladores&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Por que usar Delta-Sigma em Medi\u00e7\u00e3o de Corrente?&quot;,&quot;value&quot;:&quot;por-que-usar-delta-sigma-em-medi\u00e7\u00e3o-de-corrente&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Moduladores Externos Sigma-Delta&quot;,&quot;value&quot;:&quot;moduladores-externos-sigma-delta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Isola\u00e7\u00e3o Galv\u00e2nica Simplificada&quot;,&quot;value&quot;:&quot;isola\u00e7\u00e3o-galv\u00e2nica-simplificada&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo Real: Controle de Inversores&quot;,&quot;value&quot;:&quot;exemplo-real-controle-de-inversores&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Filtros SINC&quot;,&quot;value&quot;:&quot;filtros-sinc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Delta-Sigma em FPGA&quot;,&quot;value&quot;:&quot;delta-sigma-em-fpga&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;DAC Sigma-Delta em FPGA&quot;,&quot;value&quot;:&quot;dac-sigma-delta-em-fpga&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo Conceitual em Verilog&quot;,&quot;value&quot;:&quot;exemplo-conceitual-em-verilog&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Delta-Sigma e PWM&quot;,&quot;value&quot;:&quot;delta-sigma-e-pwm&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;PWM (Pulse Width Modulation)&quot;,&quot;value&quot;:&quot;pwm-pulse-width-modulation&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;PDM (Pulse Density Modulation)&quot;,&quot;value&quot;:&quot;pdm-pulse-density-modulation&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Aplica\u00e7\u00f5es em Fontes Chaveadas&quot;,&quot;value&quot;:&quot;aplica\u00e7\u00f5es-em-fontes-chaveadas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Sensores MEMS e Sigma-Delta&quot;,&quot;value&quot;:&quot;sensores-mems-e-sigma-delta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conversores de \u00c1udio MEMS&quot;,&quot;value&quot;:&quot;conversores-de-\u00e1udio-mems&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o com DSP Moderno&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-com-dsp-moderno&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Fundamentos Matem\u00e1ticos do Noise Shaping&quot;,&quot;value&quot;:&quot;fundamentos-matem\u00e1ticos-do-noise-shaping&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Modelo Linear do Modulador&quot;,&quot;value&quot;:&quot;modelo-linear-do-modulador&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estrutura Linearizada&quot;,&quot;value&quot;:&quot;estrutura-linearizada&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Signal Transfer Function (STF)&quot;,&quot;value&quot;:&quot;signal-transfer-function-stf&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Noise Transfer Function (NTF)&quot;,&quot;value&quot;:&quot;noise-transfer-function-ntf&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Interpreta\u00e7\u00e3o F\u00edsica&quot;,&quot;value&quot;:&quot;interpreta\u00e7\u00e3o-f\u00edsica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Segunda Ordem&quot;,&quot;value&quot;:&quot;segunda-ordem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Ordem Superior&quot;,&quot;value&quot;:&quot;ordem-superior&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Ru\u00eddo de Quantiza\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;ru\u00eddo-de-quantiza\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Oversampling e Ru\u00eddo&quot;,&quot;value&quot;:&quot;oversampling-e-ru\u00eddo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o com OSR&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-com-osr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;SNR em Delta-Sigma&quot;,&quot;value&quot;:&quot;snr-em-delta-sigma&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Zero da NTF em DC&quot;,&quot;value&quot;:&quot;zero-da-ntf-em-dc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o com Sistemas de Controle&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-com-sistemas-de-controle&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Idle Tones&quot;,&quot;value&quot;:&quot;idle-tones&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Dithering&quot;,&quot;value&quot;:&quot;dithering&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estabilidade Matem\u00e1tica&quot;,&quot;value&quot;:&quot;estabilidade-matem\u00e1tica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o com DSP Moderno&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-com-dsp-moderno&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;DAC Delta-Sigma (\u03a3\u0394 DAC)&quot;,&quot;value&quot;:&quot;dac-delta-sigma-\u03c3\u03b4-dac&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Diferen\u00e7a entre DAC Tradicional e Sigma-Delta&quot;,&quot;value&quot;:&quot;diferen\u00e7a-entre-dac-tradicional-e-sigma-delta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estrat\u00e9gia do DAC Sigma-Delta&quot;,&quot;value&quot;:&quot;estrat\u00e9gia-do-dac-sigma-delta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estrutura B\u00e1sica&quot;,&quot;value&quot;:&quot;estrutura-b\u00e1sica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;PCM e Oversampling&quot;,&quot;value&quot;:&quot;pcm-e-oversampling&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;&quot;,&quot;value&quot;:&quot;&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Modulador Sigma-Delta no DAC&quot;,&quot;value&quot;:&quot;modulador-sigma-delta-no-dac&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Sa\u00edda de 1 Bit&quot;,&quot;value&quot;:&quot;sa\u00edda-de-1-bit&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Filtro Anal\u00f3gico de Sa\u00edda&quot;,&quot;value&quot;:&quot;filtro-anal\u00f3gico-de-sa\u00edda&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Grande Vantagem do DAC Sigma-Delta&quot;,&quot;value&quot;:&quot;grande-vantagem-do-dac-sigma-delta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o com PWM&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-com-pwm&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;PWM Tradicional&quot;,&quot;value&quot;:&quot;pwm-tradicional&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Sigma-Delta&quot;,&quot;value&quot;:&quot;sigma-delta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Classe D e Sigma-Delta&quot;,&quot;value&quot;:&quot;classe-d-e-sigma-delta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;DSD (Direct Stream Digital)&quot;,&quot;value&quot;:&quot;dsd-direct-stream-digital&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que \u00e9 DSD?&quot;,&quot;value&quot;:&quot;o-que-\u00e9-dsd&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Filosofia do DSD&quot;,&quot;value&quot;:&quot;filosofia-do-dsd&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;SACD&quot;,&quot;value&quot;:&quot;sacd&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Vantagens do DSD&quot;,&quot;value&quot;:&quot;vantagens-do-dsd&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Problemas do DSD&quot;,&quot;value&quot;:&quot;problemas-do-dsd&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Muito ru\u00eddo ultrass\u00f4nico&quot;,&quot;value&quot;:&quot;muito-ru\u00eddo-ultrass\u00f4nico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Edi\u00e7\u00e3o complexa&quot;,&quot;value&quot;:&quot;edi\u00e7\u00e3o-complexa&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estabilidade e filtragem&quot;,&quot;value&quot;:&quot;estabilidade-e-filtragem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;DACs Multi-Bit Sigma-Delta&quot;,&quot;value&quot;:&quot;dacs-multi-bit-sigma-delta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;DEM (Dynamic Element Matching)&quot;,&quot;value&quot;:&quot;dem-dynamic-element-matching&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Sigma-Delta em RF&quot;,&quot;value&quot;:&quot;sigma-delta-em-rf&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;PLL Fractional-N Sigma-Delta&quot;,&quot;value&quot;:&quot;pll-fractional-n-sigma-delta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Sigma-Delta e CMOS Moderno&quot;,&quot;value&quot;:&quot;sigma-delta-e-cmos-moderno&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">O Problema da Quantização</a><li><a href="#superamostragem-oversampling">Superamostragem (Oversampling)</a><li><a href="#estrutura-interna-do-conversor-delta-sigma">Estrutura Interna do Conversor Delta-Sigma</a><ul class="eb-toc__list"><li><a href="#eb-table-content-3">Visão Conceitual do Modulador</a><li><a href="#o-integrador">O Integrador</a><li><a href="#quantizador-de-1-bit">Quantizador de 1 Bit</a><li><a href="#eb-table-content-6">DAC de Realimentação</a><li><a href="#fluxo-de-bits-bitstream">Fluxo de Bits (Bitstream)</a><li><a href="#noise-shaping">Noise Shaping</a><li><a href="#eb-table-content-9">Filtro Digital de Decimação</a><ul class="eb-toc__list"><li><a href="#eb-table-content-10">1. Filtrar ruído de alta frequência</a><li><a href="#2-reduzir-a-taxa-de-amostragem">2. Reduzir a taxa de amostragem</a></li></ul><li><a href="#eb-table-content-12">Relação entre Oversampling e Resolução</a><li><a href="#ordens-do-modulador">Ordens do Modulador</a></li></ul><li><a href="#eb-table-content-14">Comparação entre Delta-Sigma, SAR, Flash e Pipeline ADC</a><li><a href="#adc-flash">ADC Flash</a><ul class="eb-toc__list"><li><a href="#estrutura">Estrutura</a><li><a href="#eb-table-content-17">Comparação com Delta-Sigma</a></li></ul><li><a href="#adc-sar-successive-approximation-register">ADC SAR (Successive Approximation Register)</a><ul class="eb-toc__list"><li><a href="#funcionamento">Funcionamento</a><li><a href="#eb-table-content-20">Tempo de Conversão</a><li><a href="#eb-table-content-21">Características</a><li><a href="#eb-table-content-22">Comparação com Delta-Sigma</a></li></ul><li><a href="#adc-pipeline">ADC Pipeline</a><ul class="eb-toc__list"><li><a href="#conceito">Conceito</a><li><a href="#eb-table-content-25">Características</a><li><a href="#eb-table-content-26">Comparação com Delta-Sigma</a></li></ul><li><a href="#eb-table-content-27">Por que o Delta-Sigma possui Alta Latência?</a><li><a href="#eb-table-content-28">Aplicações Ideais para Delta-Sigma</a><ul class="eb-toc__list"><li><a href="#eb-table-content-29">Áudio Digital</a></li></ul><li><a href="#eb-table-content-30">Instrumentação</a><li><a href="#eb-table-content-31">Sensores de Precisão</a><li><a href="#microcontroladores-modernos">Microcontroladores Modernos</a><li><a href="#uso-em-fpgas">Uso em FPGAs</a><li><a href="#moduladores-delta-sigma-de-ordens-superiores">Moduladores Delta-Sigma de Ordens Superiores</a><li><a href="#noise-shaping-em-diferentes-ordens">Noise Shaping em Diferentes Ordens</a><ul class="eb-toc__list"><li><a href="#primeira-ordem">Primeira Ordem</a><li><a href="#segunda-ordem">Segunda Ordem</a><li><a href="#terceira-ordem">Terceira Ordem</a></li></ul><li><a href="#eb-table-content-39">Relação entre Ordem e SNR</a><ul class="eb-toc__list"><li><a href="#primeira-ordem">Primeira ordem</a><li><a href="#segunda-ordem">Segunda ordem</a><li><a href="#terceira-ordem">Terceira ordem</a></li></ul><li><a href="#problema-da-estabilidade">Problema da Estabilidade</a><li><a href="#arquitetura-mash-multi-stage-noise-shaping">Arquitetura MASH (Multi-Stage Noise Shaping)</a><li><a href="#quantizadores-multi-bit">Quantizadores Multi-Bit</a><li><a href="#eb-table-content-46">Filtros de Decimação</a><li><a href="#filtros-cic">Filtros CIC</a><li><a href="#enob-effective-number-of-bits">ENOB (Effective Number Of Bits)</a><li><a href="#thd-e-sinad">THD e SINAD</a><ul class="eb-toc__list"><li><a href="#thd">THD</a><li><a href="#sinad">SINAD</a></li></ul><li><a href="#problema-do-clock-jitter">Problema do Clock Jitter</a><li><a href="#eb-table-content-53">Áudio Hi-Fi e Delta-Sigma</a><li><a href="#eb-table-content-54">Limitações Fundamentais</a><ul class="eb-toc__list"><li><a href="#eb-table-content-55">Não é ideal para sinais ultrarrápidos</a><li><a href="#consumo-digital">Consumo Digital</a><li><a href="#instabilidade">Instabilidade</a><li><a href="#eb-table-content-58">Clock extremamente crítico</a></li></ul><li><a href="#delta-sigma-em-microcontroladores-fpga-e-sistemas-embarcados">Delta-Sigma em Microcontroladores, FPGA e Sistemas Embarcados</a><li><a href="#adcs-delta-sigma-em-microcontroladores">ADCs Delta-Sigma em Microcontroladores</a><li><a href="#eb-table-content-61">Por que usar Delta-Sigma em Medição de Corrente?</a><li><a href="#moduladores-externos-sigma-delta">Moduladores Externos Sigma-Delta</a><li><a href="#eb-table-content-63">Isolação Galvânica Simplificada</a><li><a href="#exemplo-real-controle-de-inversores">Exemplo Real: Controle de Inversores</a><li><a href="#filtros-sinc">Filtros SINC</a><li><a href="#delta-sigma-em-fpga">Delta-Sigma em FPGA</a><li><a href="#dac-sigma-delta-em-fpga">DAC Sigma-Delta em FPGA</a><li><a href="#exemplo-conceitual-em-verilog">Exemplo Conceitual em Verilog</a><li><a href="#delta-sigma-e-pwm">Delta-Sigma e PWM</a><li><a href="#pwm-pulse-width-modulation">PWM (Pulse Width Modulation)</a><li><a href="#pdm-pulse-density-modulation">PDM (Pulse Density Modulation)</a><li><a href="#eb-table-content-72">Aplicações em Fontes Chaveadas</a><li><a href="#sensores-mems-e-sigma-delta">Sensores MEMS e Sigma-Delta</a><li><a href="#eb-table-content-74">Conversores de Áudio MEMS</a><li><a href="#eb-table-content-75">Relação com DSP Moderno</a><li><a href="#eb-table-content-76">Fundamentos Matemáticos do Noise Shaping</a><li><a href="#modelo-linear-do-modulador">Modelo Linear do Modulador</a><li><a href="#estrutura-linearizada">Estrutura Linearizada</a><li><a href="#signal-transfer-function-stf">Signal Transfer Function (STF)</a><li><a href="#noise-transfer-function-ntf">Noise Transfer Function (NTF)</a><li><a href="#eb-table-content-81">Interpretação Física</a><li><a href="#segunda-ordem">Segunda Ordem</a><li><a href="#ordem-superior">Ordem Superior</a><li><a href="#eb-table-content-84">Ruído de Quantização</a><li><a href="#eb-table-content-85">Oversampling e Ruído</a><li><a href="#eb-table-content-86">Relação com OSR</a><li><a href="#snr-em-delta-sigma">SNR em Delta-Sigma</a><li><a href="#zero-da-ntf-em-dc">Zero da NTF em DC</a><li><a href="#eb-table-content-89">Relação com Sistemas de Controle</a><li><a href="#idle-tones">Idle Tones</a><li><a href="#dithering">Dithering</a><li><a href="#eb-table-content-92">Estabilidade Matemática</a><li><a href="#eb-table-content-93">Relação com DSP Moderno</a><li><a href="#eb-table-content-94">DAC Delta-Sigma (ΣΔ DAC)</a><li><a href="#eb-table-content-95">Diferença entre DAC Tradicional e Sigma-Delta</a><li><a href="#eb-table-content-96">Estratégia do DAC Sigma-Delta</a><li><a href="#eb-table-content-97">Estrutura Básica</a><li><a href="#pcm-e-oversampling">PCM e Oversampling</a><li><a href="#eb-table-content-99"></a><li><a href="#modulador-sigma-delta-no-dac">Modulador Sigma-Delta no DAC</a><li><a href="#eb-table-content-101">Saída de 1 Bit</a><li><a href="#eb-table-content-102">Filtro Analógico de Saída</a><li><a href="#grande-vantagem-do-dac-sigma-delta">Grande Vantagem do DAC Sigma-Delta</a><li><a href="#eb-table-content-104">Relação com PWM</a><li><a href="#pwm-tradicional">PWM Tradicional</a><li><a href="#sigma-delta">Sigma-Delta</a><li><a href="#classe-d-e-sigma-delta">Classe D e Sigma-Delta</a><li><a href="#dsd-direct-stream-digital">DSD (Direct Stream Digital)</a><li><a href="#eb-table-content-109">O que é DSD?</a><li><a href="#filosofia-do-dsd">Filosofia do DSD</a><li><a href="#sacd">SACD</a><li><a href="#vantagens-do-dsd">Vantagens do DSD</a><li><a href="#problemas-do-dsd">Problemas do DSD</a><ul class="eb-toc__list"><li><a href="#eb-table-content-114">Muito ruído ultrassônico</a><li><a href="#eb-table-content-115">Edição complexa</a><li><a href="#estabilidade-e-filtragem">Estabilidade e filtragem</a></li></ul><li><a href="#dacs-multi-bit-sigma-delta">DACs Multi-Bit Sigma-Delta</a><li><a href="#dem-dynamic-element-matching">DEM (Dynamic Element Matching)</a><li><a href="#sigma-delta-em-rf">Sigma-Delta em RF</a><li><a href="#pll-fractional-n-sigma-delta">PLL Fractional-N Sigma-Delta</a><li><a href="#sigma-delta-e-cmos-moderno">Sigma-Delta e CMOS Moderno</a></ul></div></div></div></div></div>


<p class="wp-block-paragraph">Os conversores analógico-digitais do tipo Delta-Sigma, também chamados de Sigma-Delta (ΣΔ), representam uma das arquiteturas de conversão mais importantes da eletrônica moderna, especialmente em aplicações que exigem alta resolução, excelente imunidade a ruído e grande precisão. Eles são amplamente utilizados em instrumentos de medição, sistemas de áudio digital, sensores industriais, balanças eletrônicas, sistemas biomédicos, aquisição de sinais lentos e equipamentos científicos.</p>



<p class="wp-block-paragraph">Diferentemente de arquiteturas clássicas como Flash ADC, SAR (Successive Approximation Register) ou Pipeline ADC, o conversor Delta-Sigma não tenta converter instantaneamente o valor analógico em um número digital final. Em vez disso, ele utiliza uma estratégia baseada em superamostragem (oversampling), modelagem espectral de ruído (noise shaping) e filtragem digital para reconstruir o sinal com elevada precisão.</p>



<p class="wp-block-paragraph">O surgimento dessa arquitetura está diretamente ligado às limitações físicas dos conversores tradicionais. Em sistemas de alta resolução, aumentar a precisão usando apenas comparadores extremamente precisos torna-se caro, complexo e energeticamente ineficiente. O Delta-Sigma contorna esse problema utilizando princípios matemáticos e temporais para deslocar o ruído de quantização para frequências mais altas, permitindo removê-lo posteriormente através de filtros digitais.</p>



<p class="wp-block-paragraph">Uma das razões do enorme sucesso dos ADCs Delta-Sigma é que eles combinam:</p>



<ul class="wp-block-list">
<li>Alta resolução (16, 24 e até 32 bits efetivos em aplicações específicas)</li>



<li>Excelente linearidade</li>



<li>Forte rejeição a ruídos</li>



<li>Baixo custo relativo em CMOS moderno</li>



<li>Grande integração digital</li>
</ul>



<p class="wp-block-paragraph">Isso explica por que praticamente todo codec de áudio moderno, muitos sensores MEMS e diversos instrumentos industriais utilizam essa arquitetura.</p>



<p class="wp-block-paragraph">Além disso, a evolução dos microcontroladores e FPGAs tornou o estudo dos conversores Delta-Sigma ainda mais relevante. Muitos microcontroladores modernos já possuem ADCs Sigma-Delta integrados, enquanto FPGAs frequentemente implementam moduladores Delta-Sigma em aplicações de aquisição de sinais, áudio e controle de potência.</p>



<p class="wp-block-paragraph">Antes de entender profundamente o funcionamento interno do conversor Delta-Sigma, é importante compreender um conceito fundamental: o processo de amostragem e o problema do ruído de quantização.</p>



<h2 class="wp-block-heading">O Problema da Quantização</h2>



<p class="wp-block-paragraph">Todo conversor analógico-digital precisa transformar uma grandeza contínua em um conjunto discreto de valores binários. Esse processo inevitavelmente introduz um erro chamado erro de quantização.</p>



<p class="wp-block-paragraph">Imagine um sinal analógico variando continuamente entre 0V e 3,3V. Um ADC de baixa resolução possui poucos níveis possíveis para representar esse sinal. Assim, o valor real do sinal precisa ser arredondado para o nível digital mais próximo.</p>



<p class="wp-block-paragraph">Por exemplo, um ADC de 3 bits possui apenas:</p>



<p class="wp-block-paragraph">2^3 = 8</p>



<p class="wp-block-paragraph">níveis possíveis de quantização.</p>



<p class="wp-block-paragraph">Se o intervalo for de 0V até 3,3V, então cada degrau representará aproximadamente:</p>



<p class="wp-block-paragraph">\[\frac{3.3V}{8} \approx 0.4125V\]



<p class="wp-block-paragraph">Isso significa que pequenas variações menores que aproximadamente 412 mV simplesmente desaparecem na conversão.</p>



<p class="wp-block-paragraph">O erro introduzido pela diferença entre o valor analógico real e o valor digital representado é chamado ruído de quantização.</p>



<p class="wp-block-paragraph">Em arquiteturas tradicionais, esse ruído está distribuído aproximadamente de forma uniforme ao longo do espectro de frequência. O grande diferencial do Delta-Sigma é justamente modificar essa distribuição espectral do ruído, empurrando-o para regiões de frequência onde ele pode ser removido digitalmente.</p>



<p class="wp-block-paragraph">Em outras palavras:</p>



<ul class="wp-block-list">
<li>O ruído não desaparece</li>



<li>O conversor reorganiza onde ele aparece no espectro</li>
</ul>



<p class="wp-block-paragraph">Esse conceito é chamado de Noise Shaping (Modelagem de Ruído), sendo um dos pilares matemáticos do conversor Delta-Sigma.</p>



<h2 class="wp-block-heading">Superamostragem (Oversampling)</h2>



<p class="wp-block-paragraph">Outro conceito essencial no Delta-Sigma é a superamostragem.</p>



<p class="wp-block-paragraph">Um ADC convencional normalmente amostra próximo da frequência mínima necessária definida pelo Teorema de Nyquist:</p>



<p class="wp-block-paragraph">f_s \geq 2f_{max}</p>



<p class="wp-block-paragraph">Já o Delta-Sigma trabalha com frequências de amostragem extremamente maiores que a banda útil do sinal.</p>



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



<ul class="wp-block-list">
<li>Áudio de 20 kHz</li>



<li>ADC operando em vários MHz</li>
</ul>



<p class="wp-block-paragraph">Essa superamostragem traz duas vantagens fundamentais:</p>



<ol class="wp-block-list">
<li>O ruído de quantização é espalhado em uma faixa espectral muito maior</li>



<li>O filtro digital posterior consegue remover boa parte desse ruído</li>
</ol>



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



<ul class="wp-block-list">
<li>Oversampling</li>



<li>Noise shaping</li>



<li>Filtragem digital</li>
</ul>



<p class="wp-block-paragraph">o conversor Delta-Sigma consegue atingir resoluções extremamente elevadas usando hardware analógico relativamente simples.</p>



<p class="wp-block-paragraph">Na próxima seção veremos a estrutura interna do modulador Delta-Sigma, incluindo:</p>



<ul class="wp-block-list">
<li>Integrador</li>



<li>Comparador</li>



<li>Realimentação (feedback)</li>



<li>DAC interno</li>



<li>Fluxo de bits do modulador</li>



<li>Funcionamento temporal do laço Sigma-Delta</li>



<li>Papel do filtro digital de decimação</li>
</ul>



<p class="wp-block-paragraph">Além disso, começaremos a comparar formalmente essa arquitetura com ADCs SAR, Flash e Pipeline.</p><p>The post <a href="https://mcu.tec.br/algoritimos/dsp/conversor-analogico-delta-sigma-%ce%b4%cf%83-adc/">Conversor Analógico Delta-Sigma (ΔΣ ADC)</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1430</post-id>	</item>
		<item>
		<title>Filtros Estatísticos em Sistemas Embarcados: EMA, Wiener e Kalman Aplicados ao RP2040</title>
		<link>https://mcu.tec.br/algoritimos/dsp/filtros-estatisticos-em-sistemas-embarcados-ema-wiener-e-kalman-aplicados-ao-rp2040/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=filtros-estatisticos-em-sistemas-embarcados-ema-wiener-e-kalman-aplicados-ao-rp2040</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Thu, 26 Feb 2026 09:24:35 +0000</pubDate>
				<category><![CDATA[DSP]]></category>
		<category><![CDATA[conectando os filtros a decisões confiáveis em sistemas de DSP embarcado]]></category>
		<category><![CDATA[destacando suas diferenças conceituais]]></category>
		<category><![CDATA[Este artigo apresenta uma abordagem didática e aprofundada sobre o uso de filtros estatísticos em sistemas embarcados]]></category>
		<category><![CDATA[explorando a média móvel exponencial (EMA)]]></category>
		<category><![CDATA[limitações e aplicações reais em microcontroladores como o RP2040. Com exemplos incrementais em linguagem C]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1137</guid>

					<description><![CDATA[<p>Este artigo apresenta uma abordagem didática e aprofundada sobre o uso de filtros estatísticos em sistemas embarcados, explorando a média móvel exponencial (EMA), o filtro de Wiener e o filtro de Kalman sob a perspectiva prática de engenharia. O texto explica como cada filtro atua na suavização, separação sinal-ruído e estimação de estados, destacando suas diferenças conceituais, limitações e aplicações reais em microcontroladores como o RP2040. Com exemplos incrementais em linguagem C, o artigo demonstra implementações eficientes e viáveis para firmware bare-metal, conectando os filtros a decisões confiáveis em sistemas de DSP embarcado, sensores e controle. Ideal para engenheiros e estudantes que desejam compreender quando e como aplicar cada filtro em projetos reais.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/dsp/filtros-estatisticos-em-sistemas-embarcados-ema-wiener-e-kalman-aplicados-ao-rp2040/">Filtros Estatísticos em Sistemas Embarcados: EMA, Wiener e Kalman Aplicados ao RP2040</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-mhzll wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-mhzll "><div class="eb-toc-container eb-toc-mhzll  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;:3,&quot;content&quot;:&quot;M\u00e9dia M\u00f3vel Exponencial, Wiener e Kalman aplicados ao RP2040&quot;,&quot;text&quot;:&quot;M\u00e9dia M\u00f3vel Exponencial, Wiener e Kalman aplicados ao RP2040&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1. Introdu\u00e7\u00e3o \u2014 Por que filtros s\u00e3o decisores disfar\u00e7ados&quot;,&quot;text&quot;:&quot;1. Introdu\u00e7\u00e3o \u2014 Por que filtros s\u00e3o decisores disfar\u00e7ados&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.1 O papel dos filtros na arquitetura embarcada moderna&quot;,&quot;text&quot;:&quot;1.1 O papel dos filtros na arquitetura embarcada moderna&quot;,&quot;link&quot;:&quot;11-o-papel-dos-filtros-na-arquitetura-embarcada-moderna&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.2 Ordem crescente de complexidade (e poder)&quot;,&quot;text&quot;:&quot;1.2 Ordem crescente de complexidade (e poder)&quot;,&quot;link&quot;:&quot;12-ordem-crescente-de-complexidade-e-poder&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.3 Come\u00e7ando pelo mais importante: M\u00e9dia M\u00f3vel Exponencial (EMA)&quot;,&quot;text&quot;:&quot;1.3 Come\u00e7ando pelo mais importante: M\u00e9dia M\u00f3vel Exponencial (EMA)&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.4 Conceito intuitivo da EMA&quot;,&quot;text&quot;:&quot;1.4 Conceito intuitivo da EMA&quot;,&quot;link&quot;:&quot;14-conceito-intuitivo-da-ema&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.5 EMA como filtro passa-baixa de primeira ordem&quot;,&quot;text&quot;:&quot;1.5 EMA como filtro passa-baixa de primeira ordem&quot;,&quot;link&quot;:&quot;15-ema-como-filtro-passa-baixa-de-primeira-ordem&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.6 Implementa\u00e7\u00e3o incremental em C (base do artigo)&quot;,&quot;text&quot;:&quot;1.6 Implementa\u00e7\u00e3o incremental em C (base do artigo)&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.7 Escolhendo o valor de \u03b1 (engenharia, n\u00e3o tentativa)&quot;,&quot;text&quot;:&quot;1.7 Escolhendo o valor de \u03b1 (engenharia, n\u00e3o tentativa)&quot;,&quot;link&quot;:&quot;eb-table-content-8&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.8 Onde a EMA falha (e por qu\u00ea)&quot;,&quot;text&quot;:&quot;1.8 Onde a EMA falha (e por qu\u00ea)&quot;,&quot;link&quot;:&quot;eb-table-content-9&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;2 \u2014 Filtro de Wiener: minimiza\u00e7\u00e3o do erro m\u00e9dio e separa\u00e7\u00e3o sinal-ru\u00eddo&quot;,&quot;text&quot;:&quot;2 \u2014 Filtro de Wiener: minimiza\u00e7\u00e3o do erro m\u00e9dio e separa\u00e7\u00e3o sinal-ru\u00eddo&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.1 A ideia central do Wiener (sem f\u00f3rmulas intimidadoras)&quot;,&quot;text&quot;:&quot;2.1 A ideia central do Wiener (sem f\u00f3rmulas intimidadoras)&quot;,&quot;link&quot;:&quot;eb-table-content-11&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.2 Modelo estat\u00edstico assumido&quot;,&quot;text&quot;:&quot;2.2 Modelo estat\u00edstico assumido&quot;,&quot;link&quot;:&quot;eb-table-content-12&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.3 Wiener no dom\u00ednio da frequ\u00eancia (vis\u00e3o conceitual)&quot;,&quot;text&quot;:&quot;2.3 Wiener no dom\u00ednio da frequ\u00eancia (vis\u00e3o conceitual)&quot;,&quot;link&quot;:&quot;eb-table-content-13&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.4 Por que isso \u00e9 poderoso em sistemas embarcados?&quot;,&quot;text&quot;:&quot;2.4 Por que isso \u00e9 poderoso em sistemas embarcados?&quot;,&quot;link&quot;:&quot;eb-table-content-14&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.5 Wiener simplificado para MCU (forma escalar)&quot;,&quot;text&quot;:&quot;2.5 Wiener simplificado para MCU (forma escalar)&quot;,&quot;link&quot;:&quot;25-wiener-simplificado-para-mcu-forma-escalar&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.6 Implementa\u00e7\u00e3o incremental em C (forma pr\u00e1tica)&quot;,&quot;text&quot;:&quot;2.6 Implementa\u00e7\u00e3o incremental em C (forma pr\u00e1tica)&quot;,&quot;link&quot;:&quot;eb-table-content-16&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.7 Estimando vari\u00e2ncias em tempo real&quot;,&quot;text&quot;:&quot;2.7 Estimando vari\u00e2ncias em tempo real&quot;,&quot;link&quot;:&quot;eb-table-content-17&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.8 Onde o Wiener falha (e quando n\u00e3o usar)&quot;,&quot;text&quot;:&quot;2.8 Onde o Wiener falha (e quando n\u00e3o usar)&quot;,&quot;link&quot;:&quot;eb-table-content-18&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.9 EMA vs. Wiener (compara\u00e7\u00e3o direta)&quot;,&quot;text&quot;:&quot;2.9 EMA vs. Wiener (compara\u00e7\u00e3o direta)&quot;,&quot;link&quot;:&quot;eb-table-content-19&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;3 \u2014 Filtro de Kalman: estima\u00e7\u00e3o de estados, incerteza e predi\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;3 \u2014 Filtro de Kalman: estima\u00e7\u00e3o de estados, incerteza e predi\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-20&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.1 Intui\u00e7\u00e3o antes da matem\u00e1tica&quot;,&quot;text&quot;:&quot;3.1 Intui\u00e7\u00e3o antes da matem\u00e1tica&quot;,&quot;link&quot;:&quot;eb-table-content-21&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.2 Modelo de estado (caso 1D)&quot;,&quot;text&quot;:&quot;3.2 Modelo de estado (caso 1D)&quot;,&quot;link&quot;:&quot;32-modelo-de-estado-caso-1d&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.3 Ciclo do Kalman: previs\u00e3o e corre\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;3.3 Ciclo do Kalman: previs\u00e3o e corre\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-23&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;1\ufe0f\u20e3 Previs\u00e3o&quot;,&quot;text&quot;:&quot;1\ufe0f\u20e3 Previs\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-24&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;2\ufe0f\u20e3 Corre\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;2\ufe0f\u20e3 Corre\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-25&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.4 Compara\u00e7\u00e3o conceitual com EMA e Wiener&quot;,&quot;text&quot;:&quot;3.4 Compara\u00e7\u00e3o conceitual com EMA e Wiener&quot;,&quot;link&quot;:&quot;eb-table-content-26&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.5 Implementa\u00e7\u00e3o Kalman 1D em C (vi\u00e1vel em MCU)&quot;,&quot;text&quot;:&quot;3.5 Implementa\u00e7\u00e3o Kalman 1D em C (vi\u00e1vel em MCU)&quot;,&quot;link&quot;:&quot;eb-table-content-27&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.6 Escolhendo Q e R (engenharia pr\u00e1tica)&quot;,&quot;text&quot;:&quot;3.6 Escolhendo Q e R (engenharia pr\u00e1tica)&quot;,&quot;link&quot;:&quot;eb-table-content-28&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.7 Quando Kalman \u00e9 a escolha certa&quot;,&quot;text&quot;:&quot;3.7 Quando Kalman \u00e9 a escolha certa&quot;,&quot;link&quot;:&quot;eb-table-content-29&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.8 Onde Kalman n\u00e3o compensa&quot;,&quot;text&quot;:&quot;3.8 Onde Kalman n\u00e3o compensa&quot;,&quot;link&quot;:&quot;eb-table-content-30&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot; 4 \u2014 Compara\u00e7\u00e3o pr\u00e1tica entre EMA, Wiener e Kalman, diretrizes de escolha, encerramento e SEO&quot;,&quot;text&quot;:&quot; 4 \u2014 Compara\u00e7\u00e3o pr\u00e1tica entre EMA, Wiener e Kalman, diretrizes de escolha, encerramento e SEO&quot;,&quot;link&quot;:&quot;eb-table-content-31&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.1 O que realmente diferencia esses filtros (al\u00e9m da matem\u00e1tica)&quot;,&quot;text&quot;:&quot;4.1 O que realmente diferencia esses filtros (al\u00e9m da matem\u00e1tica)&quot;,&quot;link&quot;:&quot;eb-table-content-32&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.2 Compara\u00e7\u00e3o direta: quando cada filtro vence&quot;,&quot;text&quot;:&quot;4.2 Compara\u00e7\u00e3o direta: quando cada filtro vence&quot;,&quot;link&quot;:&quot;eb-table-content-33&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.3 Diretrizes pr\u00e1ticas de escolha (engenharia de campo)&quot;,&quot;text&quot;:&quot;4.3 Diretrizes pr\u00e1ticas de escolha (engenharia de campo)&quot;,&quot;link&quot;:&quot;eb-table-content-34&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.4 Conex\u00e3o direta com os artigos anteriores da s\u00e9rie&quot;,&quot;text&quot;:&quot;4.4 Conex\u00e3o direta com os artigos anteriores da s\u00e9rie&quot;,&quot;link&quot;:&quot;eb-table-content-35&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.5 Um erro comum: tratar filtros como \u201cp\u00f3s-processamento\u201d&quot;,&quot;text&quot;:&quot;4.5 Um erro comum: tratar filtros como \u201cp\u00f3s-processamento\u201d&quot;,&quot;link&quot;:&quot;eb-table-content-36&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.6 Encerramento conceitual&quot;,&quot;text&quot;:&quot;4.6 Encerramento conceitual&quot;,&quot;link&quot;:&quot;46-encerramento-conceitual&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;M\u00e9dia M\u00f3vel Exponencial, Wiener e Kalman aplicados ao RP2040&quot;,&quot;value&quot;:&quot;m\u00e9dia-m\u00f3vel-exponencial-wiener-e-kalman-aplicados-ao-rp2040&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1. Introdu\u00e7\u00e3o \u2014 Por que filtros s\u00e3o decisores disfar\u00e7ados&quot;,&quot;value&quot;:&quot;1-introdu\u00e7\u00e3o-por-que-filtros-s\u00e3o-decisores-disfar\u00e7ados&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.1 O papel dos filtros na arquitetura embarcada moderna&quot;,&quot;value&quot;:&quot;11-o-papel-dos-filtros-na-arquitetura-embarcada-moderna&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.2 Ordem crescente de complexidade (e poder)&quot;,&quot;value&quot;:&quot;12-ordem-crescente-de-complexidade-e-poder&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.3 Come\u00e7ando pelo mais importante: M\u00e9dia M\u00f3vel Exponencial (EMA)&quot;,&quot;value&quot;:&quot;13-come\u00e7ando-pelo-mais-importante-m\u00e9dia-m\u00f3vel-exponencial-ema&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.4 Conceito intuitivo da EMA&quot;,&quot;value&quot;:&quot;14-conceito-intuitivo-da-ema&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.5 EMA como filtro passa-baixa de primeira ordem&quot;,&quot;value&quot;:&quot;15-ema-como-filtro-passa-baixa-de-primeira-ordem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.6 Implementa\u00e7\u00e3o incremental em C (base do artigo)&quot;,&quot;value&quot;:&quot;16-implementa\u00e7\u00e3o-incremental-em-c-base-do-artigo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.7 Escolhendo o valor de \u03b1 (engenharia, n\u00e3o tentativa)&quot;,&quot;value&quot;:&quot;17-escolhendo-o-valor-de-\u03b1-engenharia-n\u00e3o-tentativa&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.8 Onde a EMA falha (e por qu\u00ea)&quot;,&quot;value&quot;:&quot;18-onde-a-ema-falha-e-por-qu\u00ea&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2 \u2014 Filtro de Wiener: minimiza\u00e7\u00e3o do erro m\u00e9dio e separa\u00e7\u00e3o sinal-ru\u00eddo&quot;,&quot;value&quot;:&quot;2-filtro-de-wiener-minimiza\u00e7\u00e3o-do-erro-m\u00e9dio-e-separa\u00e7\u00e3o-sinal-ru\u00eddo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.1 A ideia central do Wiener (sem f\u00f3rmulas intimidadoras)&quot;,&quot;value&quot;:&quot;21-a-ideia-central-do-wiener-sem-f\u00f3rmulas-intimidadoras&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.2 Modelo estat\u00edstico assumido&quot;,&quot;value&quot;:&quot;22-modelo-estat\u00edstico-assumido&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.3 Wiener no dom\u00ednio da frequ\u00eancia (vis\u00e3o conceitual)&quot;,&quot;value&quot;:&quot;23-wiener-no-dom\u00ednio-da-frequ\u00eancia-vis\u00e3o-conceitual&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.4 Por que isso \u00e9 poderoso em sistemas embarcados?&quot;,&quot;value&quot;:&quot;24-por-que-isso-\u00e9-poderoso-em-sistemas-embarcados&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.5 Wiener simplificado para MCU (forma escalar)&quot;,&quot;value&quot;:&quot;25-wiener-simplificado-para-mcu-forma-escalar&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.6 Implementa\u00e7\u00e3o incremental em C (forma pr\u00e1tica)&quot;,&quot;value&quot;:&quot;26-implementa\u00e7\u00e3o-incremental-em-c-forma-pr\u00e1tica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.7 Estimando vari\u00e2ncias em tempo real&quot;,&quot;value&quot;:&quot;27-estimando-vari\u00e2ncias-em-tempo-real&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.8 Onde o Wiener falha (e quando n\u00e3o usar)&quot;,&quot;value&quot;:&quot;28-onde-o-wiener-falha-e-quando-n\u00e3o-usar&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.9 EMA vs. Wiener (compara\u00e7\u00e3o direta)&quot;,&quot;value&quot;:&quot;29-ema-vs-wiener-compara\u00e7\u00e3o-direta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3 \u2014 Filtro de Kalman: estima\u00e7\u00e3o de estados, incerteza e predi\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;3-filtro-de-kalman-estima\u00e7\u00e3o-de-estados-incerteza-e-predi\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.1 Intui\u00e7\u00e3o antes da matem\u00e1tica&quot;,&quot;value&quot;:&quot;31-intui\u00e7\u00e3o-antes-da-matem\u00e1tica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.2 Modelo de estado (caso 1D)&quot;,&quot;value&quot;:&quot;32-modelo-de-estado-caso-1d&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.3 Ciclo do Kalman: previs\u00e3o e corre\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;33-ciclo-do-kalman-previs\u00e3o-e-corre\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1\ufe0f\u20e3 Previs\u00e3o&quot;,&quot;value&quot;:&quot;1\ufe0f\u20e3-previs\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2\ufe0f\u20e3 Corre\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;2\ufe0f\u20e3-corre\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.4 Compara\u00e7\u00e3o conceitual com EMA e Wiener&quot;,&quot;value&quot;:&quot;34-compara\u00e7\u00e3o-conceitual-com-ema-e-wiener&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.5 Implementa\u00e7\u00e3o Kalman 1D em C (vi\u00e1vel em MCU)&quot;,&quot;value&quot;:&quot;35-implementa\u00e7\u00e3o-kalman-1d-em-c-vi\u00e1vel-em-mcu&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.6 Escolhendo Q e R (engenharia pr\u00e1tica)&quot;,&quot;value&quot;:&quot;36-escolhendo-q-e-r-engenharia-pr\u00e1tica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.7 Quando Kalman \u00e9 a escolha certa&quot;,&quot;value&quot;:&quot;37-quando-kalman-\u00e9-a-escolha-certa&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.8 Onde Kalman n\u00e3o compensa&quot;,&quot;value&quot;:&quot;38-onde-kalman-n\u00e3o-compensa&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot; 4 \u2014 Compara\u00e7\u00e3o pr\u00e1tica entre EMA, Wiener e Kalman, diretrizes de escolha, encerramento e SEO&quot;,&quot;value&quot;:&quot;4-compara\u00e7\u00e3o-pr\u00e1tica-entre-ema-wiener-e-kalman-diretrizes-de-escolha-encerramento-e-seo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.1 O que realmente diferencia esses filtros (al\u00e9m da matem\u00e1tica)&quot;,&quot;value&quot;:&quot;41-o-que-realmente-diferencia-esses-filtros-al\u00e9m-da-matem\u00e1tica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.2 Compara\u00e7\u00e3o direta: quando cada filtro vence&quot;,&quot;value&quot;:&quot;42-compara\u00e7\u00e3o-direta-quando-cada-filtro-vence&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.3 Diretrizes pr\u00e1ticas de escolha (engenharia de campo)&quot;,&quot;value&quot;:&quot;43-diretrizes-pr\u00e1ticas-de-escolha-engenharia-de-campo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.4 Conex\u00e3o direta com os artigos anteriores da s\u00e9rie&quot;,&quot;value&quot;:&quot;44-conex\u00e3o-direta-com-os-artigos-anteriores-da-s\u00e9rie&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.5 Um erro comum: tratar filtros como \u201cp\u00f3s-processamento\u201d&quot;,&quot;value&quot;:&quot;45-um-erro-comum-tratar-filtros-como-p\u00f3s-processamento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.6 Encerramento conceitual&quot;,&quot;value&quot;:&quot;46-encerramento-conceitual&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">Média Móvel Exponencial, Wiener e Kalman aplicados ao RP2040</a><li><a href="#eb-table-content-1">1. Introdução — Por que filtros são decisores disfarçados</a><li><a href="#11-o-papel-dos-filtros-na-arquitetura-embarcada-moderna">1.1 O papel dos filtros na arquitetura embarcada moderna</a><li><a href="#12-ordem-crescente-de-complexidade-e-poder">1.2 Ordem crescente de complexidade (e poder)</a><li><a href="#eb-table-content-4">1.3 Começando pelo mais importante: Média Móvel Exponencial (EMA)</a><li><a href="#14-conceito-intuitivo-da-ema">1.4 Conceito intuitivo da EMA</a><li><a href="#15-ema-como-filtro-passa-baixa-de-primeira-ordem">1.5 EMA como filtro passa-baixa de primeira ordem</a><li><a href="#eb-table-content-7">1.6 Implementação incremental em C (base do artigo)</a><li><a href="#eb-table-content-8">1.7 Escolhendo o valor de α (engenharia, não tentativa)</a><li><a href="#eb-table-content-9">1.8 Onde a EMA falha (e por quê)</a><li><a href="#eb-table-content-10">2 — Filtro de Wiener: minimização do erro médio e separação sinal-ruído</a><ul class="eb-toc__list"><li><a href="#eb-table-content-11">2.1 A ideia central do Wiener (sem fórmulas intimidadoras)</a><li><a href="#eb-table-content-12">2.2 Modelo estatístico assumido</a><li><a href="#eb-table-content-13">2.3 Wiener no domínio da frequência (visão conceitual)</a><li><a href="#eb-table-content-14">2.4 Por que isso é poderoso em sistemas embarcados?</a><li><a href="#25-wiener-simplificado-para-mcu-forma-escalar">2.5 Wiener simplificado para MCU (forma escalar)</a><li><a href="#eb-table-content-16">2.6 Implementação incremental em C (forma prática)</a><li><a href="#eb-table-content-17">2.7 Estimando variâncias em tempo real</a><li><a href="#eb-table-content-18">2.8 Onde o Wiener falha (e quando não usar)</a><li><a href="#eb-table-content-19">2.9 EMA vs. Wiener (comparação direta)</a></li></ul><li><a href="#eb-table-content-20">3 — Filtro de Kalman: estimação de estados, incerteza e predição</a><ul class="eb-toc__list"><li><a href="#eb-table-content-21">3.1 Intuição antes da matemática</a><li><a href="#32-modelo-de-estado-caso-1d">3.2 Modelo de estado (caso 1D)</a><li><a href="#eb-table-content-23">3.3 Ciclo do Kalman: previsão e correção</a><ul class="eb-toc__list"><li><a href="#eb-table-content-24">1&#x20e3; Previsão</a><li><a href="#eb-table-content-25">2&#x20e3; Correção</a></li></ul><li><a href="#eb-table-content-26">3.4 Comparação conceitual com EMA e Wiener</a><li><a href="#eb-table-content-27">3.5 Implementação Kalman 1D em C (viável em MCU)</a><li><a href="#eb-table-content-28">3.6 Escolhendo Q e R (engenharia prática)</a><li><a href="#eb-table-content-29">3.7 Quando Kalman é a escolha certa</a><li><a href="#eb-table-content-30">3.8 Onde Kalman não compensa</a></li></ul><li><a href="#eb-table-content-31"> 4 — Comparação prática entre EMA, Wiener e Kalman, diretrizes de escolha, encerramento e SEO</a><ul class="eb-toc__list"><li><a href="#eb-table-content-32">4.1 O que realmente diferencia esses filtros (além da matemática)</a><li><a href="#eb-table-content-33">4.2 Comparação direta: quando cada filtro vence</a><li><a href="#eb-table-content-34">4.3 Diretrizes práticas de escolha (engenharia de campo)</a><li><a href="#eb-table-content-35">4.4 Conexão direta com os artigos anteriores da série</a><li><a href="#eb-table-content-36">4.5 Um erro comum: tratar filtros como “pós-processamento”</a><li><a href="#46-encerramento-conceitual">4.6 Encerramento conceitual</a></li></ul></ul></div></div></div></div></div>


<h3 class="wp-block-heading">Média Móvel Exponencial, Wiener e Kalman aplicados ao RP2040</h3>



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



<h2 class="wp-block-heading">1. Introdução — Por que filtros são decisores disfarçados</h2>



<p class="wp-block-paragraph">Ao longo desta série, trabalhamos com <strong>DSP embarcado aplicado</strong>, partindo do sinal bruto até decisões confiáveis em microcontroladores de recursos limitados. Em todos os artigos anteriores, um ponto ficou claro:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Nenhum sinal real é limpo.<br>Nenhuma decisão deve confiar em uma única amostra.</strong></p>
</blockquote>



<p class="wp-block-paragraph">É exatamente nesse ponto que entram os <strong>filtros estatísticos</strong>.</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="1024" height="768" src="https://mcu.tec.br/wp-content/uploads/2026/01/image.jpeg" alt="" class="wp-image-1138" srcset="https://mcu.tec.br/wp-content/uploads/2026/01/image.jpeg 1024w, https://mcu.tec.br/wp-content/uploads/2026/01/image-300x225.jpeg 300w, https://mcu.tec.br/wp-content/uploads/2026/01/image-768x576.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Embora muitas vezes apresentados apenas como técnicas matemáticas, filtros como <strong>média móvel exponencial</strong>, <strong>Wiener</strong> e <strong>Kalman</strong> são, na prática, <strong>mecanismos de tomada de decisão temporal</strong>, capazes de separar:</p>



<ul class="wp-block-list">
<li>sinal de ruído,</li>



<li>tendência de flutuação,</li>



<li>informação de incerteza.</li>
</ul>



<p class="wp-block-paragraph">Neste artigo, vamos tratar esses filtros <strong>não como abstrações matemáticas</strong>, mas como <strong>ferramentas práticas de engenharia</strong>, aplicáveis diretamente a microcontroladores como o RP2040.</p>



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



<h2 class="wp-block-heading">1.1 O papel dos filtros na arquitetura embarcada moderna</h2>



<p class="wp-block-paragraph">Em um sistema embarcado real, filtros aparecem em três papéis fundamentais:</p>



<ol class="wp-block-list">
<li><strong>Suavização</strong>
<ul class="wp-block-list">
<li>Reduz ruído de sensores</li>



<li>Evita decisões instáveis</li>
</ul>
</li>



<li><strong>Estimativa</strong>
<ul class="wp-block-list">
<li>Inferir estados não diretamente observáveis</li>



<li>Combinar modelo e medição</li>
</ul>
</li>



<li><strong>Tomada de decisão</strong>
<ul class="wp-block-list">
<li>Controlar histerese</li>



<li>Definir quando um evento realmente ocorreu</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph">Nos artigos anteriores, usamos:</p>



<ul class="wp-block-list">
<li>EMA implicitamente (suavização de score)</li>



<li>Estatística para decisão adaptativa</li>
</ul>



<p class="wp-block-paragraph">Agora, vamos <strong>formalizar isso conscientemente</strong>.</p>



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



<h2 class="wp-block-heading">1.2 Ordem crescente de complexidade (e poder)</h2>



<p class="wp-block-paragraph">Os filtros que abordaremos seguem uma progressão natural:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Filtro</th><th>Ideia central</th><th>Custo</th><th>Uso típico</th></tr></thead><tbody><tr><td>Média móvel exponencial</td><td>Suavizar passado</td><td>Muito baixo</td><td>Ruído rápido</td></tr><tr><td>Wiener</td><td>Minimizar erro médio</td><td>Médio</td><td>SNR conhecido</td></tr><tr><td>Kalman</td><td>Estimar estado oculto</td><td>Maior</td><td>Sistemas dinâmicos</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Importante:<br><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>mais complexo não significa melhor</strong>.<br>Cada filtro resolve um tipo específico de problema.</p>



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



<h2 class="wp-block-heading">1.3 Começando pelo mais importante: Média Móvel Exponencial (EMA)</h2>



<p class="wp-block-paragraph">A <strong>média móvel exponencial</strong> é, sem exagero, <strong>o filtro mais importante do firmware moderno</strong>.</p>



<p class="wp-block-paragraph">Ela aparece em:</p>



<ul class="wp-block-list">
<li>sensores IoT,</li>



<li>controle de ganhos,</li>



<li>suavização de scores,</li>



<li>debouncing avançado,</li>



<li>aprendizado estatístico.</li>
</ul>



<p class="wp-block-paragraph">E, ainda assim, é frequentemente subestimada.</p>



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



<h2 class="wp-block-heading">1.4 Conceito intuitivo da EMA</h2>



<p class="wp-block-paragraph">A EMA responde a uma pergunta simples:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><em>Quanto do passado eu quero lembrar?</em></p>
</blockquote>



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



<ul class="wp-block-list">
<li>valor anterior filtrado</li>



<li>nova amostra</li>
</ul>



<p class="wp-block-paragraph">Equação discreta:</p>



<p class="wp-block-paragraph">\[<br>y[n] = y[n-1] + \alpha \big(x[n] &#8211; y[n-1]\big)<br>\]



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



<ul class="wp-block-list">
<li>\(x[n]\): amostra atual</li>



<li>\(y[n]\): saída filtrada</li>



<li>\(\alpha \in (0,1)\): taxa de resposta</li>
</ul>



<p class="wp-block-paragraph">Interpretação física:</p>



<ul class="wp-block-list">
<li>\(\alpha\) pequeno → memória longa</li>



<li>\(\alpha\) grande → resposta rápida</li>
</ul>



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



<h2 class="wp-block-heading">1.5 EMA como filtro passa-baixa de primeira ordem</h2>



<p class="wp-block-paragraph">Embora simples, a EMA é um <strong>filtro IIR passa-baixa</strong>, com:</p>



<ul class="wp-block-list">
<li>1 polo real</li>



<li>estabilidade garantida</li>



<li>custo O(1) por amostra</li>
</ul>



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



<ul class="wp-block-list">
<li>ruído de alta frequência</li>



<li>flutuações instantâneas</li>
</ul>



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



<ul class="wp-block-list">
<li>buffers grandes</li>



<li>atrasos excessivos</li>
</ul>



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



<h2 class="wp-block-heading">1.6 Implementação incremental em C (base do artigo)</h2>



<p class="wp-block-paragraph">Começamos com a versão mais simples possível:</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>typedef struct {
    float y;
} ema_filter_t;

static inline void ema_init(ema_filter_t *f, float y0)
{
    f->y = y0;
}

static inline float ema_step(ema_filter_t *f, float x, float alpha)
{
    f->y += alpha * (x - f->y);
    return f->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: #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">float</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 style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ema_filter_t</span><span style="color: #81A1C1">;</span></span>
<span class="line"></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">ema_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">ema_filter_t</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">y0</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">f</span><span style="color: #81A1C1">-&gt;</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">y0</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: #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">ema_step</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">ema_filter_t</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: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">alpha</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">f</span><span style="color: #81A1C1">-&gt;</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">alpha</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">y</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: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</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">Características:</p>



<ul class="wp-block-list">
<li>Nenhuma alocação dinâmica</li>



<li>Uma multiplicação por amostra</li>



<li>Ideal para ISR ou loop rápido</li>
</ul>



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



<h2 class="wp-block-heading">1.7 Escolhendo o valor de α (engenharia, não tentativa)</h2>



<p class="wp-block-paragraph">Uma regra prática muito usada em firmware:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>α</th><th>Comportamento</th></tr></thead><tbody><tr><td>0.01</td><td>Muito suave, lento</td></tr><tr><td>0.05</td><td>Estável, robusto</td></tr><tr><td>0.1</td><td>Boa resposta</td></tr><tr><td>0.3+</td><td>Pouca filtragem</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Outra forma de pensar:</p>



<ul class="wp-block-list">
<li>EMA ≈ média móvel de \(N \approx \frac{2}{\alpha}\) amostras</li>
</ul>



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



<ul class="wp-block-list">
<li>α = 0.05 → ~40 amostras efetivas</li>
</ul>



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



<h2 class="wp-block-heading">1.8 Onde a EMA falha (e por quê)</h2>



<p class="wp-block-paragraph">Apesar de poderosa, a EMA tem limitações claras:</p>



<ul class="wp-block-list">
<li>Não modela dinâmica do sistema</li>



<li>Não separa ruído de sinal estatisticamente</li>



<li>Não incorpora incerteza</li>



<li>Não prevê o futuro</li>
</ul>



<p class="wp-block-paragraph">Essas limitações nos levam naturalmente aos próximos filtros.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/algoritimos/dsp/filtros-estatisticos-em-sistemas-embarcados-ema-wiener-e-kalman-aplicados-ao-rp2040/">Filtros Estatísticos em Sistemas Embarcados: EMA, Wiener e Kalman Aplicados ao RP2040</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1137</post-id>	</item>
		<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>Quaternions, Ângulos de Euler e Matrizes de Rotação: Guia Completo para Sistemas Embarcados e IMUs</title>
		<link>https://mcu.tec.br/algoritimos/quaternions-angulos-de-euler-e-matrizes-de-rotacao-guia-completo-para-sistemas-embarcados-e-imus/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=quaternions-angulos-de-euler-e-matrizes-de-rotacao-guia-completo-para-sistemas-embarcados-e-imus</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sun, 22 Feb 2026 10:22:40 +0000</pubDate>
				<category><![CDATA[Algoritimos]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1370</guid>

					<description><![CDATA[<p>Aprenda de forma didática e aprofundada como funcionam quaternions, ângulos de Euler e matrizes de rotação aplicados a sistemas embarcados com IMUs. Entenda as diferenças matemáticas, o problema do gimbal lock, como integrar dados de giroscópio, transformar vetores entre referenciais e remover a gravidade do acelerômetro. O artigo apresenta exemplos completos em C, com código comentado, ideais para microcontroladores como STM32, ESP32 e RP2040. Um guia técnico essencial para robótica, drones, controle de atitude e fusão sensorial.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/quaternions-angulos-de-euler-e-matrizes-de-rotacao-guia-completo-para-sistemas-embarcados-e-imus/">Quaternions, Ângulos de Euler e Matrizes de Rotação: Guia Completo para Sistemas Embarcados e IMUs</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-79cz2 wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-79cz2 "><div class="eb-toc-container eb-toc-79cz2  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;Introdu\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;\u00c2ngulos de Euler&quot;,&quot;text&quot;:&quot;\u00c2ngulos de Euler&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Vetores e Matrizes de Orienta\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Vetores e Matrizes de Orienta\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Quaternions&quot;,&quot;text&quot;:&quot;Quaternions&quot;,&quot;link&quot;:&quot;quaternions&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Representa\u00e7\u00e3o em C&quot;,&quot;text&quot;:&quot;Representa\u00e7\u00e3o em C&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Normaliza\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Normaliza\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Multiplica\u00e7\u00e3o de Quaternions&quot;,&quot;text&quot;:&quot;Multiplica\u00e7\u00e3o de Quaternions&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Integra\u00e7\u00e3o com Girosc\u00f3pio&quot;,&quot;text&quot;:&quot;Integra\u00e7\u00e3o com Girosc\u00f3pio&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Convers\u00e3o para \u00c2ngulos de Euler&quot;,&quot;text&quot;:&quot;Convers\u00e3o para \u00c2ngulos de Euler&quot;,&quot;link&quot;:&quot;eb-table-content-8&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Vantagens Cr\u00edticas dos Quaternions&quot;,&quot;text&quot;:&quot;Vantagens Cr\u00edticas dos Quaternions&quot;,&quot;link&quot;:&quot;eb-table-content-9&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Conclus\u00e3o&quot;,&quot;text&quot;:&quot;Conclus\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Refer\u00eancias&quot;,&quot;text&quot;:&quot;Refer\u00eancias&quot;,&quot;link&quot;:&quot;eb-table-content-11&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;introdu\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;\u00c2ngulos de Euler&quot;,&quot;value&quot;:&quot;\u00e2ngulos-de-euler&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Vetores e Matrizes de Orienta\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;vetores-e-matrizes-de-orienta\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Quaternions&quot;,&quot;value&quot;:&quot;quaternions&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Representa\u00e7\u00e3o em C&quot;,&quot;value&quot;:&quot;representa\u00e7\u00e3o-em-c&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Normaliza\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;normaliza\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Multiplica\u00e7\u00e3o de Quaternions&quot;,&quot;value&quot;:&quot;multiplica\u00e7\u00e3o-de-quaternions&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Integra\u00e7\u00e3o com Girosc\u00f3pio&quot;,&quot;value&quot;:&quot;integra\u00e7\u00e3o-com-girosc\u00f3pio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Convers\u00e3o para \u00c2ngulos de Euler&quot;,&quot;value&quot;:&quot;convers\u00e3o-para-\u00e2ngulos-de-euler&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Vantagens Cr\u00edticas dos Quaternions&quot;,&quot;value&quot;:&quot;vantagens-cr\u00edticas-dos-quaternions&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conclus\u00e3o&quot;,&quot;value&quot;:&quot;conclus\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Refer\u00eancias&quot;,&quot;value&quot;:&quot;refer\u00eancias&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">Introdução</a><li><a href="#eb-table-content-1">Ângulos de Euler</a><li><a href="#eb-table-content-2">Vetores e Matrizes de Orientação</a><li><a href="#quaternions">Quaternions</a><ul class="eb-toc__list"><li><a href="#eb-table-content-4">Representação em C</a><li><a href="#eb-table-content-5">Normalização</a><li><a href="#eb-table-content-6">Multiplicação de Quaternions</a><li><a href="#eb-table-content-7">Integração com Giroscópio</a><li><a href="#eb-table-content-8">Conversão para Ângulos de Euler</a><li><a href="#eb-table-content-9">Vantagens Críticas dos Quaternions</a></li></ul><li><a href="#eb-table-content-10">Conclusão</a><li><a href="#eb-table-content-11">Referências</a></ul></div></div></div></div></div>


<h2 class="wp-block-heading">Introdução</h2>



<p class="wp-block-paragraph">Quando você coloca uma IMU (Unidade de Medição Inercial) como MPU6050, MPU9250 ou qualquer combinação de acelerômetro e giroscópio dentro de um projeto embarcado, você acaba esbarrando cedo ou tarde na mesma pergunta: “como eu represento a orientação do meu objeto no espaço de um jeito que eu consiga calcular inclinação, compensar gravidade, integrar rotações ao longo do tempo e ainda não destruir a estabilidade numérica do firmware?”. É aí que entram três famílias de representações que parecem concorrentes, mas na prática se complementam: ângulos de Euler (roll, pitch, yaw), vetores de orientação (por exemplo, matriz de rotação ou pares de vetores base do corpo) e quaternions.</p>



<p class="wp-block-paragraph">Ângulos de Euler são intuitivos e ótimos para interfaces humanas: “inclinei 10° para frente”, “girei 30° no eixo Z”. O problema é que eles carregam armadilhas matemáticas quando você precisa acumular rotações ou passar por certas combinações de ângulos, especialmente o famoso gimbal lock (perda de um grau de liberdade). Vetores de orientação e matrizes de rotação são muito diretos do ponto de vista geométrico: você literalmente descreve para onde apontam os eixos do corpo no referencial do mundo, e isso é excelente para transformar vetores (como gravidade, aceleração e magnetismo) entre referenciais; em contrapartida, matrizes exigem mais operações, precisam ser re-ortogonalizadas para não “entortar” com erro numérico e ocupam mais memória.</p>



<p class="wp-block-paragraph">Quaternions entram como uma representação que, apesar de menos intuitiva à primeira vista, é extremamente eficiente e robusta para integrar rotações com giroscópio, evitar gimbal lock e manter estabilidade numérica com um custo computacional baixo o suficiente para microcontroladores. Na prática, muita gente usa quaternions “por dentro” do filtro (Madgwick, Mahony, EKF etc.) e converte para Euler “por fora” quando precisa exibir ângulos ou configurar limites.</p>



<p class="wp-block-paragraph">Nas próximas seções, eu vou construir esse entendimento em camadas: primeiro ângulos de Euler e suas relações trigonométricas, depois vetores/matrizes de orientação (com a leitura geométrica do que está acontecendo), e em seguida quaternions, mostrando como eles representam rotação, como compor rotações e como converter entre as formas. Em cada conceito eu vou demonstrar em C, com código comentado, como: (1) representar a orientação, (2) atualizar essa orientação com incrementos de rotação, e (3) extrair ângulos e também aplicar a orientação para separar aceleração linear da gravidade (o passo que faz “movimento” ficar mensurável a partir do acelerômetro).</p><p>The post <a href="https://mcu.tec.br/algoritimos/quaternions-angulos-de-euler-e-matrizes-de-rotacao-guia-completo-para-sistemas-embarcados-e-imus/">Quaternions, Ângulos de Euler e Matrizes de Rotação: Guia Completo para Sistemas Embarcados e IMUs</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1370</post-id>	</item>
		<item>
		<title>Filtragem de ruído em leituras ADC em microcontroladores (ATmega e ESP32) com exemplos em C</title>
		<link>https://mcu.tec.br/geral/filtragem-de-ruido-em-leituras-adc-em-microcontroladores-atmega-e-esp32-com-exemplos-em-c/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=filtragem-de-ruido-em-leituras-adc-em-microcontroladores-atmega-e-esp32-com-exemplos-em-c</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sat, 21 Feb 2026 13:47:31 +0000</pubDate>
				<category><![CDATA[Filstros]]></category>
		<category><![CDATA[geral]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1351</guid>

					<description><![CDATA[<p>Descubra como reduzir ruídos em leituras de ADC utilizando filtros digitais implementados em linguagem C para microcontroladores ATmega e ESP32. Este conteúdo técnico apresenta abordagens práticas como média móvel (FIR), filtro IIR de primeira ordem com ponto fixo (Q15), filtro de mediana para remoção de picos e a combinação eficiente mediana + IIR amplamente utilizada em firmware embarcado. Aprenda a escolher corretamente o coeficiente de suavização, entender o impacto da constante de tempo na resposta dinâmica do sistema e aplicar essas técnicas em sensores reais como NTC, sensores de corrente com shunt, pressão e sinais industriais. Guia essencial para desenvolvedores de sistemas embarcados e projetos IoT.</p>
<p>The post <a href="https://mcu.tec.br/geral/filtragem-de-ruido-em-leituras-adc-em-microcontroladores-atmega-e-esp32-com-exemplos-em-c/">Filtragem de ruído em leituras ADC em microcontroladores (ATmega e ESP32) com exemplos em C</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Quando você lê um ADC (Conversor Analógico-Digital) no “mundo real”, você não está lendo apenas o sinal útil: você está lendo também ruídos do próprio ADC (quantização, ruído térmico interno, ruído de referência), ruídos de fonte e layout (chaveamento de regulador, retorno de GND, acoplamento de trilhas), e ruídos “de ambiente” (EMI de motores, relés, Wi-Fi, etc.). O resultado clássico é um valor que “dança” alguns LSBs (Least Significant Bits) mesmo com o sinal estável. Filtrar isso em firmware costuma ser o caminho mais barato e rápido, desde que você escolha um filtro compatível com o tipo de ruído e com a dinâmica do seu sinal (se você filtrar demais, mata resposta; se filtrar de menos, sobra ruído).</p>



<p class="wp-block-paragraph">Um jeito prático de pensar é: primeiro você decide o que quer preservar (variações lentas? degraus rápidos? picos curtíssimos devem sumir?), depois você escolhe um filtro com custo computacional adequado ao MCU e ao seu <em>sampling rate</em> (taxa de amostragem). Em projetos embarcados, isso normalmente vira uma combinação simples e robusta: um filtro de mediana para “estouros” (spikes) + um passa-baixas leve (IIR de 1ª ordem) para suavizar o jitter. A ideia de encapsular a filtragem como um “bloco” bem definido (um filtro como componente) é um padrão recorrente em arquitetura de sistemas embarcados, porque separa aquisição, filtragem e consumo do dado, facilitando testes e evolução do firmware.</p>



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



<h2 class="wp-block-heading">O “mínimo que funciona” (pipeline recomendado)</h2>



<p class="wp-block-paragraph">Para a maioria dos sensores analógicos comuns (NTC, shunt com amplificador, potenciômetro, sensores de pressão), um pipeline simples funciona muito bem: você coleta <code>N</code> amostras rápidas, derruba outliers com <strong>mediana de 3 ou 5</strong>, e em seguida suaviza com um <strong>IIR 1-pole</strong>. A mediana protege contra picos (por exemplo, interferência curta de comutação), e o IIR dá suavidade com custo baixíssimo e latência controlável.</p>



<p class="wp-block-paragraph">A seguir eu deixo códigos em C “portáveis”, onde você só precisa plugar sua função de leitura do ADC (no ATmega pode ser <code>adc_read()</code>, no ESP32 pode ser <code>adc1_get_raw()</code>/<code>adc_oneshot_read()</code>).</p>



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



<h2 class="wp-block-heading">Filtro de média móvel (FIR simples) — bom para ruído “aleatório”, ruim para degrau rápido</h2>



<p class="wp-block-paragraph">A média móvel é o filtro mais lembrado porque é fácil de entender. Ela reduz ruído branco aproximadamente com ganho de suavização proporcional a <code>√N</code>, mas adiciona latência e “borra” degraus. Se seu sinal muda devagar (ex.: temperatura), ela é ótima.</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>

typedef struct {
    uint32_t acc;
    uint16_t *buf;
    uint16_t size;
    uint16_t idx;
    uint8_t  primed;
} movavg_t;

void movavg_init(movavg_t *f, uint16_t *buffer, uint16_t size) {
    f->acc = 0;
    f->buf = buffer;
    f->size = size;
    f->idx = 0;
    f->primed = 0;
    for (uint16_t i = 0; i &lt; size; i++) f->buf&#91;i&#93; = 0;
}

uint16_t movavg_update(movavg_t *f, uint16_t x) {
    f->acc -= f->buf&#91;f->idx&#93;;
    f->buf&#91;f->idx&#93; = x;
    f->acc += x;

    f->idx++;
    if (f->idx >= f->size) {
        f->idx = 0;
        f->primed = 1;
    }

    // Durante o aquecimento, a média fica "puxada" para zero.
    // Você pode tratar isso retornando x até primed=1, se preferir.
    uint16_t denom = f->primed ? f->size : (f->idx == 0 ? 1 : f->idx);
    return (uint16_t)(f->acc / denom);
}
</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>
<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">uint32_t</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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">buf</span><span style="color: #81A1C1">;</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">size</span><span style="color: #81A1C1">;</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>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">primed</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">movavg_t</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">movavg_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">movavg_t</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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">buffer</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">size</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</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">acc</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buffer</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">size</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">size</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">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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">primed</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: #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">size</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: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">buf</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: #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: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">movavg_update</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">movavg_t</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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</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">acc</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">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">f</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>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">f</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">x</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">acc</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: #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">idx</span><span style="color: #81A1C1">++;</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">f</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">size</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</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">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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">primed</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</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">// Durante o aquecimento, a média fica &quot;puxada&quot; para zero.</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Você pode tratar isso retornando x até primed=1, se preferir.</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">denom</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">primed</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">size</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">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: #D8DEE9FF"> </span><span style="color: #81A1C1">?</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</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">idx</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: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF">)(</span><span style="color: #D8DEE9">f</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">denom</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></code></pre></div>



<p class="wp-block-paragraph">No ATmega, isso é leve, mas se você usar janelas grandes (ex.: 64, 128) em uma taxa alta, vira custo de RAM e latência. No ESP32, geralmente é tranquilo.</p>



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



<h2 class="wp-block-heading">Filtro IIR de 1ª ordem (passa-baixas “exponencial”) — o cavalo de batalha do firmware</h2>



<p class="wp-block-paragraph">Esse filtro é o “suavizador” mais usado em embarcados porque tem custo O(1), pouca RAM e é estável se você escolher o ganho corretamente. Ele implementa, na prática, uma média ponderada: o valor novo puxa o estado aos poucos. Em tempo discreto: <code>y[n] = y[n-1] + α (x[n] - y[n-1])</code>. O parâmetro <code>α</code> controla o compromisso entre suavidade e resposta.</p>



<h3 class="wp-block-heading">Versão fixed-point (boa para ATmega, sem <code>float</code>)</h3>



<p class="wp-block-paragraph">Aqui eu uso Q15 (15 bits fracionários). <code>alpha_q15</code> vai de 1 a 32767, equivalente a (0, 1).</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>

typedef struct {
    int32_t y_q15;       // estado em Q15
    uint16_t alpha_q15;  // 0..32767 (~0..1)
    uint8_t initialized;
} iir1_q15_t;

void iir1_q15_init(iir1_q15_t *f, uint16_t alpha_q15) {
    if (alpha_q15 > 32767) alpha_q15 = 32767;
    f->y_q15 = 0;
    f->alpha_q15 = alpha_q15;
    f->initialized = 0;
}

uint16_t iir1_q15_update(iir1_q15_t *f, uint16_t x) {
    int32_t x_q15 = ((int32_t)x) &lt;&lt; 15;

    if (!f->initialized) {
        f->y_q15 = x_q15;
        f->initialized = 1;
        return x;
    }

    // y = y + alpha*(x - y)
    int32_t err = x_q15 - f->y_q15;
    f->y_q15 += ( (int32_t)f->alpha_q15 * err ) >> 15;

    // arredondamento simples e saturação para 16 bits
    int32_t y = (f->y_q15 + (1 &lt;&lt; 14)) >> 15;
    if (y &lt; 0) y = 0;
    if (y > 65535) y = 65535;
    return (uint16_t)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">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: #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">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y_q15</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">       </span><span style="color: #616E88">// estado em Q15</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">alpha_q15</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">// 0..32767 (~0..1)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">initialized</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">iir1_q15_t</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">iir1_q15_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">iir1_q15_t</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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">alpha_q15</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</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">alpha_q15</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">32767</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">alpha_q15</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">32767</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">y_q15</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">alpha_q15</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">alpha_q15</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">initialized</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: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">iir1_q15_update</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">iir1_q15_t</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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</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_q15</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">x</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">15</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: #81A1C1">!</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">initialized</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</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">y_q15</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x_q15</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">initialized</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</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">x</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">// y = y + alpha*(x - y)</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">err</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x_q15</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">y_q15</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">y_q15</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">alpha_q15</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF"> ) </span><span style="color: #81A1C1">&gt;&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">15</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// arredondamento simples e saturação para 16 bits</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">y_q15</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">14</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">&gt;&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">15</span><span style="color: #81A1C1">;</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">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</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: #B48EAD">0</span><span style="color: #81A1C1">;</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">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">65535</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: #B48EAD">65535</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">uint16_t</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>Como escolher <code>α</code> sem virar matemática demais?</strong> Se você amostra a cada <code>Ts</code> e quer uma suavização equivalente a uma constante de tempo aproximada <code>τ</code>, uma aproximação prática é <code>α ≈ Ts / (τ + Ts)</code>. Exemplo: amostragem a 1 kHz (<code>Ts=1 ms</code>) e você quer “assentar” em ~100 ms ⇒ <code>α ≈ 0,001/(0,101) ≈ 0,0099</code>, então <code>alpha_q15 ≈ 0,0099 * 32768 ≈ 324</code>. Isso dá um filtro bem suave.</p>



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



<h2 class="wp-block-heading">Filtro de mediana — mata spikes sem “atrasar” tanto quanto média</h2>



<p class="wp-block-paragraph">Se o seu problema são picos curtos (ex.: ruído de chaveamento de relé, PWM, comutação de fonte), a mediana é muito eficiente. Para janela 3, o custo é mínimo.</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>

static inline uint16_t median3_u16(uint16_t a, uint16_t b, uint16_t c) {
    // ordena parcialmente sem usar array
    if (a > b) { uint16_t t=a; a=b; b=t; }
    if (b > c) { uint16_t t=b; b=c; c=t; }
    if (a > b) { uint16_t t=a; a=b; b=t; }
    return b; // b é a mediana
}

typedef struct {
    uint16_t x1, x2;
    uint8_t primed;
} median3_t;

void median3_init(median3_t *f) {
    f->x1 = f->x2 = 0;
    f->primed = 0;
}

uint16_t median3_update(median3_t *f, uint16_t x) {
    if (!f->primed) {
        f->x2 = f->x1;
        f->x1 = x;
        if (f->x2 != 0) f->primed = 1;
        return x;
    }
    uint16_t y = median3_u16(f->x2, f->x1, x);
    f->x2 = f->x1;
    f->x1 = x;
    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">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: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">median3_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</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">b</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">c</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// ordena parcialmente sem usar array</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">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b</span><span style="color: #D8DEE9FF">) </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">t</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">a</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">b</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">t</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: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">b</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">c</span><span style="color: #D8DEE9FF">) </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">t</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">b</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">c</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">c</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">t</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: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b</span><span style="color: #D8DEE9FF">) </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">t</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">a</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">b</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">t</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: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// b é a mediana</span></span>
<span class="line"><span style="color: #ECEFF4">}</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">x1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x2</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">primed</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">median3_t</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">median3_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">median3_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</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">x1</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">x2</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">primed</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: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">median3_update</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">median3_t</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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">primed</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</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">x2</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">x1</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">x1</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: #81A1C1">;</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">x2</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: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">primed</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</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">x</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: #D8DEE9">uint16_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: #88C0D0">median3_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">x2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">x1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">)</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">x2</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">x1</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">x1</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: #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>



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



<h2 class="wp-block-heading">Exemplo completo: mediana + IIR (bom “default” para ATmega e ESP32)</h2>



<p class="wp-block-paragraph">Aqui fica o esqueleto de uma função de “leitura filtrada” que você pode usar em uma task/loop periódico. Você substitui <code>adc_read_raw()</code> por sua leitura real.</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>

// ---- mocks / stubs: substitua pela sua HAL ----
uint16_t adc_read_raw(void); // ATmega: ADC; ESP32: adc oneshot raw
// ----------------------------------------------

typedef struct {
    median3_t   med;
    iir1_q15_t  lp;
} adc_filter_t;

void adc_filter_init(adc_filter_t *f, uint16_t alpha_q15) {
    median3_init(&amp;f->med);
    iir1_q15_init(&amp;f->lp, alpha_q15);
}

uint16_t adc_read_filtered(adc_filter_t *f) {
    uint16_t x = adc_read_raw();
    uint16_t x_med = median3_update(&amp;f->med, x);
    uint16_t y = iir1_q15_update(&amp;f->lp, x_med);
    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">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: #616E88">// ---- mocks / stubs: substitua pela sua HAL ----</span></span>
<span class="line"><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">adc_read_raw</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// ATmega: ADC; ESP32: adc oneshot raw</span></span>
<span class="line"><span style="color: #616E88">// ----------------------------------------------</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">median3_t</span><span style="color: #D8DEE9FF">   </span><span style="color: #D8DEE9">med</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">iir1_q15_t</span><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">lp</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">adc_filter_t</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">adc_filter_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">adc_filter_t</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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">alpha_q15</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">median3_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">med</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">iir1_q15_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">lp</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">alpha_q15</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: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">adc_read_filtered</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">adc_filter_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">f</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">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">adc_read_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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x_med</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">median3_update</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">med</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</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">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">iir1_q15_update</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">lp</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x_med</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: #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">No ATmega, isso costuma caber confortavelmente e resolve 80% dos casos reais. No ESP32, você pode manter igual ou trocar o IIR para <code>float</code> se quiser ajustar <code>α</code> dinamicamente com mais facilidade, mas não é necessário.</p>



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



<h2 class="wp-block-heading">Quando isso não basta (e o que fazer)</h2>



<p class="wp-block-paragraph">Se o seu ruído é “bem comportado” (aleatório, de alta frequência), média móvel e IIR resolvem. Se o ruído é dominado por rede elétrica (50/60 Hz) acoplando no sensor, muitas vezes vale mais a pena atacar na causa (impedância de fonte, RC analógico antes do ADC, referência e aterramento) e depois, no firmware, usar um filtro que tenha rejeição nessa frequência, como um notch discreto ou uma média sincronizada com o período (quando você sabe a fase). E se o ADC está sofrendo com fonte de alta impedância, nenhum filtro compensa totalmente: aí você melhora o circuito (buffer com op-amp, capacitor no sample/hold, tempo de aquisição maior, etc.) antes de “pedir milagre” ao DSP.</p><p>The post <a href="https://mcu.tec.br/geral/filtragem-de-ruido-em-leituras-adc-em-microcontroladores-atmega-e-esp32-com-exemplos-em-c/">Filtragem de ruído em leituras ADC em microcontroladores (ATmega e ESP32) com exemplos 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">1351</post-id>	</item>
		<item>
		<title>Mediana em medições via ADC e o algoritmo de seleção por partição (Quickselect)</title>
		<link>https://mcu.tec.br/algoritimos/dsp/mediana-em-medicoes-via-adc-e-o-algoritmo-de-selecao-por-particao-quickselect/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mediana-em-medicoes-via-adc-e-o-algoritmo-de-selecao-por-particao-quickselect</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Thu, 19 Feb 2026 16:44:49 +0000</pubDate>
				<category><![CDATA[DSP]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1374</guid>

					<description><![CDATA[<p>Aprenda de forma didática como calcular a mediana em medições de ADC utilizando o algoritmo de seleção por partição (Quickselect) em sistemas embarcados. Este artigo explica o conceito estatístico de mediana, apresenta as fórmulas para janelas pares e ímpares, discute complexidade computacional O(N) média versus O(N log N) da ordenação completa e demonstra passo a passo a implementação em linguagem C otimizada para microcontroladores. Ideal para aplicações com STM32, ESP32, RP2040 e outros MCUs, o conteúdo mostra como reduzir ruídos impulsivos, melhorar a robustez de leituras analógicas e aplicar o filtro de mediana em janelas deslizantes de forma eficiente e segura em tempo real.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/dsp/mediana-em-medicoes-via-adc-e-o-algoritmo-de-selecao-por-particao-quickselect/">Mediana em medições via ADC e o algoritmo de seleção por partição (Quickselect)</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Em medições reais com ADC (Conversor Analógico–Digital), ruído impulsivo e leituras “espúrias” aparecem com frequência: comutação de fonte, EMI (Interferência Eletromagnética), contato ruim, saturação momentânea do front-end, etc. Se você faz apenas média aritmética, um único pico pode arrastar o resultado. A mediana, por outro lado, é um estimador robusto: ela “ignora” a magnitude dos extremos e depende basicamente da posição (ordem) dos valores. Isso a torna excelente para filtrar leituras em janelas deslizantes (por exemplo, 9, 15 ou 31 amostras), entregando um valor estável sem “amassar” tanto degraus quanto um passa-baixas forte faria.</p>



<p class="wp-block-paragraph">A ideia prática em firmware é simples: você acumula <strong>N</strong> amostras do ADC em um buffer, calcula a mediana do buffer e usa esse valor como leitura filtrada. O detalhe é que ordenar <strong>tudo</strong> (por exemplo, com quicksort) custa mais do que precisamos. Para achar a mediana, basta encontrar o elemento “do meio” na ordem — e isso pode ser feito com <strong>seleção por partição</strong>, também conhecida como <strong>Quickselect</strong>.</p>



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



<h2 class="wp-block-heading">Fórmulas: o que é a mediana (caso ímpar e par)</h2>



<p class="wp-block-paragraph">Considere uma janela com <strong>N</strong> amostras \(x_0, x_1, \dots, x_{N-1}\). Imagine a versão ordenada dessas amostras \(x_{(0)} \le x_{(1)} \le \dots \le x_{(N-1)}\), onde \(x_{(k)}\) é o k-ésimo menor valor.</p>



<p class="wp-block-paragraph">Quando <strong>N é ímpar</strong>, a mediana é o elemento central:</p>



<p class="wp-block-paragraph">\[<br>\mathrm{med}(x) = x_{\left(\frac{N-1}{2}\right)}<br>\]



<p class="wp-block-paragraph">Quando <strong>N é par</strong>, há duas convenções comuns. A mais usada em processamento numérico é a média dos dois centrais:</p>



<p class="wp-block-paragraph">\[<br>\mathrm{med}(x) = \frac{ x_{\left(\frac{N}{2}-1\right)} + x_{\left(\frac{N}{2}\right)} }{2}<br>\]



<p class="wp-block-paragraph">Em ADC (inteiro), essa divisão por 2 costuma ser feita com cuidado para não estourar o tipo (por isso somamos em 32 bits e só depois dividimos).</p>



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



<h2 class="wp-block-heading">Por que “seleção por partição” resolve melhor que ordenar tudo</h2>



<p class="wp-block-paragraph">Ordenar N valores tipicamente custa \(O(N \log N)\). Já o <strong>Quickselect</strong> encontra o k-ésimo menor em <strong>tempo médio (O(N))</strong>, porque ele faz o mesmo “corte” do quicksort (partição em torno de um pivô), mas só continua recursivamente/iterativamente <strong>no lado que contém o índice k</strong>. Para a mediana, você quer \(k = (N-1)/2\) (ou os dois centrais se N for par).</p>



<p class="wp-block-paragraph">Para firmware, isso é valioso: menos ciclos, menos consumo, e você pode rodar a cada janela sem pesar no tempo real. Em geral, o algoritmo trabalha <strong>in-place</strong> (ele rearranja o buffer). Se você precisa preservar as amostras originais, basta copiar a janela para um buffer temporário e aplicar o Quickselect nesse temporário.</p>



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



<h2 class="wp-block-heading">Código em C: Quickselect iterativo + mediana para ADC (uint16_t)</h2>



<p class="wp-block-paragraph">Abaixo vai uma implementação <strong>iterativa</strong> (evita recursão, o que é mais amigável a microcontroladores), com partição estilo Lomuto. Ela funciona bem para medianas em janelas pequenas/médias (bem típico em ADC). Está tudo comentado e pronto para colar em um projeto bare-metal/RTOS.</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;stddef.h>

/**
 * @brief Troca dois elementos uint16_t.
 */
static inline void swap_u16(uint16_t *a, uint16_t *b)
{
    uint16_t t = *a;
    *a = *b;
    *b = t;
}

/**
 * @brief Particiona o array no intervalo &#91;left, right&#93; usando o pivô em pivot_index.
 *
 * Após a partição:
 * - todos os elementos &lt; pivot ficam à esquerda,
 * - todos os elementos >= pivot ficam à direita,
 * - a função retorna a posição final do pivô.
 *
 * @param a Array de amostras (será rearranjado in-place).
 * @param left Índice inicial do intervalo.
 * @param right Índice final do intervalo.
 * @param pivot_index Índice do pivô escolhido.
 * @return size_t Posição final do pivô após a partição.
 */
static size_t partition_lomuto_u16(uint16_t *a, size_t left, size_t right, size_t pivot_index)
{
    const uint16_t pivot = a&#91;pivot_index&#93;;

    // Move pivô para o final para particionar mais facilmente
    swap_u16(&amp;a&#91;pivot_index&#93;, &amp;a&#91;right&#93;);

    size_t store = left;

    for (size_t i = left; i &lt; right; i++)
    {
        if (a&#91;i&#93; &lt; pivot)
        {
            swap_u16(&amp;a&#91;i&#93;, &amp;a&#91;store&#93;);
            store++;
        }
    }

    // Coloca o pivô na posição final
    swap_u16(&amp;a&#91;store&#93;, &amp;a&#91;right&#93;);
    return store;
}

/**
 * @brief Escolha simples de pivô: "mediana de três" (left, mid, right).
 *
 * Isso reduz a chance de pior caso em dados parcialmente ordenados,
 * algo comum em ADC com rampa lenta.
 */
static size_t pivot_median_of_three_u16(uint16_t *a, size_t left, size_t right)
{
    size_t mid = left + (right - left) / 2;

    uint16_t x = a&#91;left&#93;;
    uint16_t y = a&#91;mid&#93;;
    uint16_t z = a&#91;right&#93;;

    // Retorna o índice da mediana entre x, y, z
    if ((x &lt;= y &amp;&amp; y &lt;= z) || (z &lt;= y &amp;&amp; y &lt;= x)) return mid;
    if ((y &lt;= x &amp;&amp; x &lt;= z) || (z &lt;= x &amp;&amp; x &lt;= y)) return left;
    return right;
}

/**
 * @brief Quickselect iterativo: encontra o k-ésimo menor elemento (0-based).
 *
 * @param a Array (será rearranjado in-place).
 * @param n Tamanho do array.
 * @param k Índice (0..n-1) do elemento desejado na ordem crescente.
 * @return uint16_t Valor do k-ésimo menor elemento.
 */
uint16_t quickselect_k_u16(uint16_t *a, size_t n, size_t k)
{
    size_t left = 0;
    size_t right = n - 1;

    while (left &lt;= right)
    {
        size_t pivot_index = pivot_median_of_three_u16(a, left, right);
        size_t pivot_final = partition_lomuto_u16(a, left, right, pivot_index);

        if (pivot_final == k)
        {
            return a&#91;pivot_final&#93;;
        }
        else if (k &lt; pivot_final)
        {
            // Continua só no lado esquerdo
            if (pivot_final == 0) break; // proteção contra underflow
            right = pivot_final - 1;
        }
        else
        {
            // Continua só no lado direito
            left = pivot_final + 1;
        }
    }

    // Em condições normais não chega aqui; retorno defensivo
    return a&#91;k&#93;;
}

/**
 * @brief Calcula a mediana de uma janela ADC (uint16_t).
 *
 * Observação importante: o Quickselect altera o array.
 * Se você precisa preservar o buffer original, passe uma cópia.
 *
 * @param window Buffer de N amostras.
 * @param n Número de amostras (N).
 * @return uint16_t Mediana (para N par, retorna a média dos dois centrais).
 */
uint16_t median_adc_u16_inplace(uint16_t *window, size_t n)
{
    if (n == 0) return 0;

    if (n &amp; 1u)
    {
        // N ímpar: elemento central
        size_t k = (n - 1u) / 2u;
        return quickselect_k_u16(window, n, k);
    }
    else
    {
        // N par: média dos dois centrais
        size_t k1 = (n / 2u) - 1u;
        size_t k2 = (n / 2u);

        uint16_t m1 = quickselect_k_u16(window, n, k1);
        uint16_t m2 = quickselect_k_u16(window, n, k2);

        // Soma em 32 bits para evitar overflow e divide por 2
        uint32_t sum = (uint32_t)m1 + (uint32_t)m2;
        return (uint16_t)(sum / 2u);
    }
}
</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">stddef</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">/**</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"> Troca dois elementos uint16_t.</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">swap_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">a</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: #81A1C1">*</span><span style="color: #D8DEE9">b</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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">a</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">b</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">b</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">t</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"> Particiona o array no intervalo &#91;left, right&#93; usando o pivô em pivot_index.</span></span>
<span class="line"><span style="color: #616E88"> *</span></span>
<span class="line"><span style="color: #616E88"> * Após a partição:</span></span>
<span class="line"><span style="color: #616E88"> * - todos os elementos &lt; pivot ficam à esquerda,</span></span>
<span class="line"><span style="color: #616E88"> * - todos os elementos &gt;= pivot ficam à direita,</span></span>
<span class="line"><span style="color: #616E88"> * - a função retorna a posição final do pivô.</span></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">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">a</span><span style="color: #616E88"> Array de amostras (será rearranjado in-place).</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">left</span><span style="color: #616E88"> Índice inicial do intervalo.</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">right</span><span style="color: #616E88"> Índice final do intervalo.</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">pivot_index</span><span style="color: #616E88"> Índice do pivô escolhido.</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"> size_t Posição final do pivô após a partição.</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">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">partition_lomuto_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">a</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">left</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">right</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">pivot_index</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">uint16_t</span><span style="color: #D8DEE9FF"> pivot </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">pivot_index</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Move pivô para o final para particionar mais facilmente</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">swap_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">pivot_index</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">right</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">store</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">left</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: #D8DEE9">size_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: #D8DEE9">left</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">right</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>
<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: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pivot</span><span style="color: #D8DEE9FF">)</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: #88C0D0">swap_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">store</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">store</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: #ECEFF4">    </span><span style="color: #616E88">// Coloca o pivô na posição final</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">swap_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">store</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">right</span><span style="color: #D8DEE9FF">&#93;)</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">store</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"> Escolha simples de pivô: &quot;mediana de três&quot; (left, mid, right).</span></span>
<span class="line"><span style="color: #616E88"> *</span></span>
<span class="line"><span style="color: #616E88"> * Isso reduz a chance de pior caso em dados parcialmente ordenados,</span></span>
<span class="line"><span style="color: #616E88"> * algo comum em ADC com rampa lenta.</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">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">pivot_median_of_three_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">a</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">left</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">right</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">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mid</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">left</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">right</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">left</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">;</span></span>
<span class="line"></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">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">left</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</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">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">mid</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</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">z</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">right</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Retorna o índice da mediana entre x, y, z</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">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">||</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">z</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mid</span><span style="color: #81A1C1">;</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">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">||</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">z</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">left</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">right</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"> Quickselect iterativo: encontra o k-ésimo menor elemento (0-based).</span></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">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">a</span><span style="color: #616E88"> Array (será rearranjado in-place).</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"> Tamanho do array.</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">k</span><span style="color: #616E88"> Índice (0..n-1) do elemento desejado na ordem crescente.</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"> uint16_t Valor do k-ésimo menor elemento.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">quickselect_k_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">a</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: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</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">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">left</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">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">right</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: #B48EAD">1</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">left</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">right</span><span style="color: #D8DEE9FF">)</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: #D8DEE9">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pivot_index</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">pivot_median_of_three_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">left</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">right</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pivot_final</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">partition_lomuto_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">left</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">right</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pivot_index</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">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">pivot_final</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF">)</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: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">pivot_final</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: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pivot_final</span><span style="color: #D8DEE9FF">)</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 style="color: #616E88">// Continua só no lado esquerdo</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">pivot_final</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: #81A1C1">break;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// proteção contra underflow</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">right</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pivot_final</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</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: #81A1C1">else</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 style="color: #616E88">// Continua só no lado direito</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">left</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pivot_final</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</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: #ECEFF4">    </span><span style="color: #616E88">// Em condições normais não chega aqui; retorno defensivo</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">a</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF">&#93;</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"> Calcula a mediana de uma janela ADC (uint16_t).</span></span>
<span class="line"><span style="color: #616E88"> *</span></span>
<span class="line"><span style="color: #616E88"> * Observação importante: o Quickselect altera o array.</span></span>
<span class="line"><span style="color: #616E88"> * Se você precisa preservar o buffer original, passe uma cópia.</span></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">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">window</span><span style="color: #616E88"> Buffer de N amostras.</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"> Número de amostras (N).</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"> uint16_t Mediana (para N par, retorna a média dos dois centrais).</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">median_adc_u16_inplace</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">window</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>
<span class="line"><span style="color: #ECEFF4">{</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: #B48EAD">0</span><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>
<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">&amp;</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #D8DEE9">u</span><span style="color: #D8DEE9FF">)</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 style="color: #616E88">// N ímpar: elemento central</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF"> </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: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #D8DEE9">u</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> 2</span><span style="color: #D8DEE9">u</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: #88C0D0">quickselect_k_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">window</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </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: #81A1C1">else</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 style="color: #616E88">// N par: média dos dois centrais</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k1</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"> 2</span><span style="color: #D8DEE9">u</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #D8DEE9">u</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k2</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"> 2</span><span style="color: #D8DEE9">u</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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">m1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">quickselect_k_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">window</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k1</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</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">m2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">quickselect_k_u16</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">window</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k2</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">// Soma em 32 bits para evitar overflow e divide por 2</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">sum</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">m1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">m2</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">uint16_t</span><span style="color: #D8DEE9FF">)(</span><span style="color: #D8DEE9">sum</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> 2</span><span style="color: #D8DEE9">u</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: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Como usar em um fluxo típico de ADC (janela deslizante)</h3>



<p class="wp-block-paragraph">Em prática embarcada, você costuma ter um buffer circular com N amostras mais recentes. Quando a janela “fecha” (por exemplo, a cada amostra ou a cada bloco DMA), você copia para um buffer temporário e calcula a mediana nele, preservando o circular.</p>



<p class="wp-block-paragraph">Uma versão de uso (exemplo) ficaria assim:</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;string.h> // memcpy

#define N  15

static uint16_t adc_ring&#91;N&#93;;
static uint16_t tmp&#91;N&#93;;
static size_t wr = 0;

/**
 * @brief Atualiza a janela com uma nova amostra e devolve a mediana.
 *
 * @param sample Nova leitura ADC.
 * @return uint16_t Mediana das últimas N amostras.
 */
uint16_t adc_update_and_median(uint16_t sample)
{
    adc_ring&#91;wr&#93; = sample;
    wr = (wr + 1u) % N;

    // Copia a janela para processar sem bagunçar o ring
    memcpy(tmp, adc_ring, sizeof(tmp));

    return median_adc_u16_inplace(tmp, N);
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="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">string</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// memcpy</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</span><span style="color: #D8DEE9FF">  </span><span style="color: #B48EAD">15</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">adc_ring</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">N</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">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">tmp</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">N</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">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">wr</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>
<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"> Atualiza a janela com uma nova amostra e devolve a mediana.</span></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">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">sample</span><span style="color: #616E88"> Nova leitura ADC.</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"> uint16_t Mediana das últimas N amostras.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">adc_update_and_median</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sample</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">adc_ring</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">wr</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sample</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">wr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">wr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #D8DEE9">u</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>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Copia a janela para processar sem bagunçar o ring</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">memcpy</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">tmp</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">adc_ring</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sizeof</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">tmp</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">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">median_adc_u16_inplace</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">tmp</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</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></code></pre></div>



<p class="wp-block-paragraph">Esse padrão é especialmente bom quando você tem ruídos impulsivos: a mediana remove “picos” isolados com eficiência sem a latência de um filtro passa-baixas forte.</p>



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



<h2 class="wp-block-heading">Observações de engenharia para ficar “bom de firmware”</h2>



<p class="wp-block-paragraph">Como o Quickselect rearranja dados, o custo de memória vira uma decisão de projeto: se você pode destruir a janela, roda direto; se não pode, copie. Em microcontroladores pequenos, dá para manter um <code>tmp[]</code> estático do tamanho da janela. Para tempo real, prefira N pequeno (9, 15, 31) e pivô “mediana de três” como no código para reduzir casos ruins quando o sinal muda lentamente. Se você estiver usando FreeRTOS, essa função pode rodar numa tarefa de processamento após um evento do DMA, mantendo o ISR enxuto.</p>



<p class="wp-block-paragraph">Se você quiser ir além, dá para combinar mediana com média: primeiro aplica mediana para “limpar” impulsos e depois uma média móvel curta para reduzir ruído branco, o que costuma ficar excelente para sensores resistivos, NTC e shunt (onde spikes de comutação aparecem).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/algoritimos/dsp/mediana-em-medicoes-via-adc-e-o-algoritmo-de-selecao-por-particao-quickselect/">Mediana em medições via ADC e o algoritmo de seleção por partição (Quickselect)</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1374</post-id>	</item>
		<item>
		<title>MPU9250: como usar uma IMU 9 eixos e extrair dados realmente “úteis”</title>
		<link>https://mcu.tec.br/algoritimos/posicionamento/mpu9250-como-usar-uma-imu-9-eixos-e-extrair-dados-realmente-uteis/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mpu9250-como-usar-uma-imu-9-eixos-e-extrair-dados-realmente-uteis</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sun, 15 Feb 2026 12:27:33 +0000</pubDate>
				<category><![CDATA[posicionamento]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1338</guid>

					<description><![CDATA[<p>Aprenda a usar o MPU9250, uma IMU de 9 eixos que integra acelerômetro, giroscópio e magnetômetro, para medir movimento e orientação em três dimensões com qualidade prática de engenharia. Este guia mostra como estruturar a aquisição de dados por I²C ou SPI, converter leituras cruas para unidades físicas, remover bias de giroscópio, lidar com ruído e aplicar filtragem eficiente em microcontroladores. Você verá como transformar sinais em informações úteis como roll, pitch e yaw, entendendo as projeções trigonométricas e por que o magnetômetro precisa de calibração para evitar erros de rumo. O artigo inclui exemplos de algoritmos em linguagem C, com arquitetura de firmware organizada, e finaliza com scripts em Python para visualizar eixos e conceitos geométricos 3D, servindo como referência para depuração e validação do seu pipeline.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/posicionamento/mpu9250-como-usar-uma-imu-9-eixos-e-extrair-dados-realmente-uteis/">MPU9250: como usar uma IMU 9 eixos e extrair dados realmente “úteis”</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">O MPU9250 ficou popular porque entrega, num único encapsulamento, um acelerômetro de 3 eixos, um giroscópio de 3 eixos e um magnetômetro de 3 eixos (na prática, são dois “dies”: o bloco accel/gyro e o AK8963 para bússola). Isso permite estimar orientação 3D (roll, pitch, yaw), detectar padrões de movimento, vibração e eventos transitórios, além de fornecer insumos para navegação inercial e estabilização. Ele é muito bom para aprendizado e prototipagem, mas hoje está marcado como fim de vida/NRND pela própria TDK/InvenSense, então a recomendação é não projetar produto novo em cima dele. (<a href="https://invensense.tdk.com/products/motion-tracking/9-axis/mpu-9250/?utm_source=chatgpt.com">TDK InvenSense</a>)</p>


<div class="wp-block-image">
<figure class="alignright size-full is-resized"><img decoding="async" width="410" height="424" src="https://mcu.tec.br/wp-content/uploads/2026/02/image-34.png" alt="" class="wp-image-1339" style="aspect-ratio:0.967032967032967;width:330px;height:auto" srcset="https://mcu.tec.br/wp-content/uploads/2026/02/image-34.png 410w, https://mcu.tec.br/wp-content/uploads/2026/02/image-34-290x300.png 290w" sizes="(max-width: 410px) 100vw, 410px" /></figure>
</div>


<p class="wp-block-paragraph">A parte “enganosa” das IMUs é que ler registradores e imprimir “Ax, Ay, Az” quase nunca resolve o problema real. O valor está cru, com bias (offset), ruído, drift, saturação, escalas diferentes, e no caso do magnetômetro ainda existe distorção de hard-iron/soft-iron. O objetivo aqui é te mostrar um caminho de uso que funciona na prática: inicialização correta, aquisição consistente, calibração e, por fim, fusão de sensores para produzir orientação e métricas refinadas.</p>



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



<h3 class="wp-block-heading">1) Arquitetura do MPU9250 e o que isso muda no firmware</h3>



<p class="wp-block-paragraph">O MPU9250 tem dois “mundos” que você precisa coordenar:</p>



<ol class="wp-block-list">
<li><strong>Accel/Gyro</strong> (bloco principal) acessado direto pelo barramento do host (I²C ou SPI).</li>



<li><strong>Magnetômetro (AK8963)</strong> acessado de duas formas: ou você coloca o MPU em “pass-through / bypass” e fala direto com o AK8963 no endereço I²C <strong>0x0C</strong>, ou você usa o barramento auxiliar interno do MPU (modo “master”) para o MPU ler o magnetômetro e disponibilizar os dados ao host. A própria especificação descreve o uso do pass-through e cita explicitamente o endereço do AK8963. (<a href="https://invensense.tdk.com/wp-content/uploads/2015/02/PS-MPU-9250A-01-v1.1.pdf?utm_source=chatgpt.com">TDK InvenSense</a>)</li>
</ol>



<p class="wp-block-paragraph">Para simplificar e reduzir “magia” no início, muitos projetos usam <strong>pass-through</strong>: o host configura e lê o magnetômetro como se fosse outro dispositivo I²C no mesmo barramento. Isso também facilita depuração com ferramentas como <code>i2cdetect</code>, embora existam armadilhas de configuração.</p>



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



<h3 class="wp-block-heading">2) O “pipeline” certo: do dado cru ao dado refinado</h3>



<p class="wp-block-paragraph">Um pipeline robusto costuma seguir esta lógica (mesmo que você implemente em etapas):</p>



<ol class="wp-block-list">
<li><strong>Leitura atômica</strong> de accel/gyro (idealmente usando burst read para garantir coerência temporal).</li>



<li><strong>Conversão de escala</strong> (LSB → unidades físicas).</li>



<li><strong>Compensação de bias</strong> (offset) e, se necessário, escala fina (ganho).</li>



<li><strong>Filtragem leve</strong> (LPF) para reduzir ruído sem destruir dinâmica.</li>



<li><strong>Fusão de sensores</strong> para estimar orientação:
<ul class="wp-block-list">
<li>Complementary filter (simples e bom) para roll/pitch</li>



<li>Madgwick/Mahony (quaternions) para roll/pitch/yaw com magnetômetro</li>
</ul>
</li>



<li><strong>Calibração do magnetômetro</strong> (hard-iron/soft-iron) para yaw confiável.</li>
</ol>



<p class="wp-block-paragraph">A ideia é: se você pular a calibração e fusão, yaw vai “dançar”, gyro vai derivar e vibração vira um festival de falso-positivo.</p>



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



<h2 class="wp-block-heading">3) Base de firmware em C: leitura, escala e filtros</h2>



<p class="wp-block-paragraph">Abaixo vai um esqueleto que separa responsabilidades: driver (registradores) e processamento (algoritmos). Eu vou deixar as funções <code>i2c_read</code> e <code>i2c_write</code> como “portáveis” (você adapta para STM32 HAL, ESP-IDF, baremetal etc.).</p>



<h3 class="wp-block-heading">3.1 Tipos e constantes úteis</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;stdint.h>
#include &lt;stdbool.h>
#include &lt;math.h>

/* Endereços I2C típicos do MPU9250: 0x68 (AD0=0) ou 0x69 (AD0=1). */
#define MPU9250_ADDR 0x68

/* Magnetômetro AK8963 no pass-through/bypass: 0x0C */
#define AK8963_ADDR  0x0C  /* citado na especificação do MPU9250 :contentReference&#91;oaicite:2&#93;{index=2} */

/* Exemplo de faixas (você escolhe conforme aplicação) */
typedef enum {
  ACC_FS_2G = 0,
  ACC_FS_4G,
  ACC_FS_8G,
  ACC_FS_16G
} acc_fs_t;

typedef enum {
  GYR_FS_250DPS = 0,
  GYR_FS_500DPS,
  GYR_FS_1000DPS,
  GYR_FS_2000DPS
} gyr_fs_t;

typedef struct {
  float ax, ay, az;   /* m/s^2 */
  float gx, gy, gz;   /* rad/s */
  float mx, my, mz;   /* uT (ou unidade relativa, depende do seu fator) */
  float temp_c;
  uint32_t t_us;      /* timestamp (opcional) */
} imu_sample_t;

typedef struct {
  /* Bias estimado (offset) */
  float acc_bias&#91;3&#93;;
  float gyr_bias&#91;3&#93;;
  float mag_bias&#91;3&#93;;

  /* Matriz 3x3 de correção do magnetômetro (soft-iron) */
  float mag_softiron&#91;3&#93;&#91;3&#93;;

  /* Fatores de escala em unidades físicas por LSB */
  float acc_lsb_to_mps2;
  float gyr_lsb_to_rads;
  float mag_lsb_to_uT; /* depende do modo do AK8963 e do datasheet dele */
} imu_cal_t;
</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">stdbool</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">math</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">/* Endereços I2C típicos do MPU9250: 0x68 (AD0=0) ou 0x69 (AD0=1). */</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">MPU9250_ADDR</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x68</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/* Magnetômetro AK8963 no pass-through/bypass: 0x0C */</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">AK8963_ADDR</span><span style="color: #D8DEE9FF">  </span><span style="color: #B48EAD">0x0C</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* citado na especificação do MPU9250 :contentReference&#91;oaicite:2&#93;{index=2} */</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/* Exemplo de faixas (você escolhe conforme aplicação) */</span></span>
<span class="line"><span style="color: #D8DEE9">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">enum</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">ACC_FS_2G</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: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">ACC_FS_4G</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">ACC_FS_8G</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">ACC_FS_16G</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc_fs_t</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">enum</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">GYR_FS_250DPS</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: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">GYR_FS_500DPS</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">GYR_FS_1000DPS</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">GYR_FS_2000DPS</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gyr_fs_t</span><span style="color: #81A1C1">;</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">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ax</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ay</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">az</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">   </span><span style="color: #616E88">/* m/s^2 */</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">gx</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gy</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gz</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">   </span><span style="color: #616E88">/* rad/s */</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">mx</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">my</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mz</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">   </span><span style="color: #616E88">/* uT (ou unidade relativa, depende do seu fator) */</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">temp_c</span><span style="color: #81A1C1">;</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">t_us</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">      </span><span style="color: #616E88">/* timestamp (opcional) */</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">imu_sample_t</span><span style="color: #81A1C1">;</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: #616E88">/* Bias estimado (offset) */</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">acc_bias</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</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">gyr_bias</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</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">mag_bias</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* Matriz 3x3 de correção do magnetômetro (soft-iron) */</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">mag_softiron</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* Fatores de escala em unidades físicas por LSB */</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">acc_lsb_to_mps2</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">gyr_lsb_to_rads</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">mag_lsb_to_uT</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">/* depende do modo do AK8963 e do datasheet dele */</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">imu_cal_t</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">3.2 Funções “portáveis” de barramento</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>/**
 * @brief Lê N bytes de um registrador.
 * @return true se sucesso.
 */
bool i2c_read(uint8_t dev, uint8_t reg, uint8_t *buf, uint16_t len);

/**
 * @brief Escreve 1 byte em um registrador.
 */
bool i2c_write(uint8_t dev, uint8_t reg, uint8_t value);
</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: #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"> Lê N bytes de um registrador.</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"> true se sucesso.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">bool</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i2c_read</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dev</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">reg</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">buf</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">len</span><span style="color: #D8DEE9FF">)</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"> Escreve 1 byte em um registrador.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">bool</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i2c_write</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dev</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">reg</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">value</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



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



<h2 class="wp-block-heading">4) Inicialização prática: o mínimo que evita dor de cabeça</h2>



<p class="wp-block-paragraph">Aqui entram três pontos: clock, ranges e habilitar leitura coerente. Para o magnetômetro via pass-through, você também precisa habilitar o bypass no MPU e configurar o AK8963. O documento de especificação descreve o “pass-through mode” justamente para permitir que o host acesse o AK8963 diretamente. (<a href="https://invensense.tdk.com/wp-content/uploads/2015/02/PS-MPU-9250A-01-v1.1.pdf?utm_source=chatgpt.com">TDK InvenSense</a>)</p>



<p class="wp-block-paragraph"><strong>Observação importante:</strong> os endereços de registradores (PWR_MGMT_1, INT_PIN_CFG etc.) ficam no register map do MPU9250. Se você já usa uma lib, ótimo; se não, use o RM oficial para confirmar endereços e bits. (<a href="https://invensense.tdk.com/wp-content/uploads/2015/02/RM-MPU-9250A-00-v1.6.pdf?utm_source=chatgpt.com">TDK InvenSense</a>)</p>



<p class="wp-block-paragraph">Exemplo (conceitual, com registradores “nomeados” via defines que você tiraria do RM):</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>/* Estes defines você deve mapear pelo Register Map oficial. :contentReference&#91;oaicite:5&#93;{index=5} */
#define REG_PWR_MGMT_1     0x6B
#define REG_PWR_MGMT_2     0x6C
#define REG_CONFIG         0x1A
#define REG_GYRO_CONFIG    0x1B
#define REG_ACCEL_CONFIG   0x1C
#define REG_ACCEL_CONFIG2  0x1D
#define REG_INT_PIN_CFG    0x37
#define REG_USER_CTRL      0x6A

/* Bits típicos: consultar RM */
#define BIT_BYPASS_EN      0x02  /* INT_PIN_CFG */
#define BIT_I2C_MST_EN     0x20  /* USER_CTRL (se usar master interno) */

static bool mpu9250_init_basic(acc_fs_t acc_fs, gyr_fs_t gyr_fs)
{
  /* 1) Acorda o chip e seleciona clock (ex.: PLL) */
  if (!i2c_write(MPU9250_ADDR, REG_PWR_MGMT_1, 0x01)) return false;

  /* 2) Configura filtros digitais (DLPF) conforme seu fs e ruído */
  if (!i2c_write(MPU9250_ADDR, REG_CONFIG, 0x03)) return false;

  /* 3) Faixa do giroscópio */
  uint8_t gcfg = (uint8_t)(gyr_fs &lt;&lt; 3);
  if (!i2c_write(MPU9250_ADDR, REG_GYRO_CONFIG, gcfg)) return false;

  /* 4) Faixa do acelerômetro */
  uint8_t acfg = (uint8_t)(acc_fs &lt;&lt; 3);
  if (!i2c_write(MPU9250_ADDR, REG_ACCEL_CONFIG, acfg)) return false;

  /* 5) Config do accel DLPF */
  if (!i2c_write(MPU9250_ADDR, REG_ACCEL_CONFIG2, 0x03)) return false;

  return true;
}

/* Habilita pass-through para acessar AK8963 direto no I2C (0x0C). :contentReference&#91;oaicite:6&#93;{index=6} */
static bool mpu9250_enable_mag_passthrough(void)
{
  /* Desabilita master interno (se estiver ligado) e ativa bypass */
  if (!i2c_write(MPU9250_ADDR, REG_USER_CTRL, 0x00)) return false;
  if (!i2c_write(MPU9250_ADDR, REG_INT_PIN_CFG, BIT_BYPASS_EN)) return false;
  return true;
}
</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: #616E88">/* Estes defines você deve mapear pelo Register Map oficial. :contentReference&#91;oaicite:5&#93;{index=5} */</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">REG_PWR_MGMT_1</span><span style="color: #D8DEE9FF">     </span><span style="color: #B48EAD">0x6B</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">REG_PWR_MGMT_2</span><span style="color: #D8DEE9FF">     </span><span style="color: #B48EAD">0x6C</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">REG_CONFIG</span><span style="color: #D8DEE9FF">         </span><span style="color: #B48EAD">0x1A</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">REG_GYRO_CONFIG</span><span style="color: #D8DEE9FF">    </span><span style="color: #B48EAD">0x1B</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">REG_ACCEL_CONFIG</span><span style="color: #D8DEE9FF">   </span><span style="color: #B48EAD">0x1C</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">REG_ACCEL_CONFIG2</span><span style="color: #D8DEE9FF">  </span><span style="color: #B48EAD">0x1D</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">REG_INT_PIN_CFG</span><span style="color: #D8DEE9FF">    </span><span style="color: #B48EAD">0x37</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">REG_USER_CTRL</span><span style="color: #D8DEE9FF">      </span><span style="color: #B48EAD">0x6A</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/* Bits típicos: consultar RM */</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">BIT_BYPASS_EN</span><span style="color: #D8DEE9FF">      </span><span style="color: #B48EAD">0x02</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* INT_PIN_CFG */</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">BIT_I2C_MST_EN</span><span style="color: #D8DEE9FF">     </span><span style="color: #B48EAD">0x20</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* USER_CTRL (se usar master interno) */</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">bool</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mpu9250_init_basic</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">acc_fs_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc_fs</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gyr_fs_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gyr_fs</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: #616E88">/* 1) Acorda o chip e seleciona clock (ex.: PLL) */</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">i2c_write</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MPU9250_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">REG_PWR_MGMT_1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x01</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* 2) Configura filtros digitais (DLPF) conforme seu fs e ruído */</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">i2c_write</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MPU9250_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">REG_CONFIG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x03</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* 3) Faixa do giroscópio */</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gcfg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF">)(</span><span style="color: #D8DEE9">gyr_fs</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">i2c_write</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MPU9250_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">REG_GYRO_CONFIG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gcfg</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* 4) Faixa do acelerômetro */</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acfg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF">)(</span><span style="color: #D8DEE9">acc_fs</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">i2c_write</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MPU9250_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">REG_ACCEL_CONFIG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acfg</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* 5) Config do accel DLPF */</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">i2c_write</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MPU9250_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">REG_ACCEL_CONFIG2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x03</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</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: #81A1C1">true;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/* Habilita pass-through para acessar AK8963 direto no I2C (0x0C). :contentReference&#91;oaicite:6&#93;{index=6} */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">bool</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mpu9250_enable_mag_passthrough</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: #616E88">/* Desabilita master interno (se estiver ligado) e ativa bypass */</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">i2c_write</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MPU9250_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">REG_USER_CTRL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x00</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">i2c_write</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MPU9250_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">REG_INT_PIN_CFG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">BIT_BYPASS_EN</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true;</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">5) Aquisição coerente: burst read e conversão para unidades físicas</h2>



<p class="wp-block-paragraph">A leitura ideal é em “bloco”, porque isso reduz a chance de pegar metade do sample antigo e metade do novo (especialmente quando você lê eixos separados).</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>#define REG_ACCEL_XOUT_H 0x3B  /* base do bloco accel/temp/gyro no RM */

/* Layout típico do burst: accel(6), temp(2), gyro(6) => 14 bytes */
static bool mpu9250_read_accel_gyro_raw(int16_t acc&#91;3&#93;, int16_t gyr&#91;3&#93;, int16_t *temp)
{
  uint8_t buf&#91;14&#93;;
  if (!i2c_read(MPU9250_ADDR, REG_ACCEL_XOUT_H, buf, 14)) return false;

  acc&#91;0&#93; = (int16_t)((buf&#91;0&#93; &lt;&lt; 8) | buf&#91;1&#93;);
  acc&#91;1&#93; = (int16_t)((buf&#91;2&#93; &lt;&lt; 8) | buf&#91;3&#93;);
  acc&#91;2&#93; = (int16_t)((buf&#91;4&#93; &lt;&lt; 8) | buf&#91;5&#93;);

  *temp = (int16_t)((buf&#91;6&#93; &lt;&lt; 8) | buf&#91;7&#93;);

  gyr&#91;0&#93; = (int16_t)((buf&#91;8&#93;  &lt;&lt; 8) | buf&#91;9&#93;);
  gyr&#91;1&#93; = (int16_t)((buf&#91;10&#93; &lt;&lt; 8) | buf&#91;11&#93;);
  gyr&#91;2&#93; = (int16_t)((buf&#91;12&#93; &lt;&lt; 8) | buf&#91;13&#93;);

  return true;
}

/* Converte valores crus para físico, já aplicando bias */
static void imu_convert_apply_cal(
  const int16_t acc_raw&#91;3&#93;,
  const int16_t gyr_raw&#91;3&#93;,
  const imu_cal_t *cal,
  float acc_mps2&#91;3&#93;,
  float gyr_rads&#91;3&#93;
){
  /* LSB -> unidade e remove bias */
  for (int i = 0; i &lt; 3; i++) {
    acc_mps2&#91;i&#93; = (float)acc_raw&#91;i&#93; * cal->acc_lsb_to_mps2 - cal->acc_bias&#91;i&#93;;
    gyr_rads&#91;i&#93; = (float)gyr_raw&#91;i&#93; * cal->gyr_lsb_to_rads - cal->gyr_bias&#91;i&#93;;
  }
}
</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">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">REG_ACCEL_XOUT_H</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x3B</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* base do bloco accel/temp/gyro no RM */</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/* Layout típico do burst: accel(6), temp(2), gyro(6) =&gt; 14 bytes */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">bool</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mpu9250_read_accel_gyro_raw</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gyr</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">temp</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">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">14</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">i2c_read</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MPU9250_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">REG_ACCEL_XOUT_H</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">14</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF">)((</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF">)((</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF">)((</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">4</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">5</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">temp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF">)((</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">6</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">7</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">gyr</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF">)((</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">&#93;  </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">9</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">gyr</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF">)((</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">10</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">11</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">gyr</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF">)((</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">12</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">13</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</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: #81A1C1">true;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/* Converte valores crus para físico, já aplicando bias */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">imu_convert_apply_cal</span><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc_raw</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gyr_raw</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">imu_cal_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">cal</span><span style="color: #ECEFF4">,</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">acc_mps2</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</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">gyr_rads</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</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: #616E88">/* LSB -&gt; unidade e remove bias */</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">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: #B48EAD">3</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">acc_mps2</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">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">acc_raw</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">cal</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">acc_lsb_to_mps2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cal</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">acc_bias</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>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">gyr_rads</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">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">gyr_raw</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">cal</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">gyr_lsb_to_rads</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cal</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">gyr_bias</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>
<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>



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



<h2 class="wp-block-heading">6) Calibração essencial: bias do giroscópio e “leveling” do acelerômetro</h2>



<h3 class="wp-block-heading">6.1 Bias do giroscópio (parado)</h3>



<p class="wp-block-paragraph">O gyro sempre tem um offset. Se você integrar gyro “cru”, a orientação deriva mesmo com o sensor parado. O método mais robusto para começar é: durante 2–5 s com o dispositivo imóvel, calcule a média de Gx,Gy,Gz e chame isso de bias.</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>static void calibrate_gyro_bias(imu_cal_t *cal, int samples, float dt_s)
{
  (void)dt_s; /* aqui dt não é necessário, mas você pode checar estabilidade */
  double sum&#91;3&#93; = {0,0,0};

  for (int n = 0; n &lt; samples; n++) {
    int16_t acc_raw&#91;3&#93;, gyr_raw&#91;3&#93;, temp_raw;
    if (!mpu9250_read_accel_gyro_raw(acc_raw, gyr_raw, &amp;temp_raw)) continue;

    sum&#91;0&#93; += (double)gyr_raw&#91;0&#93;;
    sum&#91;1&#93; += (double)gyr_raw&#91;1&#93;;
    sum&#91;2&#93; += (double)gyr_raw&#91;2&#93;;
  }

  cal->gyr_bias&#91;0&#93; = (float)(sum&#91;0&#93;/samples) * cal->gyr_lsb_to_rads;
  cal->gyr_bias&#91;1&#93; = (float)(sum&#91;1&#93;/samples) * cal->gyr_lsb_to_rads;
  cal->gyr_bias&#91;2&#93; = (float)(sum&#91;2&#93;/samples) * cal->gyr_lsb_to_rads;
}
</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: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">calibrate_gyro_bias</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">imu_cal_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">cal</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">samples</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">dt_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: #81A1C1">void</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">dt_s</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">/* aqui dt não é necessário, mas você pode checar estabilidade */</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sum</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #B48EAD">0</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: #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: #D8DEE9">samples</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: #D8DEE9FF">    </span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc_raw</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gyr_raw</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">temp_raw</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">mpu9250_read_accel_gyro_raw</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">acc_raw</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gyr_raw</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">temp_raw</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">continue;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">sum</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">double</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">gyr_raw</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">sum</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">double</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">gyr_raw</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">sum</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">double</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">gyr_raw</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</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>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">cal</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">gyr_bias</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93; </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">sum</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">samples</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cal</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">gyr_lsb_to_rads</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">cal</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">gyr_bias</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93; </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">sum</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">samples</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cal</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">gyr_lsb_to_rads</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">cal</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">gyr_bias</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93; </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">sum</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">samples</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cal</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">gyr_lsb_to_rads</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>


<div class="wp-block-image">
<figure class="alignleft size-full"><img decoding="async" width="454" height="421" src="https://mcu.tec.br/wp-content/uploads/2026/02/image-35.png" alt="" class="wp-image-1340" srcset="https://mcu.tec.br/wp-content/uploads/2026/02/image-35.png 454w, https://mcu.tec.br/wp-content/uploads/2026/02/image-35-300x278.png 300w" sizes="(max-width: 454px) 100vw, 454px" /></figure>
</div>


<p class="wp-block-paragraph">Para o acelerômetro, o bias depende muito de como você define “referência”: em repouso, ele mede gravidade projetada no frame do sensor. Um jeito prático: faça uma calibração simples em repouso com o sensor em uma orientação conhecida (por exemplo, Z apontando para cima), e ajuste apenas o eixo da gravidade. Para calibração “de verdade”, você faz a técnica de 6 faces (±X, ±Y, ±Z), mas isso já vira um procedimento de bancada.</p>



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



<h2 class="wp-block-heading">7) Filtro passa-baixa simples (IIR) e por que ele é suficiente em muita coisa</h2>



<p class="wp-block-paragraph">Em IMU, um filtro IIR de 1ª ordem é o “feijão com arroz” porque custa quase nada e reduz ruído.</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>typedef struct {
  float y&#91;3&#93;;
  float alpha; /* 0..1  (quanto menor, mais filtrado) */
} lpf1_t;

static void lpf1_init(lpf1_t *f, float alpha)
{
  f->alpha = alpha;
  f->y&#91;0&#93; = f->y&#91;1&#93; = f->y&#91;2&#93; = 0.0f;
}

static void lpf1_update(lpf1_t *f, const float x&#91;3&#93;, float out&#91;3&#93;)
{
  for (int i = 0; i &lt; 3; i++) {
    f->y&#91;i&#93; = f->alpha * f->y&#91;i&#93; + (1.0f - f->alpha) * x&#91;i&#93;;
    out&#91;i&#93; = f->y&#91;i&#93;;
  }
}
</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: #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">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</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">alpha</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">/* 0..1  (quanto menor, mais filtrado) */</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">lpf1_t</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">lpf1_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">lpf1_t</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">alpha</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">alpha</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">alpha</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">y</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93; </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">y</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93; </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">y</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93; </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: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">lpf1_update</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">lpf1_t</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">const</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">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</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">out</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;)</span></span>
<span class="line"><span style="color: #ECEFF4">{</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">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: #B48EAD">3</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">y</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">alpha</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">y</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"> (1</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">alpha</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">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">out</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">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">y</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>
<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">Escolha de <code>alpha</code>: se seu loop é 200 Hz, <code>alpha</code> entre 0,85 e 0,98 costuma funcionar bem para suavizar sem “matar” dinâmica. Para vibração e manutenção preditiva, você pode filtrar menos (alpha menor) e trabalhar com FFT/PSD em janelas curtas.</p>



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



<h2 class="wp-block-heading">8) Orientação “refinada”: Complementary Filter (rápido e bom) e caminho para quaternions</h2>



<h3 class="wp-block-heading">8.1 Roll e Pitch com Complementary Filter</h3>



<p class="wp-block-paragraph">O acelerômetro dá uma boa referência de inclinação (porque a gravidade aponta “para baixo”), mas é ruidoso e sofre com acelerações lineares. O gyro é suave e rápido, mas deriva. O filtro complementar mistura os dois: <strong>gyro domina no curto prazo, accel corrige no longo prazo</strong>.</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>typedef struct {
  float roll;   /* rad */
  float pitch;  /* rad */
  float alpha;  /* ex.: 0.98 */
} comp_t;

static void comp_init(comp_t *c, float alpha)
{
  c->roll = 0.0f;
  c->pitch = 0.0f;
  c->alpha = alpha;
}

static void comp_update(comp_t *c, const float acc&#91;3&#93;, const float gyr&#91;3&#93;, float dt)
{
  /* roll_acc = atan2(Ay, Az) ; pitch_acc = atan2(-Ax, sqrt(Ay^2+Az^2)) */
  float roll_acc  = atan2f(acc&#91;1&#93;, acc&#91;2&#93;);
  float pitch_acc = atan2f(-acc&#91;0&#93;, sqrtf(acc&#91;1&#93;*acc&#91;1&#93; + acc&#91;2&#93;*acc&#91;2&#93;));

  /* Integra gyro (assumindo gyr[] em rad/s) */
  float roll_g  = c->roll  + gyr&#91;0&#93;*dt;
  float pitch_g = c->pitch + gyr&#91;1&#93;*dt;

  /* Mistura */
  c->roll  = c->alpha*roll_g  + (1.0f - c->alpha)*roll_acc;
  c->pitch = c->alpha*pitch_g + (1.0f - c->alpha)*pitch_acc;
}
</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: #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">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">roll</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">   </span><span style="color: #616E88">/* rad */</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">pitch</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* rad */</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">alpha</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* ex.: 0.98 */</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">comp_t</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">comp_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">comp_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">c</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">alpha</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">c</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">roll</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">c</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">pitch</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">c</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">alpha</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">alpha</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: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">comp_update</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">comp_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">c</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gyr</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</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">dt</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: #616E88">/* roll_acc = atan2(Ay, Az) ; pitch_acc = atan2(-Ax, sqrt(Ay^2+Az^2)) */</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">roll_acc</span><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">atan2f</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93;)</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">pitch_acc</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">atan2f</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">acc</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: #88C0D0">sqrtf</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93;))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* Integra gyro (assumindo gyr[] em rad/s) */</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">roll_g</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">-&gt;</span><span style="color: #D8DEE9">roll</span><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gyr</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">dt</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">pitch_g</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">-&gt;</span><span style="color: #D8DEE9">pitch</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gyr</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">dt</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* Mistura */</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">c</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">roll</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">-&gt;</span><span style="color: #D8DEE9">alpha</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">roll_g</span><span style="color: #D8DEE9FF">  </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: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">c</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">alpha</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">roll_acc</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">c</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">pitch</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">-&gt;</span><span style="color: #D8DEE9">alpha</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pitch_g</span><span style="color: #D8DEE9FF"> </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: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">c</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">alpha</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pitch_acc</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>


<div class="wp-block-image">
<figure class="alignright size-full"><img loading="lazy" decoding="async" width="441" height="421" src="https://mcu.tec.br/wp-content/uploads/2026/02/image-36.png" alt="" class="wp-image-1341" srcset="https://mcu.tec.br/wp-content/uploads/2026/02/image-36.png 441w, https://mcu.tec.br/wp-content/uploads/2026/02/image-36-300x286.png 300w" sizes="(max-width: 441px) 100vw, 441px" /></figure>
</div>


<p class="wp-block-paragraph">Isso já resolve uma quantidade enorme de aplicações: estabilização simples, detecção de inclinação, controle de plataforma, etc. Mas ainda falta yaw (rumo).</p>



<h3 class="wp-block-heading">8.2 Yaw e magnetômetro: onde quase todo mundo sofre</h3>



<p class="wp-block-paragraph">Yaw com magnetômetro só fica bom se você fizer duas coisas:</p>



<ol class="wp-block-list">
<li><strong>Hard-iron</strong>: remover offset (a “nuvem” de pontos do mag não fica centrada no zero).</li>



<li><strong>Soft-iron</strong>: corrigir escala/rotação (a nuvem vira uma elipse em vez de esfera).</li>
</ol>



<p class="wp-block-paragraph">O procedimento prático é coletar dados do magnetômetro girando o dispositivo em várias orientações, ajustar uma elipse e transformar para esfera. Em firmware embarcado simples, você pode aplicar uma aproximação: bias = (max+min)/2 por eixo e escala = (max-min)/2 para normalizar. Não é perfeito, mas melhora muito.</p>



<p class="wp-block-paragraph">Aplicação de correção (bias + matriz soft-iron):</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>static void mag_apply_cal(const imu_cal_t *cal, const float m_raw&#91;3&#93;, float m_corr&#91;3&#93;)
{
  float v&#91;3&#93; = {
    m_raw&#91;0&#93; - cal->mag_bias&#91;0&#93;,
    m_raw&#91;1&#93; - cal->mag_bias&#91;1&#93;,
    m_raw&#91;2&#93; - cal->mag_bias&#91;2&#93;
  };

  /* m_corr = SoftIron * v */
  for (int r = 0; r &lt; 3; r++) {
    m_corr&#91;r&#93; =
      cal->mag_softiron&#91;r&#93;&#91;0&#93;*v&#91;0&#93; +
      cal->mag_softiron&#91;r&#93;&#91;1&#93;*v&#91;1&#93; +
      cal->mag_softiron&#91;r&#93;&#91;2&#93;*v&#91;2&#93;;
  }
}
</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: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mag_apply_cal</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">imu_cal_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">cal</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">m_raw</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</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">m_corr</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;)</span></span>
<span class="line"><span style="color: #ECEFF4">{</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">v</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    m_raw</span><span style="color: #88C0D0">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #88C0D0">&#93; - cal-&gt;mag_bias&#91;</span><span style="color: #B48EAD">0</span><span style="color: #88C0D0">&#93;,</span></span>
<span class="line"><span style="color: #88C0D0">    m_raw&#91;</span><span style="color: #B48EAD">1</span><span style="color: #88C0D0">&#93; - cal-&gt;mag_bias&#91;</span><span style="color: #B48EAD">1</span><span style="color: #88C0D0">&#93;,</span></span>
<span class="line"><span style="color: #88C0D0">    m_raw&#91;</span><span style="color: #B48EAD">2</span><span style="color: #88C0D0">&#93; - cal-&gt;mag_bias&#91;</span><span style="color: #B48EAD">2</span><span style="color: #88C0D0">&#93;</span></span>
<span class="line"><span style="color: #88C0D0">  };</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">  </span><span style="color: #616E88">/* m_corr = SoftIron * v */</span></span>
<span class="line"><span style="color: #88C0D0">  for (int r = 0; r &lt; 3; r++) {</span></span>
<span class="line"><span style="color: #88C0D0">    m_corr&#91;</span><span style="color: #D8DEE9">r</span><span style="color: #88C0D0">&#93; =</span></span>
<span class="line"><span style="color: #88C0D0">      cal-&gt;mag_softiron&#91;</span><span style="color: #D8DEE9">r</span><span style="color: #88C0D0">&#93;&#91;</span><span style="color: #B48EAD">0</span><span style="color: #88C0D0">&#93;*v&#91;</span><span style="color: #B48EAD">0</span><span style="color: #88C0D0">&#93; +</span></span>
<span class="line"><span style="color: #88C0D0">      cal-&gt;mag_softiron&#91;</span><span style="color: #D8DEE9">r</span><span style="color: #88C0D0">&#93;&#91;</span><span style="color: #B48EAD">1</span><span style="color: #88C0D0">&#93;*v&#91;</span><span style="color: #B48EAD">1</span><span style="color: #88C0D0">&#93; +</span></span>
<span class="line"><span style="color: #88C0D0">      cal-&gt;mag_softiron&#91;</span><span style="color: #D8DEE9">r</span><span style="color: #88C0D0">&#93;&#91;</span><span style="color: #B48EAD">2</span><span style="color: #88C0D0">&#93;*v&#91;</span><span style="color: #B48EAD">2</span><span style="color: #88C0D0">&#93;;</span></span>
<span class="line"><span style="color: #88C0D0">  }</span></span>
<span class="line"><span style="color: #88C0D0">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Depois disso, para obter yaw “tilt-compensated” (compensado por roll/pitch), você projeta o vetor magnético no plano horizontal do mundo (ou do corpo) usando a orientação atual. Se você já estiver em quaternions (Madgwick/Mahony), isso fica limpo. Se você estiver em roll/pitch, dá para fazer com trigonometria também, mas o ideal para robustez é migrar para quaternion.</p>



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



<h2 class="wp-block-heading">9) Leitura do magnetômetro (pass-through) e sincronismo</h2>



<p class="wp-block-paragraph">Quando você usa pass-through, o host lê o AK8963 em 0x0C diretamente, o que é exatamente o que o modo foi feito para permitir. (<a href="https://invensense.tdk.com/wp-content/uploads/2015/02/PS-MPU-9250A-01-v1.1.pdf?utm_source=chatgpt.com">TDK InvenSense</a>) A atenção aqui é garantir que você está lendo no ritmo correto e respeitando o “data ready” do magnetômetro (senão você repete amostras).</p>



<p class="wp-block-paragraph">Um pseudo-exemplo (registradores do AK8963 você pega do datasheet/register map do AK):</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>/* Endereços do AK8963 (exemplo comum) */
#define AK8963_ST1   0x02
#define AK8963_HXL   0x03
#define AK8963_CNTL1 0x0A

static bool ak8963_init_16bit_100hz(void)
{
  /* Exemplo: modo contínuo 100Hz e saída 16-bit (depende do CNTL1) */
  return i2c_write(AK8963_ADDR, AK8963_CNTL1, 0x16);
}

static bool ak8963_read_raw(int16_t mag&#91;3&#93;)
{
  uint8_t st1;
  if (!i2c_read(AK8963_ADDR, AK8963_ST1, &amp;st1, 1)) return false;

  if (!(st1 &amp; 0x01)) {
    /* dado ainda não pronto */
    return false;
  }

  uint8_t buf&#91;7&#93;;
  if (!i2c_read(AK8963_ADDR, AK8963_HXL, buf, 7)) return false;

  /* Atenção: AK8963 costuma ser little-endian */
  mag&#91;0&#93; = (int16_t)((buf&#91;1&#93; &lt;&lt; 8) | buf&#91;0&#93;);
  mag&#91;1&#93; = (int16_t)((buf&#91;3&#93; &lt;&lt; 8) | buf&#91;2&#93;);
  mag&#91;2&#93; = (int16_t)((buf&#91;5&#93; &lt;&lt; 8) | buf&#91;4&#93;);

  return true;
}
</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: #616E88">/* Endereços do AK8963 (exemplo comum) */</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">AK8963_ST1</span><span style="color: #D8DEE9FF">   </span><span style="color: #B48EAD">0x02</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">AK8963_HXL</span><span style="color: #D8DEE9FF">   </span><span style="color: #B48EAD">0x03</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">AK8963_CNTL1</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x0A</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">bool</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">ak8963_init_16bit_100hz</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: #616E88">/* Exemplo: modo contínuo 100Hz e saída 16-bit (depende do CNTL1) */</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">i2c_write</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">AK8963_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AK8963_CNTL1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x16</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: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">bool</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">ak8963_read_raw</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mag</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">st1</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">i2c_read</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">AK8963_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AK8963_ST1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">st1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</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: #81A1C1">!</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">st1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x01</span><span style="color: #D8DEE9FF">)) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #616E88">/* dado ainda não pronto */</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</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: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">7</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">i2c_read</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">AK8963_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AK8963_HXL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">7</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">/* Atenção: AK8963 costuma ser little-endian */</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">mag</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF">)((</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">mag</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF">)((</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">mag</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int16_t</span><span style="color: #D8DEE9FF">)((</span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">5</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">4</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</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: #81A1C1">true;</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">10) Nota de engenharia: NRND/EOL e o que fazer com isso</h2>



<p class="wp-block-paragraph">A TDK/InvenSense marca o MPU-9250 como fim de vida / não recomendado para novos projetos, então em produto final vale considerar sucessores (ex.: ICM-20948 e outros, dependendo do que você precisa). (<a href="https://invensense.tdk.com/products/motion-tracking/9-axis/mpu-9250/?utm_source=chatgpt.com">TDK InvenSense</a>) Para aprendizado, laboratório, hobby e protótipos, ele continua sendo excelente justamente porque existe muito material, exemplos e bibliotecas.</p>



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



<h1 class="wp-block-heading">Exemplos de gráficos em Python (no final, como referência)</h1>



<p class="wp-block-paragraph">Abaixo está um script <strong>didático</strong> que gera dados sintéticos (simulados) de aceleração, giroscópio, magnetômetro e também a orientação (Euler) usada como referência do exemplo. Ele serve para você enxergar a “cara” típica dos eixos e como eles variam no tempo. É útil para validar pipeline, filtros e escalas antes de plugar no hardware.</p><p>The post <a href="https://mcu.tec.br/algoritimos/posicionamento/mpu9250-como-usar-uma-imu-9-eixos-e-extrair-dados-realmente-uteis/">MPU9250: como usar uma IMU 9 eixos e extrair dados realmente “úteis”</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1338</post-id>	</item>
		<item>
		<title>Detecção de Assobio com Goertzel e Aprendizado Estatístico no RP2040</title>
		<link>https://mcu.tec.br/algoritimos/dsp/deteccao-de-assobio-com-goertzel-e-aprendizado-estatistico-no-rp2040/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=deteccao-de-assobio-com-goertzel-e-aprendizado-estatistico-no-rp2040</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Thu, 12 Feb 2026 11:36:50 +0000</pubDate>
				<category><![CDATA[DSP]]></category>
		<category><![CDATA[aprendizado estatístico]]></category>
		<category><![CDATA[BitDogLab]]></category>
		<category><![CDATA[classificação estatística]]></category>
		<category><![CDATA[detecção de assobio]]></category>
		<category><![CDATA[DSP embarcado]]></category>
		<category><![CDATA[firmware em c]]></category>
		<category><![CDATA[Goertzel]]></category>
		<category><![CDATA[processamento de áudio]]></category>
		<category><![CDATA[RP2040]]></category>
		<category><![CDATA[sistemas adaptativos]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1127</guid>

					<description><![CDATA[<p>Este artigo apresenta uma abordagem avançada e didática para detecção de assobio humano em microcontroladores RP2040 utilizando o algoritmo de Goertzel combinado com aprendizado estatístico adaptativo. Como continuação direta de uma série sobre DSP embarcado, o conteúdo mostra como transformar medições espectrais determinísticas em vetores de características robustos e como aplicar modelos estatísticos leves — baseados em média, variância e distância probabilística — para tomada de decisão confiável em ambientes variáveis. Toda a solução é implementada integralmente em linguagem C, sem bibliotecas externas, executando em tempo real na BitDogLab. O artigo é voltado a engenheiros, estudantes e desenvolvedores que desejam compreender, projetar e aplicar sistemas de processamento digital de sinais adaptativos em microcontroladores de recursos limitados.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/dsp/deteccao-de-assobio-com-goertzel-e-aprendizado-estatistico-no-rp2040/">Detecção de Assobio com Goertzel e Aprendizado Estatístico no RP2040</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Continuação da série: </p>



<ul class="wp-block-list">
<li><a href="https://mcu.tec.br/?p=1115" title="">Filtragem Digital, Cepstrum e Detecção Acústica em MCU</a></li>



<li><a href="https://mcu.tec.br/?p=1125" title="detecção de assobio">Detecção de Assobio Humano com o Algoritmo de Goertzel no RP2040</a></li>
</ul>


<div class="root-eb-toc-tjnly wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-tjnly "><div class="eb-toc-container eb-toc-tjnly  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. Introdu\u00e7\u00e3o \u2014 Por que combinar Goertzel com aprendizado estat\u00edstico?&quot;,&quot;text&quot;:&quot;1. Introdu\u00e7\u00e3o \u2014 Por que combinar Goertzel com aprendizado estat\u00edstico?&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.1 O papel do Goertzel nesta nova arquitetura&quot;,&quot;text&quot;:&quot;1.1 O papel do Goertzel nesta nova arquitetura&quot;,&quot;link&quot;:&quot;11-o-papel-do-goertzel-nesta-nova-arquitetura&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.2 O que entendemos aqui por \u201caprendizado estat\u00edstico\u201d&quot;,&quot;text&quot;:&quot;1.2 O que entendemos aqui por \u201caprendizado estat\u00edstico\u201d&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.3 Por que limiares fixos falham em campo&quot;,&quot;text&quot;:&quot;1.3 Por que limiares fixos falham em campo&quot;,&quot;link&quot;:&quot;13-por-que-limiares-fixos-falham-em-campo&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.4 Vis\u00e3o geral da nova arquitetura&quot;,&quot;text&quot;:&quot;1.4 Vis\u00e3o geral da nova arquitetura&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;1.5 O que voc\u00ea ter\u00e1 ao final deste artigo&quot;,&quot;text&quot;:&quot;1.5 O que voc\u00ea ter\u00e1 ao final deste artigo&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;2 \u2014 Do sinal ao vetor de caracter\u00edsticas: extraindo features estat\u00edsticas a partir do Goertzel&quot;,&quot;text&quot;:&quot;2 \u2014 Do sinal ao vetor de caracter\u00edsticas: extraindo features estat\u00edsticas a partir do Goertzel&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.1 Por que \u201cfeatures\u201d s\u00e3o mais importantes que o algoritmo de decis\u00e3o&quot;,&quot;text&quot;:&quot;2.1 Por que \u201cfeatures\u201d s\u00e3o mais importantes que o algoritmo de decis\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.2 O que N\u00c3O usar como feature (e por qu\u00ea)&quot;,&quot;text&quot;:&quot;2.2 O que N\u00c3O usar como feature (e por qu\u00ea)&quot;,&quot;link&quot;:&quot;eb-table-content-8&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.3 Princ\u00edpio fundamental: normaliza\u00e7\u00e3o e rela\u00e7\u00f5es&quot;,&quot;text&quot;:&quot;2.3 Princ\u00edpio fundamental: normaliza\u00e7\u00e3o e rela\u00e7\u00f5es&quot;,&quot;link&quot;:&quot;eb-table-content-9&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.4 Feature 1 \u2014 Energia normalizada da fundamental&quot;,&quot;text&quot;:&quot;2.4 Feature 1 \u2014 Energia normalizada da fundamental&quot;,&quot;link&quot;:&quot;24-feature-1-energia-normalizada-da-fundamental&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.5 Feature 2 \u2014 Rela\u00e7\u00e3o do 2\u00ba harm\u00f4nico&quot;,&quot;text&quot;:&quot;2.5 Feature 2 \u2014 Rela\u00e7\u00e3o do 2\u00ba harm\u00f4nico&quot;,&quot;link&quot;:&quot;eb-table-content-11&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.6 Feature 3 \u2014 Rela\u00e7\u00e3o do 3\u00ba harm\u00f4nico (opcional, mas valiosa)&quot;,&quot;text&quot;:&quot;2.6 Feature 3 \u2014 Rela\u00e7\u00e3o do 3\u00ba harm\u00f4nico (opcional, mas valiosa)&quot;,&quot;link&quot;:&quot;eb-table-content-12&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.7 Feature 4 \u2014 Estabilidade temporal da frequ\u00eancia&quot;,&quot;text&quot;:&quot;2.7 Feature 4 \u2014 Estabilidade temporal da frequ\u00eancia&quot;,&quot;link&quot;:&quot;eb-table-content-13&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.8 Montando o vetor de caracter\u00edsticas&quot;,&quot;text&quot;:&quot;2.8 Montando o vetor de caracter\u00edsticas&quot;,&quot;link&quot;:&quot;eb-table-content-14&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.9 Feature engineering \u00e9 engenharia, n\u00e3o tentativa&quot;,&quot;text&quot;:&quot;2.9 Feature engineering \u00e9 engenharia, n\u00e3o tentativa&quot;,&quot;link&quot;:&quot;eb-table-content-15&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;3 \u2014 Modelo estat\u00edstico adaptativo: m\u00e9dia, vari\u00e2ncia e decis\u00e3o probabil\u00edstica (online, leve e interpret\u00e1vel)&quot;,&quot;text&quot;:&quot;3 \u2014 Modelo estat\u00edstico adaptativo: m\u00e9dia, vari\u00e2ncia e decis\u00e3o probabil\u00edstica (online, leve e interpret\u00e1vel)&quot;,&quot;link&quot;:&quot;eb-table-content-16&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.1 Princ\u00edpio do modelo: aprender o \u201cnormal\u201d e medir desvio&quot;,&quot;text&quot;:&quot;3.1 Princ\u00edpio do modelo: aprender o \u201cnormal\u201d e medir desvio&quot;,&quot;link&quot;:&quot;eb-table-content-17&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.2 Modelo estat\u00edstico por feature (independente)&quot;,&quot;text&quot;:&quot;3.2 Modelo estat\u00edstico por feature (independente)&quot;,&quot;link&quot;:&quot;eb-table-content-18&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.3 Atualiza\u00e7\u00e3o online da m\u00e9dia (EMA)&quot;,&quot;text&quot;:&quot;3.3 Atualiza\u00e7\u00e3o online da m\u00e9dia (EMA)&quot;,&quot;link&quot;:&quot;eb-table-content-19&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.4 Atualiza\u00e7\u00e3o online da vari\u00e2ncia (forma est\u00e1vel)&quot;,&quot;text&quot;:&quot;3.4 Atualiza\u00e7\u00e3o online da vari\u00e2ncia (forma est\u00e1vel)&quot;,&quot;link&quot;:&quot;eb-table-content-20&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.5 Inicializa\u00e7\u00e3o segura do modelo&quot;,&quot;text&quot;:&quot;3.5 Inicializa\u00e7\u00e3o segura do modelo&quot;,&quot;link&quot;:&quot;eb-table-content-21&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.6 Medida de desvio: Z-score por feature&quot;,&quot;text&quot;:&quot;3.6 Medida de desvio: Z-score por feature&quot;,&quot;link&quot;:&quot;36-medida-de-desvio-z-score-por-feature&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.7 Dist\u00e2ncia estat\u00edstica simplificada (score global)&quot;,&quot;text&quot;:&quot;3.7 Dist\u00e2ncia estat\u00edstica simplificada (score global)&quot;,&quot;link&quot;:&quot;eb-table-content-23&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.8 Regra de decis\u00e3o probabil\u00edstica simples&quot;,&quot;text&quot;:&quot;3.8 Regra de decis\u00e3o probabil\u00edstica simples&quot;,&quot;link&quot;:&quot;eb-table-content-24&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.9 Aprendizado controlado (n\u00e3o aprender ru\u00eddo)&quot;,&quot;text&quot;:&quot;3.9 Aprendizado controlado (n\u00e3o aprender ru\u00eddo)&quot;,&quot;link&quot;:&quot;eb-table-content-25&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.10 O que conquistamos at\u00e9 aqui&quot;,&quot;text&quot;:&quot;3.10 O que conquistamos at\u00e9 aqui&quot;,&quot;link&quot;:&quot;eb-table-content-26&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;4 \u2014 Integra\u00e7\u00e3o completa em tempo real: Goertzel + features + modelo estat\u00edstico + LED no RP2040&quot;,&quot;text&quot;:&quot;4 \u2014 Integra\u00e7\u00e3o completa em tempo real: Goertzel + features + modelo estat\u00edstico + LED no RP2040&quot;,&quot;link&quot;:&quot;eb-table-content-27&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.1 Vis\u00e3o geral do fluxo em tempo real&quot;,&quot;text&quot;:&quot;4.1 Vis\u00e3o geral do fluxo em tempo real&quot;,&quot;link&quot;:&quot;eb-table-content-28&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.2 Estruturas globais de estado&quot;,&quot;text&quot;:&quot;4.2 Estruturas globais de estado&quot;,&quot;link&quot;:&quot;42-estruturas-globais-de-estado&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.3 Constru\u00e7\u00e3o do vetor de features em tempo real&quot;,&quot;text&quot;:&quot;4.3 Constru\u00e7\u00e3o do vetor de features em tempo real&quot;,&quot;link&quot;:&quot;eb-table-content-30&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.4 Avalia\u00e7\u00e3o estat\u00edstica e decis\u00e3o&quot;,&quot;text&quot;:&quot;4.4 Avalia\u00e7\u00e3o estat\u00edstica e decis\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-31&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.5 Atualiza\u00e7\u00e3o do modelo (aprendizado online controlado)&quot;,&quot;text&quot;:&quot;4.5 Atualiza\u00e7\u00e3o do modelo (aprendizado online controlado)&quot;,&quot;link&quot;:&quot;eb-table-content-32&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.6 Acionamento do LED (sem l\u00f3gica escondida)&quot;,&quot;text&quot;:&quot;4.6 Acionamento do LED (sem l\u00f3gica escondida)&quot;,&quot;link&quot;:&quot;eb-table-content-33&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.7 Loop principal: simples, limpo e determin\u00edstico&quot;,&quot;text&quot;:&quot;4.7 Loop principal: simples, limpo e determin\u00edstico&quot;,&quot;link&quot;:&quot;eb-table-content-34&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.8 O que temos agora (antes do c\u00f3digo final)&quot;,&quot;text&quot;:&quot;4.8 O que temos agora (antes do c\u00f3digo final)&quot;,&quot;link&quot;:&quot;eb-table-content-35&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;5 \u2014 C\u00f3digo completo e funcional (Goertzel + aprendizado estat\u00edstico) para BitDogLab \/ RP2040&quot;,&quot;text&quot;:&quot;5 \u2014 C\u00f3digo completo e funcional (Goertzel + aprendizado estat\u00edstico) para BitDogLab \/ RP2040&quot;,&quot;link&quot;:&quot;eb-table-content-36&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;6 \u2014 Calibra\u00e7\u00e3o pr\u00e1tica, boas escolhas vs. m\u00e1s escolhas, compara\u00e7\u00e3o entre estrat\u00e9gias, encerramento e SEO&quot;,&quot;text&quot;:&quot;6 \u2014 Calibra\u00e7\u00e3o pr\u00e1tica, boas escolhas vs. m\u00e1s escolhas, compara\u00e7\u00e3o entre estrat\u00e9gias, encerramento e SEO&quot;,&quot;link&quot;:&quot;eb-table-content-37&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.1 Calibra\u00e7\u00e3o pr\u00e1tica do modelo estat\u00edstico (como fazer funcionar em campo)&quot;,&quot;text&quot;:&quot;6.1 Calibra\u00e7\u00e3o pr\u00e1tica do modelo estat\u00edstico (como fazer funcionar em campo)&quot;,&quot;link&quot;:&quot;eb-table-content-38&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.2 Boas escolhas vs. m\u00e1s escolhas (aprendizado estat\u00edstico em MCU)&quot;,&quot;text&quot;:&quot;6.2 Boas escolhas vs. m\u00e1s escolhas (aprendizado estat\u00edstico em MCU)&quot;,&quot;link&quot;:&quot;eb-table-content-39&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.3 Compara\u00e7\u00e3o final entre os tr\u00eas artigos da s\u00e9rie&quot;,&quot;text&quot;:&quot;6.3 Compara\u00e7\u00e3o final entre os tr\u00eas artigos da s\u00e9rie&quot;,&quot;link&quot;:&quot;eb-table-content-40&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.4 Encerramento conceitual&quot;,&quot;text&quot;:&quot;6.4 Encerramento conceitual&quot;,&quot;link&quot;:&quot;64-encerramento-conceitual&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;1. Introdu\u00e7\u00e3o \u2014 Por que combinar Goertzel com aprendizado estat\u00edstico?&quot;,&quot;value&quot;:&quot;1-introdu\u00e7\u00e3o-por-que-combinar-goertzel-com-aprendizado-estat\u00edstico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.1 O papel do Goertzel nesta nova arquitetura&quot;,&quot;value&quot;:&quot;11-o-papel-do-goertzel-nesta-nova-arquitetura&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.2 O que entendemos aqui por \u201caprendizado estat\u00edstico\u201d&quot;,&quot;value&quot;:&quot;12-o-que-entendemos-aqui-por-aprendizado-estat\u00edstico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.3 Por que limiares fixos falham em campo&quot;,&quot;value&quot;:&quot;13-por-que-limiares-fixos-falham-em-campo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.4 Vis\u00e3o geral da nova arquitetura&quot;,&quot;value&quot;:&quot;14-vis\u00e3o-geral-da-nova-arquitetura&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.5 O que voc\u00ea ter\u00e1 ao final deste artigo&quot;,&quot;value&quot;:&quot;15-o-que-voc\u00ea-ter\u00e1-ao-final-deste-artigo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2 \u2014 Do sinal ao vetor de caracter\u00edsticas: extraindo features estat\u00edsticas a partir do Goertzel&quot;,&quot;value&quot;:&quot;2-do-sinal-ao-vetor-de-caracter\u00edsticas-extraindo-features-estat\u00edsticas-a-partir-do-goertzel&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.1 Por que \u201cfeatures\u201d s\u00e3o mais importantes que o algoritmo de decis\u00e3o&quot;,&quot;value&quot;:&quot;21-por-que-features-s\u00e3o-mais-importantes-que-o-algoritmo-de-decis\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.2 O que N\u00c3O usar como feature (e por qu\u00ea)&quot;,&quot;value&quot;:&quot;22-o-que-n\u00e3o-usar-como-feature-e-por-qu\u00ea&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.3 Princ\u00edpio fundamental: normaliza\u00e7\u00e3o e rela\u00e7\u00f5es&quot;,&quot;value&quot;:&quot;23-princ\u00edpio-fundamental-normaliza\u00e7\u00e3o-e-rela\u00e7\u00f5es&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.4 Feature 1 \u2014 Energia normalizada da fundamental&quot;,&quot;value&quot;:&quot;24-feature-1-energia-normalizada-da-fundamental&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.5 Feature 2 \u2014 Rela\u00e7\u00e3o do 2\u00ba harm\u00f4nico&quot;,&quot;value&quot;:&quot;25-feature-2-rela\u00e7\u00e3o-do-2\u00ba-harm\u00f4nico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.6 Feature 3 \u2014 Rela\u00e7\u00e3o do 3\u00ba harm\u00f4nico (opcional, mas valiosa)&quot;,&quot;value&quot;:&quot;26-feature-3-rela\u00e7\u00e3o-do-3\u00ba-harm\u00f4nico-opcional-mas-valiosa&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.7 Feature 4 \u2014 Estabilidade temporal da frequ\u00eancia&quot;,&quot;value&quot;:&quot;27-feature-4-estabilidade-temporal-da-frequ\u00eancia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.8 Montando o vetor de caracter\u00edsticas&quot;,&quot;value&quot;:&quot;28-montando-o-vetor-de-caracter\u00edsticas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.9 Feature engineering \u00e9 engenharia, n\u00e3o tentativa&quot;,&quot;value&quot;:&quot;29-feature-engineering-\u00e9-engenharia-n\u00e3o-tentativa&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3 \u2014 Modelo estat\u00edstico adaptativo: m\u00e9dia, vari\u00e2ncia e decis\u00e3o probabil\u00edstica (online, leve e interpret\u00e1vel)&quot;,&quot;value&quot;:&quot;3-modelo-estat\u00edstico-adaptativo-m\u00e9dia-vari\u00e2ncia-e-decis\u00e3o-probabil\u00edstica-online-leve-e-interpret\u00e1vel&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.1 Princ\u00edpio do modelo: aprender o \u201cnormal\u201d e medir desvio&quot;,&quot;value&quot;:&quot;31-princ\u00edpio-do-modelo-aprender-o-normal-e-medir-desvio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.2 Modelo estat\u00edstico por feature (independente)&quot;,&quot;value&quot;:&quot;32-modelo-estat\u00edstico-por-feature-independente&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.3 Atualiza\u00e7\u00e3o online da m\u00e9dia (EMA)&quot;,&quot;value&quot;:&quot;33-atualiza\u00e7\u00e3o-online-da-m\u00e9dia-ema&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.4 Atualiza\u00e7\u00e3o online da vari\u00e2ncia (forma est\u00e1vel)&quot;,&quot;value&quot;:&quot;34-atualiza\u00e7\u00e3o-online-da-vari\u00e2ncia-forma-est\u00e1vel&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.5 Inicializa\u00e7\u00e3o segura do modelo&quot;,&quot;value&quot;:&quot;35-inicializa\u00e7\u00e3o-segura-do-modelo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.6 Medida de desvio: Z-score por feature&quot;,&quot;value&quot;:&quot;36-medida-de-desvio-z-score-por-feature&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.7 Dist\u00e2ncia estat\u00edstica simplificada (score global)&quot;,&quot;value&quot;:&quot;37-dist\u00e2ncia-estat\u00edstica-simplificada-score-global&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.8 Regra de decis\u00e3o probabil\u00edstica simples&quot;,&quot;value&quot;:&quot;38-regra-de-decis\u00e3o-probabil\u00edstica-simples&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.9 Aprendizado controlado (n\u00e3o aprender ru\u00eddo)&quot;,&quot;value&quot;:&quot;39-aprendizado-controlado-n\u00e3o-aprender-ru\u00eddo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.10 O que conquistamos at\u00e9 aqui&quot;,&quot;value&quot;:&quot;310-o-que-conquistamos-at\u00e9-aqui&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4 \u2014 Integra\u00e7\u00e3o completa em tempo real: Goertzel + features + modelo estat\u00edstico + LED no RP2040&quot;,&quot;value&quot;:&quot;4-integra\u00e7\u00e3o-completa-em-tempo-real-goertzel-features-modelo-estat\u00edstico-led-no-rp2040&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.1 Vis\u00e3o geral do fluxo em tempo real&quot;,&quot;value&quot;:&quot;41-vis\u00e3o-geral-do-fluxo-em-tempo-real&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.2 Estruturas globais de estado&quot;,&quot;value&quot;:&quot;42-estruturas-globais-de-estado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.3 Constru\u00e7\u00e3o do vetor de features em tempo real&quot;,&quot;value&quot;:&quot;43-constru\u00e7\u00e3o-do-vetor-de-features-em-tempo-real&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.4 Avalia\u00e7\u00e3o estat\u00edstica e decis\u00e3o&quot;,&quot;value&quot;:&quot;44-avalia\u00e7\u00e3o-estat\u00edstica-e-decis\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.5 Atualiza\u00e7\u00e3o do modelo (aprendizado online controlado)&quot;,&quot;value&quot;:&quot;45-atualiza\u00e7\u00e3o-do-modelo-aprendizado-online-controlado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.6 Acionamento do LED (sem l\u00f3gica escondida)&quot;,&quot;value&quot;:&quot;46-acionamento-do-led-sem-l\u00f3gica-escondida&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.7 Loop principal: simples, limpo e determin\u00edstico&quot;,&quot;value&quot;:&quot;47-loop-principal-simples-limpo-e-determin\u00edstico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.8 O que temos agora (antes do c\u00f3digo final)&quot;,&quot;value&quot;:&quot;48-o-que-temos-agora-antes-do-c\u00f3digo-final&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5 \u2014 C\u00f3digo completo e funcional (Goertzel + aprendizado estat\u00edstico) para BitDogLab \/ RP2040&quot;,&quot;value&quot;:&quot;5-c\u00f3digo-completo-e-funcional-goertzel-aprendizado-estat\u00edstico-para-bitdoglab-rp2040&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6 \u2014 Calibra\u00e7\u00e3o pr\u00e1tica, boas escolhas vs. m\u00e1s escolhas, compara\u00e7\u00e3o entre estrat\u00e9gias, encerramento e SEO&quot;,&quot;value&quot;:&quot;6-calibra\u00e7\u00e3o-pr\u00e1tica-boas-escolhas-vs-m\u00e1s-escolhas-compara\u00e7\u00e3o-entre-estrat\u00e9gias-encerramento-e-seo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.1 Calibra\u00e7\u00e3o pr\u00e1tica do modelo estat\u00edstico (como fazer funcionar em campo)&quot;,&quot;value&quot;:&quot;61-calibra\u00e7\u00e3o-pr\u00e1tica-do-modelo-estat\u00edstico-como-fazer-funcionar-em-campo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.2 Boas escolhas vs. m\u00e1s escolhas (aprendizado estat\u00edstico em MCU)&quot;,&quot;value&quot;:&quot;62-boas-escolhas-vs-m\u00e1s-escolhas-aprendizado-estat\u00edstico-em-mcu&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.3 Compara\u00e7\u00e3o final entre os tr\u00eas artigos da s\u00e9rie&quot;,&quot;value&quot;:&quot;63-compara\u00e7\u00e3o-final-entre-os-tr\u00eas-artigos-da-s\u00e9rie&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.4 Encerramento conceitual&quot;,&quot;value&quot;:&quot;64-encerramento-conceitual&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. Introdução — Por que combinar Goertzel com aprendizado estatístico?</a><li><a href="#11-o-papel-do-goertzel-nesta-nova-arquitetura">1.1 O papel do Goertzel nesta nova arquitetura</a><li><a href="#eb-table-content-2">1.2 O que entendemos aqui por “aprendizado estatístico”</a><li><a href="#13-por-que-limiares-fixos-falham-em-campo">1.3 Por que limiares fixos falham em campo</a><li><a href="#eb-table-content-4">1.4 Visão geral da nova arquitetura</a><li><a href="#eb-table-content-5">1.5 O que você terá ao final deste artigo</a><li><a href="#eb-table-content-6">2 — Do sinal ao vetor de características: extraindo features estatísticas a partir do Goertzel</a><ul class="eb-toc__list"><li><a href="#eb-table-content-7">2.1 Por que “features” são mais importantes que o algoritmo de decisão</a><li><a href="#eb-table-content-8">2.2 O que NÃO usar como feature (e por quê)</a><li><a href="#eb-table-content-9">2.3 Princípio fundamental: normalização e relações</a><li><a href="#24-feature-1-energia-normalizada-da-fundamental">2.4 Feature 1 — Energia normalizada da fundamental</a><li><a href="#eb-table-content-11">2.5 Feature 2 — Relação do 2º harmônico</a><li><a href="#eb-table-content-12">2.6 Feature 3 — Relação do 3º harmônico (opcional, mas valiosa)</a><li><a href="#eb-table-content-13">2.7 Feature 4 — Estabilidade temporal da frequência</a><li><a href="#eb-table-content-14">2.8 Montando o vetor de características</a><li><a href="#eb-table-content-15">2.9 Feature engineering é engenharia, não tentativa</a></li></ul><li><a href="#eb-table-content-16">3 — Modelo estatístico adaptativo: média, variância e decisão probabilística (online, leve e interpretável)</a><ul class="eb-toc__list"><li><a href="#eb-table-content-17">3.1 Princípio do modelo: aprender o “normal” e medir desvio</a><li><a href="#eb-table-content-18">3.2 Modelo estatístico por feature (independente)</a><li><a href="#eb-table-content-19">3.3 Atualização online da média (EMA)</a><li><a href="#eb-table-content-20">3.4 Atualização online da variância (forma estável)</a><li><a href="#eb-table-content-21">3.5 Inicialização segura do modelo</a><li><a href="#36-medida-de-desvio-z-score-por-feature">3.6 Medida de desvio: Z-score por feature</a><li><a href="#eb-table-content-23">3.7 Distância estatística simplificada (score global)</a><li><a href="#eb-table-content-24">3.8 Regra de decisão probabilística simples</a><li><a href="#eb-table-content-25">3.9 Aprendizado controlado (não aprender ruído)</a><li><a href="#eb-table-content-26">3.10 O que conquistamos até aqui</a></li></ul><li><a href="#eb-table-content-27">4 — Integração completa em tempo real: Goertzel + features + modelo estatístico + LED no RP2040</a><ul class="eb-toc__list"><li><a href="#eb-table-content-28">4.1 Visão geral do fluxo em tempo real</a><li><a href="#42-estruturas-globais-de-estado">4.2 Estruturas globais de estado</a><li><a href="#eb-table-content-30">4.3 Construção do vetor de features em tempo real</a><li><a href="#eb-table-content-31">4.4 Avaliação estatística e decisão</a><li><a href="#eb-table-content-32">4.5 Atualização do modelo (aprendizado online controlado)</a><li><a href="#eb-table-content-33">4.6 Acionamento do LED (sem lógica escondida)</a><li><a href="#eb-table-content-34">4.7 Loop principal: simples, limpo e determinístico</a><li><a href="#eb-table-content-35">4.8 O que temos agora (antes do código final)</a></li></ul><li><a href="#eb-table-content-36">5 — Código completo e funcional (Goertzel + aprendizado estatístico) para BitDogLab / RP2040</a><li><a href="#eb-table-content-37">6 — Calibração prática, boas escolhas vs. más escolhas, comparação entre estratégias, encerramento e SEO</a><ul class="eb-toc__list"><li><a href="#eb-table-content-38">6.1 Calibração prática do modelo estatístico (como fazer funcionar em campo)</a><li><a href="#eb-table-content-39">6.2 Boas escolhas vs. más escolhas (aprendizado estatístico em MCU)</a><li><a href="#eb-table-content-40">6.3 Comparação final entre os três artigos da série</a><li><a href="#64-encerramento-conceitual">6.4 Encerramento conceitual</a></li></ul></ul></div></div></div></div></div>


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



<h2 class="wp-block-heading">1. Introdução — Por que combinar Goertzel com aprendizado estatístico?</h2>



<p class="wp-block-paragraph">Nos dois artigos anteriores desta série, exploramos <strong>duas estratégias clássicas e complementares</strong> de processamento digital de sinais em microcontroladores:</p>



<ol class="wp-block-list">
<li><strong>Séries de Taylor + Cepstrum</strong> → análise estrutural e harmônica do sinal</li>



<li><strong>Algoritmo de Goertzel</strong> → detecção espectral dirigida e altamente eficiente</li>
</ol>



<p class="wp-block-paragraph">Ambas funcionam muito bem, mas compartilham uma característica importante:<br><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>a decisão final é baseada em limiares fixos</strong>.</p>



<p class="wp-block-paragraph">Neste terceiro artigo, damos um passo conceitual além, mantendo o Goertzel como <strong>extrator de características espectrais</strong>, mas substituindo o decisor rígido por um <strong>modelo de aprendizado estatístico leve</strong>, adequado a MCUs como o RP2040.</p>



<p class="wp-block-paragraph">O objetivo não é “colocar inteligência artificial por marketing”, mas sim responder a um problema real:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><em>Como tornar a detecção mais robusta quando o ambiente muda, o usuário muda ou o ruído não é previsível?</em></p>
</blockquote>



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



<h2 class="wp-block-heading">1.1 O papel do Goertzel nesta nova arquitetura</h2>



<p class="wp-block-paragraph">É importante deixar claro desde o início:</p>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Goertzel <strong>não será substituído</strong></li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Não vamos rodar FFT gigante</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Não vamos usar redes neurais profundas</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Goertzel continua sendo o <strong>sensor espectral</strong></li>
</ul>



<p class="wp-block-paragraph">Nesta arquitetura, o Goertzel atua como um <strong>extrator determinístico de características (features)</strong>:</p>



<ul class="wp-block-list">
<li>Energia na frequência fundamental</li>



<li>Relação entre harmônicos</li>



<li>Estabilidade espectral ao longo do tempo</li>
</ul>



<p class="wp-block-paragraph">Esses valores passam a ser <strong>dados de entrada</strong> para um bloco estatístico que decide se o padrão observado <strong>se parece ou não com um assobio humano real</strong>.</p>



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



<h2 class="wp-block-heading">1.2 O que entendemos aqui por “aprendizado estatístico”</h2>



<p class="wp-block-paragraph">Neste artigo, <strong>aprendizado estatístico não significa deep learning</strong>.</p>



<p class="wp-block-paragraph">Vamos trabalhar com modelos:</p>



<ul class="wp-block-list">
<li>Interpretáveis</li>



<li>Leves</li>



<li>Computacionalmente previsíveis</li>



<li>Treináveis com poucos dados</li>
</ul>



<p class="wp-block-paragraph">Exemplos que abordaremos ao longo do artigo:</p>



<ul class="wp-block-list">
<li>Média e variância adaptativas</li>



<li>Distância estatística (z-score, Mahalanobis simplificada)</li>



<li>Classificador linear simples</li>



<li>Modelo incremental (online learning)</li>
</ul>



<p class="wp-block-paragraph">Tudo isso é:</p>



<ul class="wp-block-list">
<li>Executável em ponto flutuante simples</li>



<li>Compatível com firmware bare-metal</li>



<li>Determinístico em tempo real</li>
</ul>



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



<h2 class="wp-block-heading">1.3 Por que limiares fixos falham em campo</h2>



<p class="wp-block-paragraph">Nos artigos anteriores, usamos decisões do tipo:</p>



<ul class="wp-block-list">
<li><code>score &gt; S_ON</code></li>



<li><code>score &lt; S_OFF</code></li>
</ul>



<p class="wp-block-paragraph">Isso funciona bem quando:</p>



<ul class="wp-block-list">
<li>O ambiente é estável</li>



<li>O microfone é sempre o mesmo</li>



<li>O usuário assobia sempre da mesma forma</li>
</ul>



<p class="wp-block-paragraph">Mas em campo real:</p>



<ul class="wp-block-list">
<li>Pessoas assobiam diferente</li>



<li>Distância ao microfone muda</li>



<li>Ruído de fundo varia</li>



<li>Ganho analógico muda com temperatura e alimentação</li>
</ul>



<p class="wp-block-paragraph">Resultado:<br><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>limiar bom hoje, ruim amanhã</strong>.</p>



<p class="wp-block-paragraph">O aprendizado estatístico resolve exatamente isso:</p>



<ul class="wp-block-list">
<li>Ele <strong>aprende o padrão típico</strong></li>



<li>Ele <strong>tolera variações naturais</strong></li>



<li>Ele <strong>se adapta lentamente ao ambiente</strong></li>
</ul>



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



<h2 class="wp-block-heading">1.4 Visão geral da nova arquitetura</h2>



<p class="wp-block-paragraph">A nova cadeia de processamento será:</p>



<pre class="wp-block-code"><code>ADC
 └── DC-block
     └── Frame (256 amostras)
         └── Goertzel (fundamental + harmônicos)
             └── Vetor de características
                 └── Modelo estatístico adaptativo
                     └── Decisão (assobio / não assobio)
                         └── LED / evento
</code></pre>



<p class="wp-block-paragraph">Comparando com o artigo anterior:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Artigo</th><th>Decisão</th></tr></thead><tbody><tr><td>Taylor + Cepstrum</td><td>Limiar estrutural</td></tr><tr><td>Goertzel clássico</td><td>Score com limiar</td></tr><tr><td><strong>Goertzel + Estatística</strong></td><td><strong>Classificação adaptativa</strong></td></tr></tbody></table></figure>



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



<h2 class="wp-block-heading">1.5 O que você terá ao final deste artigo</h2>



<p class="wp-block-paragraph">Ao final deste terceiro artigo da série, você terá:</p>



<ul class="wp-block-list">
<li>Um <strong>detector de assobio adaptativo</strong></li>



<li>Baseado em <strong>Goertzel + estatística</strong></li>



<li>Código <strong>100% em C</strong></li>



<li>Executando em <strong>tempo real no RP2040</strong></li>



<li>Sem dependência de bibliotecas externas</li>



<li>Com arquitetura reutilizável para:
<ul class="wp-block-list">
<li>Detecção de padrões acústicos</li>



<li>Sensores inteligentes</li>



<li>Interfaces por som</li>



<li>Pré-processamento para tinyML</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph">Mais importante:<br><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;" /> você entenderá <strong>como transformar DSP em dados</strong> e <strong>dados em decisão</strong>, de forma técnica.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/algoritimos/dsp/deteccao-de-assobio-com-goertzel-e-aprendizado-estatistico-no-rp2040/">Detecção de Assobio com Goertzel e Aprendizado Estatístico no RP2040</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1127</post-id>	</item>
		<item>
		<title>LPCC (Linear Prediction Cepstral Coefficients): Fundamentos, Algoritmos e Aplicações em Sistemas Embarcados</title>
		<link>https://mcu.tec.br/algoritimos/dsp/lpcc-linear-prediction-cepstral-coefficients-fundamentos-algoritmos-e-aplicacoes-em-sistemas-embarcados/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lpcc-linear-prediction-cepstral-coefficients-fundamentos-algoritmos-e-aplicacoes-em-sistemas-embarcados</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 30 Jan 2026 18:04:34 +0000</pubDate>
				<category><![CDATA[DSP]]></category>
		<category><![CDATA[algoritmo de Levinson-Durbin]]></category>
		<category><![CDATA[análise de sinais]]></category>
		<category><![CDATA[autocorrelação]]></category>
		<category><![CDATA[diagnóstico de falhas]]></category>
		<category><![CDATA[edge computing]]></category>
		<category><![CDATA[extração de características]]></category>
		<category><![CDATA[firmware DSP]]></category>
		<category><![CDATA[iot industrial]]></category>
		<category><![CDATA[Linear Prediction Cepstral Coefficients]]></category>
		<category><![CDATA[LPC]]></category>
		<category><![CDATA[LPCC]]></category>
		<category><![CDATA[MFCC vs LPCC]]></category>
		<category><![CDATA[predição linear]]></category>
		<category><![CDATA[processamento digital de sinais]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[vibroacústica]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1254</guid>

					<description><![CDATA[<p>Os coeficientes cepstrais por predição linear (LPCC) são uma técnica clássica e altamente eficiente para extração de características em sinais de fala, vibração e acústica industrial. Neste artigo, apresentamos uma explicação completa e didática sobre LPCC, partindo dos fundamentos da predição linear (LP), passando pela autocorrelação, equações de Yule-Walker, algoritmo de Levinson-Durbin e erro de predição, até a conversão de coeficientes LPC em LPCC. Todo o conteúdo é contextualizado para aplicações práticas em sistemas embarcados, edge computing, IoT e diagnóstico vibroacústico, com exemplos de implementação em linguagem C, sem dependência de MATLAB ou bibliotecas pesadas. Também é apresentada uma comparação técnica entre LPCC e MFCC, destacando diferenças conceituais, computacionais e de interpretabilidade. O artigo é indicado para engenheiros, estudantes e pesquisadores que buscam compreender não apenas como usar LPCC, mas por que essa técnica continua relevante em aplicações industriais, manutenção preditiva, detecção de anomalias e análise de sinais físicos em ambientes com recursos limitados.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/dsp/lpcc-linear-prediction-cepstral-coefficients-fundamentos-algoritmos-e-aplicacoes-em-sistemas-embarcados/">LPCC (Linear Prediction Cepstral Coefficients): Fundamentos, Algoritmos e Aplicações em Sistemas Embarcados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-8gar6 wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-8gar6 "><div class="eb-toc-container eb-toc-8gar6  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 LPC (Linear Predictive Coding)&quot;,&quot;text&quot;:&quot;1 \u2014 LPC (Linear Predictive Coding)&quot;,&quot;link&quot;:&quot;1-lpc-linear-predictive-coding&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que significa LPC&quot;,&quot;text&quot;:&quot;O que significa LPC&quot;,&quot;link&quot;:&quot;o-que-significa-lpc&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Intui\u00e7\u00e3o f\u00edsica e de sinal&quot;,&quot;text&quot;:&quot;Intui\u00e7\u00e3o f\u00edsica e de sinal&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Modelo matem\u00e1tico do LPC&quot;,&quot;text&quot;:&quot;Modelo matem\u00e1tico do LPC&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Por que o LPC \u00e9 importante para LPCC&quot;,&quot;text&quot;:&quot;Por que o LPC \u00e9 importante para LPCC&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Implementa\u00e7\u00e3o conceitual do LPC em C (vis\u00e3o geral)&quot;,&quot;text&quot;:&quot;Implementa\u00e7\u00e3o conceitual do LPC em C (vis\u00e3o geral)&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo em C \u2014 c\u00e1lculo da autocorrela\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Exemplo em C \u2014 c\u00e1lculo da autocorrela\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Observa\u00e7\u00f5es pr\u00e1ticas para sistemas embarcados&quot;,&quot;text&quot;:&quot;Observa\u00e7\u00f5es pr\u00e1ticas para sistemas embarcados&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;2 \u2014 LPCC (Linear Prediction Cepstral Coefficients)&quot;,&quot;text&quot;:&quot;2 \u2014 LPCC (Linear Prediction Cepstral Coefficients)&quot;,&quot;link&quot;:&quot;2-lpcc-linear-prediction-cepstral-coefficients&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que significa LPCC&quot;,&quot;text&quot;:&quot;O que significa LPCC&quot;,&quot;link&quot;:&quot;o-que-significa-lpcc&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que \u00e9 o dom\u00ednio cepstral (intui\u00e7\u00e3o)&quot;,&quot;text&quot;:&quot;O que \u00e9 o dom\u00ednio cepstral (intui\u00e7\u00e3o)&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Rela\u00e7\u00e3o matem\u00e1tica entre LPC e LPCC&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o matem\u00e1tica entre LPC e LPCC&quot;,&quot;link&quot;:&quot;eb-table-content-11&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Por que LPCC \u00e9 prefer\u00edvel ao LPC em Machine Learning&quot;,&quot;text&quot;:&quot;Por que LPCC \u00e9 prefer\u00edvel ao LPC em Machine Learning&quot;,&quot;link&quot;:&quot;eb-table-content-12&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Implementa\u00e7\u00e3o em C \u2014 LPC \u2192 LPCC&quot;,&quot;text&quot;:&quot;Implementa\u00e7\u00e3o em C \u2014 LPC \u2192 LPCC&quot;,&quot;link&quot;:&quot;eb-table-content-13&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Observa\u00e7\u00f5es importantes sobre o c\u00f3digo&quot;,&quot;text&quot;:&quot;Observa\u00e7\u00f5es importantes sobre o c\u00f3digo&quot;,&quot;link&quot;:&quot;eb-table-content-14&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Complexidade computacional&quot;,&quot;text&quot;:&quot;Complexidade computacional&quot;,&quot;link&quot;:&quot;complexidade-computacional&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;3 \u2014 CEPSTRUM&quot;,&quot;text&quot;:&quot;3 \u2014 CEPSTRUM&quot;,&quot;link&quot;:&quot;3-cepstrum&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que significa Cepstrum&quot;,&quot;text&quot;:&quot;O que significa Cepstrum&quot;,&quot;link&quot;:&quot;o-que-significa-cepstrum&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Intui\u00e7\u00e3o f\u00edsica do Cepstrum&quot;,&quot;text&quot;:&quot;Intui\u00e7\u00e3o f\u00edsica do Cepstrum&quot;,&quot;link&quot;:&quot;eb-table-content-18&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Cepstrum \u201ccl\u00e1ssico\u201d vs Cepstrum via LPC&quot;,&quot;text&quot;:&quot;Cepstrum \u201ccl\u00e1ssico\u201d vs Cepstrum via LPC&quot;,&quot;link&quot;:&quot;eb-table-content-19&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;1. Cepstrum via FFT (cepstrum cl\u00e1ssico)&quot;,&quot;text&quot;:&quot;1. Cepstrum via FFT (cepstrum cl\u00e1ssico)&quot;,&quot;link&quot;:&quot;eb-table-content-20&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;2. Cepstrum via LPC (LPCC)&quot;,&quot;text&quot;:&quot;2. Cepstrum via LPC (LPCC)&quot;,&quot;link&quot;:&quot;2-cepstrum-via-lpc-lpcc&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Por que o Cepstrum \u00e9 t\u00e3o poderoso&quot;,&quot;text&quot;:&quot;Por que o Cepstrum \u00e9 t\u00e3o poderoso&quot;,&quot;link&quot;:&quot;eb-table-content-22&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Quefr\u00eancia: interpreta\u00e7\u00e3o correta&quot;,&quot;text&quot;:&quot;Quefr\u00eancia: interpreta\u00e7\u00e3o correta&quot;,&quot;link&quot;:&quot;eb-table-content-23&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Conex\u00e3o direta com LPCC&quot;,&quot;text&quot;:&quot;Conex\u00e3o direta com LPCC&quot;,&quot;link&quot;:&quot;eb-table-content-24&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;4 \u2014 LP (Linear Prediction)&quot;,&quot;text&quot;:&quot;4 \u2014 LP (Linear Prediction)&quot;,&quot;link&quot;:&quot;4-lp-linear-prediction&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que significa LP&quot;,&quot;text&quot;:&quot;O que significa LP&quot;,&quot;link&quot;:&quot;o-que-significa-lp&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Predi\u00e7\u00e3o linear como modelo autoregressivo (AR)&quot;,&quot;text&quot;:&quot;Predi\u00e7\u00e3o linear como modelo autoregressivo (AR)&quot;,&quot;link&quot;:&quot;eb-table-content-27&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Interpreta\u00e7\u00e3o como filtro digital&quot;,&quot;text&quot;:&quot;Interpreta\u00e7\u00e3o como filtro digital&quot;,&quot;link&quot;:&quot;eb-table-content-28&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Estabilidade do modelo LP&quot;,&quot;text&quot;:&quot;Estabilidade do modelo LP&quot;,&quot;link&quot;:&quot;estabilidade-do-modelo-lp&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Escolha da ordem do modelo (p)&quot;,&quot;text&quot;:&quot;Escolha da ordem do modelo (p)&quot;,&quot;link&quot;:&quot;escolha-da-ordem-do-modelo-p&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Rela\u00e7\u00e3o direta entre LP, LPC e LPCC&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o direta entre LP, LPC e LPCC&quot;,&quot;link&quot;:&quot;eb-table-content-31&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo conceitual em C \u2014 erro de predi\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Exemplo conceitual em C \u2014 erro de predi\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-32&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;5 \u2014 AC (Autocorrelation)&quot;,&quot;text&quot;:&quot;5 \u2014 AC (Autocorrelation)&quot;,&quot;link&quot;:&quot;5-ac-autocorrelation&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que significa AC&quot;,&quot;text&quot;:&quot;O que significa AC&quot;,&quot;link&quot;:&quot;o-que-significa-ac&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Defini\u00e7\u00e3o matem\u00e1tica da autocorrela\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Defini\u00e7\u00e3o matem\u00e1tica da autocorrela\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-35&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Por que a autocorrela\u00e7\u00e3o \u00e9 usada em LPC&quot;,&quot;text&quot;:&quot;Por que a autocorrela\u00e7\u00e3o \u00e9 usada em LPC&quot;,&quot;link&quot;:&quot;eb-table-content-36&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;1. Garante estabilidade do filtro LPC&quot;,&quot;text&quot;:&quot;1. Garante estabilidade do filtro LPC&quot;,&quot;link&quot;:&quot;1-garante-estabilidade-do-filtro-lpc&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;2. Reduz sensibilidade a ru\u00eddo&quot;,&quot;text&quot;:&quot;2. Reduz sensibilidade a ru\u00eddo&quot;,&quot;link&quot;:&quot;eb-table-content-38&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;3. Conecta LP a m\u00ednimos quadrados&quot;,&quot;text&quot;:&quot;3. Conecta LP a m\u00ednimos quadrados&quot;,&quot;link&quot;:&quot;eb-table-content-39&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Equa\u00e7\u00f5es de Yule-Walker&quot;,&quot;text&quot;:&quot;Equa\u00e7\u00f5es de Yule-Walker&quot;,&quot;link&quot;:&quot;eb-table-content-40&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Interpreta\u00e7\u00e3o f\u00edsica da autocorrela\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Interpreta\u00e7\u00e3o f\u00edsica da autocorrela\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-41&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Autocorrela\u00e7\u00e3o e estacionariedade&quot;,&quot;text&quot;:&quot;Autocorrela\u00e7\u00e3o e estacionariedade&quot;,&quot;link&quot;:&quot;eb-table-content-42&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Implementa\u00e7\u00e3o em C \u2014 autocorrela\u00e7\u00e3o (revis\u00e3o pr\u00e1tica)&quot;,&quot;text&quot;:&quot;Implementa\u00e7\u00e3o em C \u2014 autocorrela\u00e7\u00e3o (revis\u00e3o pr\u00e1tica)&quot;,&quot;link&quot;:&quot;eb-table-content-43&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Consequ\u00eancias pr\u00e1ticas em sistemas embarcados&quot;,&quot;text&quot;:&quot;Consequ\u00eancias pr\u00e1ticas em sistemas embarcados&quot;,&quot;link&quot;:&quot;eb-table-content-44&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;6 \u2014 LDA (Levinson\u2013Durbin Algorithm)&quot;,&quot;text&quot;:&quot;6 \u2014 LDA (Levinson\u2013Durbin Algorithm)&quot;,&quot;link&quot;:&quot;6-lda-levinsondurbin-algorithm&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que significa LDA neste contexto&quot;,&quot;text&quot;:&quot;O que significa LDA neste contexto&quot;,&quot;link&quot;:&quot;o-que-significa-lda-neste-contexto&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Por que Levinson\u2013Durbin \u00e9 essencial&quot;,&quot;text&quot;:&quot;Por que Levinson\u2013Durbin \u00e9 essencial&quot;,&quot;link&quot;:&quot;eb-table-content-47&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Estrutura recursiva do algoritmo&quot;,&quot;text&quot;:&quot;Estrutura recursiva do algoritmo&quot;,&quot;link&quot;:&quot;estrutura-recursiva-do-algoritmo&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Interpreta\u00e7\u00e3o f\u00edsica do coeficiente de reflex\u00e3o&quot;,&quot;text&quot;:&quot;Interpreta\u00e7\u00e3o f\u00edsica do coeficiente de reflex\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-49&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Implementa\u00e7\u00e3o completa em C \u2014 Levinson\u2013Durbin&quot;,&quot;text&quot;:&quot;Implementa\u00e7\u00e3o completa em C \u2014 Levinson\u2013Durbin&quot;,&quot;link&quot;:&quot;eb-table-content-50&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Observa\u00e7\u00f5es importantes sobre o c\u00f3digo&quot;,&quot;text&quot;:&quot;Observa\u00e7\u00f5es importantes sobre o c\u00f3digo&quot;,&quot;link&quot;:&quot;eb-table-content-51&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Papel do Levinson\u2013Durbin no pipeline completo&quot;,&quot;text&quot;:&quot;Papel do Levinson\u2013Durbin no pipeline completo&quot;,&quot;link&quot;:&quot;papel-do-levinsondurbin-no-pipeline-completo&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;7 \u2014 PE (Prediction Error)&quot;,&quot;text&quot;:&quot;7 \u2014 PE (Prediction Error)&quot;,&quot;link&quot;:&quot;7-pe-prediction-error&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que significa PE&quot;,&quot;text&quot;:&quot;O que significa PE&quot;,&quot;link&quot;:&quot;o-que-significa-pe&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Energia do erro de predi\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Energia do erro de predi\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-55&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Interpreta\u00e7\u00e3o f\u00edsica do erro de predi\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Interpreta\u00e7\u00e3o f\u00edsica do erro de predi\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-56&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Em fala&quot;,&quot;text&quot;:&quot;Em fala&quot;,&quot;link&quot;:&quot;em-fala&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Em vibra\u00e7\u00e3o mec\u00e2nica&quot;,&quot;text&quot;:&quot;Em vibra\u00e7\u00e3o mec\u00e2nica&quot;,&quot;link&quot;:&quot;eb-table-content-58&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Rela\u00e7\u00e3o direta entre PE e LPCC (coeficiente c\u2080)&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o direta entre PE e LPCC (coeficiente c\u2080)&quot;,&quot;link&quot;:&quot;eb-table-content-59&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;PE como m\u00e9trica de qualidade do modelo&quot;,&quot;text&quot;:&quot;PE como m\u00e9trica de qualidade do modelo&quot;,&quot;link&quot;:&quot;eb-table-content-60&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo em C \u2014 c\u00e1lculo expl\u00edcito do erro m\u00e9dio&quot;,&quot;text&quot;:&quot;Exemplo em C \u2014 c\u00e1lculo expl\u00edcito do erro m\u00e9dio&quot;,&quot;link&quot;:&quot;eb-table-content-61&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;PE e estabilidade num\u00e9rica&quot;,&quot;text&quot;:&quot;PE e estabilidade num\u00e9rica&quot;,&quot;link&quot;:&quot;eb-table-content-62&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Rela\u00e7\u00e3o final no pipeline&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o final no pipeline&quot;,&quot;link&quot;:&quot;eb-table-content-63&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Conclus\u00e3o desta se\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Conclus\u00e3o desta se\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-64&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;8 \u2014 LPCC Extraction Pipeline (Pipeline de Extra\u00e7\u00e3o de LPCC)&quot;,&quot;text&quot;:&quot;8 \u2014 LPCC Extraction Pipeline (Pipeline de Extra\u00e7\u00e3o de LPCC)&quot;,&quot;link&quot;:&quot;eb-table-content-65&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Vis\u00e3o geral do pipeline&quot;,&quot;text&quot;:&quot;Vis\u00e3o geral do pipeline&quot;,&quot;link&quot;:&quot;eb-table-content-66&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Etapa 1 \u2014 Janelamento do sinal&quot;,&quot;text&quot;:&quot;Etapa 1 \u2014 Janelamento do sinal&quot;,&quot;link&quot;:&quot;etapa-1-janelamento-do-sinal&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Etapa 2 \u2014 Autocorrela\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Etapa 2 \u2014 Autocorrela\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-68&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Etapa 3 \u2014 Levinson\u2013Durbin&quot;,&quot;text&quot;:&quot;Etapa 3 \u2014 Levinson\u2013Durbin&quot;,&quot;link&quot;:&quot;etapa-3-levinsondurbin&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Etapa 4 \u2014 Convers\u00e3o LPC \u2192 LPCC&quot;,&quot;text&quot;:&quot;Etapa 4 \u2014 Convers\u00e3o LPC \u2192 LPCC&quot;,&quot;link&quot;:&quot;eb-table-content-70&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Etapa 5 \u2014 Vetor de caracter\u00edsticas&quot;,&quot;text&quot;:&quot;Etapa 5 \u2014 Vetor de caracter\u00edsticas&quot;,&quot;link&quot;:&quot;eb-table-content-71&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo completo \u2014 pipeline integrado em C&quot;,&quot;text&quot;:&quot;Exemplo completo \u2014 pipeline integrado em C&quot;,&quot;link&quot;:&quot;exemplo-completo-pipeline-integrado-em-c&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Considera\u00e7\u00f5es num\u00e9ricas e de engenharia&quot;,&quot;text&quot;:&quot;Considera\u00e7\u00f5es num\u00e9ricas e de engenharia&quot;,&quot;link&quot;:&quot;eb-table-content-73&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;9 \u2014 LPCC \u00d7 MFCC (Compara\u00e7\u00e3o Conceitual e Pr\u00e1tica)&quot;,&quot;text&quot;:&quot;9 \u2014 LPCC \u00d7 MFCC (Compara\u00e7\u00e3o Conceitual e Pr\u00e1tica)&quot;,&quot;link&quot;:&quot;eb-table-content-74&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que significa MFCC&quot;,&quot;text&quot;:&quot;O que significa MFCC&quot;,&quot;link&quot;:&quot;o-que-significa-mfcc&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Diferen\u00e7a filos\u00f3fica entre LPCC e MFCC&quot;,&quot;text&quot;:&quot;Diferen\u00e7a filos\u00f3fica entre LPCC e MFCC&quot;,&quot;link&quot;:&quot;eb-table-content-76&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;LPCC \u2014 modelo f\u00edsico\/matem\u00e1tico&quot;,&quot;text&quot;:&quot;LPCC \u2014 modelo f\u00edsico\/matem\u00e1tico&quot;,&quot;link&quot;:&quot;eb-table-content-77&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;MFCC \u2014 modelo perceptual&quot;,&quot;text&quot;:&quot;MFCC \u2014 modelo perceptual&quot;,&quot;link&quot;:&quot;mfcc-modelo-perceptual&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Pipeline comparativo&quot;,&quot;text&quot;:&quot;Pipeline comparativo&quot;,&quot;link&quot;:&quot;pipeline-comparativo&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;LPCC&quot;,&quot;text&quot;:&quot;LPCC&quot;,&quot;link&quot;:&quot;lpcc&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;MFCC&quot;,&quot;text&quot;:&quot;MFCC&quot;,&quot;link&quot;:&quot;mfcc&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Complexidade computacional&quot;,&quot;text&quot;:&quot;Complexidade computacional&quot;,&quot;link&quot;:&quot;complexidade-computacional&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Sensibilidade a ru\u00eddo e n\u00e3o-linearidades&quot;,&quot;text&quot;:&quot;Sensibilidade a ru\u00eddo e n\u00e3o-linearidades&quot;,&quot;link&quot;:&quot;eb-table-content-83&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Interpretabilidade dos coeficientes&quot;,&quot;text&quot;:&quot;Interpretabilidade dos coeficientes&quot;,&quot;link&quot;:&quot;interpretabilidade-dos-coeficientes&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo pr\u00e1tico de escolha&quot;,&quot;text&quot;:&quot;Exemplo pr\u00e1tico de escolha&quot;,&quot;link&quot;:&quot;eb-table-content-85&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Ponto cr\u00edtico raramente discutido&quot;,&quot;text&quot;:&quot;Ponto cr\u00edtico raramente discutido&quot;,&quot;link&quot;:&quot;eb-table-content-86&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;10 \u2014 Aplica\u00e7\u00f5es do LPCC (Linear Prediction Cepstral Coefficients)&quot;,&quot;text&quot;:&quot;10 \u2014 Aplica\u00e7\u00f5es do LPCC (Linear Prediction Cepstral Coefficients)&quot;,&quot;link&quot;:&quot;eb-table-content-87&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Por que LPCC \u00e9 usado na pr\u00e1tica&quot;,&quot;text&quot;:&quot;Por que LPCC \u00e9 usado na pr\u00e1tica&quot;,&quot;link&quot;:&quot;eb-table-content-88&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1. Reconhecimento e classifica\u00e7\u00e3o de fala (cl\u00e1ssico)&quot;,&quot;text&quot;:&quot;1. Reconhecimento e classifica\u00e7\u00e3o de fala (cl\u00e1ssico)&quot;,&quot;link&quot;:&quot;eb-table-content-89&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2. Diagn\u00f3stico vibroac\u00fastico e monitoramento de condi\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;2. Diagn\u00f3stico vibroac\u00fastico e monitoramento de condi\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-90&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3. Detec\u00e7\u00e3o de anomalias (Anomaly Detection)&quot;,&quot;text&quot;:&quot;3. Detec\u00e7\u00e3o de anomalias (Anomaly Detection)&quot;,&quot;link&quot;:&quot;eb-table-content-91&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4. Classifica\u00e7\u00e3o com Machine Learning cl\u00e1ssico&quot;,&quot;text&quot;:&quot;4. Classifica\u00e7\u00e3o com Machine Learning cl\u00e1ssico&quot;,&quot;link&quot;:&quot;eb-table-content-92&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5. Monitoramento em tempo real (edge \/ firmware)&quot;,&quot;text&quot;:&quot;5. Monitoramento em tempo real (edge \/ firmware)&quot;,&quot;link&quot;:&quot;5-monitoramento-em-tempo-real-edge-firmware&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6. Aplica\u00e7\u00f5es em energia e eletromagnetismo&quot;,&quot;text&quot;:&quot;6. Aplica\u00e7\u00f5es em energia e eletromagnetismo&quot;,&quot;link&quot;:&quot;eb-table-content-94&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7. Por que LPCC \u00e9 subestimado hoje&quot;,&quot;text&quot;:&quot;7. Por que LPCC \u00e9 subestimado hoje&quot;,&quot;link&quot;:&quot;eb-table-content-95&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo conceitual de uso do LPCC em classifica\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Exemplo conceitual de uso do LPCC em classifica\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-96&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Conclus\u00e3o&quot;,&quot;text&quot;:&quot;Conclus\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-97&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;1 \u2014 LPC (Linear Predictive Coding)&quot;,&quot;value&quot;:&quot;1-lpc-linear-predictive-coding&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que significa LPC&quot;,&quot;value&quot;:&quot;o-que-significa-lpc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Intui\u00e7\u00e3o f\u00edsica e de sinal&quot;,&quot;value&quot;:&quot;intui\u00e7\u00e3o-f\u00edsica-e-de-sinal&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Modelo matem\u00e1tico do LPC&quot;,&quot;value&quot;:&quot;modelo-matem\u00e1tico-do-lpc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Por que o LPC \u00e9 importante para LPCC&quot;,&quot;value&quot;:&quot;por-que-o-lpc-\u00e9-importante-para-lpcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Implementa\u00e7\u00e3o conceitual do LPC em C (vis\u00e3o geral)&quot;,&quot;value&quot;:&quot;implementa\u00e7\u00e3o-conceitual-do-lpc-em-c-vis\u00e3o-geral&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo em C \u2014 c\u00e1lculo da autocorrela\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;exemplo-em-c-c\u00e1lculo-da-autocorrela\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Observa\u00e7\u00f5es pr\u00e1ticas para sistemas embarcados&quot;,&quot;value&quot;:&quot;observa\u00e7\u00f5es-pr\u00e1ticas-para-sistemas-embarcados&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2 \u2014 LPCC (Linear Prediction Cepstral Coefficients)&quot;,&quot;value&quot;:&quot;2-lpcc-linear-prediction-cepstral-coefficients&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que significa LPCC&quot;,&quot;value&quot;:&quot;o-que-significa-lpcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que \u00e9 o dom\u00ednio cepstral (intui\u00e7\u00e3o)&quot;,&quot;value&quot;:&quot;o-que-\u00e9-o-dom\u00ednio-cepstral-intui\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o matem\u00e1tica entre LPC e LPCC&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-matem\u00e1tica-entre-lpc-e-lpcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Por que LPCC \u00e9 prefer\u00edvel ao LPC em Machine Learning&quot;,&quot;value&quot;:&quot;por-que-lpcc-\u00e9-prefer\u00edvel-ao-lpc-em-machine-learning&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Implementa\u00e7\u00e3o em C \u2014 LPC \u2192 LPCC&quot;,&quot;value&quot;:&quot;implementa\u00e7\u00e3o-em-c-lpc-\u2192-lpcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Observa\u00e7\u00f5es importantes sobre o c\u00f3digo&quot;,&quot;value&quot;:&quot;observa\u00e7\u00f5es-importantes-sobre-o-c\u00f3digo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Complexidade computacional&quot;,&quot;value&quot;:&quot;complexidade-computacional&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3 \u2014 CEPSTRUM&quot;,&quot;value&quot;:&quot;3-cepstrum&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que significa Cepstrum&quot;,&quot;value&quot;:&quot;o-que-significa-cepstrum&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Intui\u00e7\u00e3o f\u00edsica do Cepstrum&quot;,&quot;value&quot;:&quot;intui\u00e7\u00e3o-f\u00edsica-do-cepstrum&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Cepstrum \u201ccl\u00e1ssico\u201d vs Cepstrum via LPC&quot;,&quot;value&quot;:&quot;cepstrum-cl\u00e1ssico-vs-cepstrum-via-lpc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1. Cepstrum via FFT (cepstrum cl\u00e1ssico)&quot;,&quot;value&quot;:&quot;1-cepstrum-via-fft-cepstrum-cl\u00e1ssico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2. Cepstrum via LPC (LPCC)&quot;,&quot;value&quot;:&quot;2-cepstrum-via-lpc-lpcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Por que o Cepstrum \u00e9 t\u00e3o poderoso&quot;,&quot;value&quot;:&quot;por-que-o-cepstrum-\u00e9-t\u00e3o-poderoso&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Quefr\u00eancia: interpreta\u00e7\u00e3o correta&quot;,&quot;value&quot;:&quot;quefr\u00eancia-interpreta\u00e7\u00e3o-correta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conex\u00e3o direta com LPCC&quot;,&quot;value&quot;:&quot;conex\u00e3o-direta-com-lpcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4 \u2014 LP (Linear Prediction)&quot;,&quot;value&quot;:&quot;4-lp-linear-prediction&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que significa LP&quot;,&quot;value&quot;:&quot;o-que-significa-lp&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Predi\u00e7\u00e3o linear como modelo autoregressivo (AR)&quot;,&quot;value&quot;:&quot;predi\u00e7\u00e3o-linear-como-modelo-autoregressivo-ar&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Interpreta\u00e7\u00e3o como filtro digital&quot;,&quot;value&quot;:&quot;interpreta\u00e7\u00e3o-como-filtro-digital&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estabilidade do modelo LP&quot;,&quot;value&quot;:&quot;estabilidade-do-modelo-lp&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Escolha da ordem do modelo (p)&quot;,&quot;value&quot;:&quot;escolha-da-ordem-do-modelo-p&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o direta entre LP, LPC e LPCC&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-direta-entre-lp-lpc-e-lpcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo conceitual em C \u2014 erro de predi\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;exemplo-conceitual-em-c-erro-de-predi\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5 \u2014 AC (Autocorrelation)&quot;,&quot;value&quot;:&quot;5-ac-autocorrelation&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que significa AC&quot;,&quot;value&quot;:&quot;o-que-significa-ac&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Defini\u00e7\u00e3o matem\u00e1tica da autocorrela\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;defini\u00e7\u00e3o-matem\u00e1tica-da-autocorrela\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Por que a autocorrela\u00e7\u00e3o \u00e9 usada em LPC&quot;,&quot;value&quot;:&quot;por-que-a-autocorrela\u00e7\u00e3o-\u00e9-usada-em-lpc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1. Garante estabilidade do filtro LPC&quot;,&quot;value&quot;:&quot;1-garante-estabilidade-do-filtro-lpc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2. Reduz sensibilidade a ru\u00eddo&quot;,&quot;value&quot;:&quot;2-reduz-sensibilidade-a-ru\u00eddo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3. Conecta LP a m\u00ednimos quadrados&quot;,&quot;value&quot;:&quot;3-conecta-lp-a-m\u00ednimos-quadrados&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Equa\u00e7\u00f5es de Yule-Walker&quot;,&quot;value&quot;:&quot;equa\u00e7\u00f5es-de-yule-walker&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Interpreta\u00e7\u00e3o f\u00edsica da autocorrela\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;interpreta\u00e7\u00e3o-f\u00edsica-da-autocorrela\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Autocorrela\u00e7\u00e3o e estacionariedade&quot;,&quot;value&quot;:&quot;autocorrela\u00e7\u00e3o-e-estacionariedade&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Implementa\u00e7\u00e3o em C \u2014 autocorrela\u00e7\u00e3o (revis\u00e3o pr\u00e1tica)&quot;,&quot;value&quot;:&quot;implementa\u00e7\u00e3o-em-c-autocorrela\u00e7\u00e3o-revis\u00e3o-pr\u00e1tica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Consequ\u00eancias pr\u00e1ticas em sistemas embarcados&quot;,&quot;value&quot;:&quot;consequ\u00eancias-pr\u00e1ticas-em-sistemas-embarcados&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6 \u2014 LDA (Levinson\u2013Durbin Algorithm)&quot;,&quot;value&quot;:&quot;6-lda-levinsondurbin-algorithm&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que significa LDA neste contexto&quot;,&quot;value&quot;:&quot;o-que-significa-lda-neste-contexto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Por que Levinson\u2013Durbin \u00e9 essencial&quot;,&quot;value&quot;:&quot;por-que-levinsondurbin-\u00e9-essencial&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estrutura recursiva do algoritmo&quot;,&quot;value&quot;:&quot;estrutura-recursiva-do-algoritmo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Interpreta\u00e7\u00e3o f\u00edsica do coeficiente de reflex\u00e3o&quot;,&quot;value&quot;:&quot;interpreta\u00e7\u00e3o-f\u00edsica-do-coeficiente-de-reflex\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Implementa\u00e7\u00e3o completa em C \u2014 Levinson\u2013Durbin&quot;,&quot;value&quot;:&quot;implementa\u00e7\u00e3o-completa-em-c-levinsondurbin&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Observa\u00e7\u00f5es importantes sobre o c\u00f3digo&quot;,&quot;value&quot;:&quot;observa\u00e7\u00f5es-importantes-sobre-o-c\u00f3digo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Papel do Levinson\u2013Durbin no pipeline completo&quot;,&quot;value&quot;:&quot;papel-do-levinsondurbin-no-pipeline-completo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7 \u2014 PE (Prediction Error)&quot;,&quot;value&quot;:&quot;7-pe-prediction-error&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que significa PE&quot;,&quot;value&quot;:&quot;o-que-significa-pe&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Energia do erro de predi\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;energia-do-erro-de-predi\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Interpreta\u00e7\u00e3o f\u00edsica do erro de predi\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;interpreta\u00e7\u00e3o-f\u00edsica-do-erro-de-predi\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Em fala&quot;,&quot;value&quot;:&quot;em-fala&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Em vibra\u00e7\u00e3o mec\u00e2nica&quot;,&quot;value&quot;:&quot;em-vibra\u00e7\u00e3o-mec\u00e2nica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o direta entre PE e LPCC (coeficiente c\u2080)&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-direta-entre-pe-e-lpcc-coeficiente-c\u2080&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;PE como m\u00e9trica de qualidade do modelo&quot;,&quot;value&quot;:&quot;pe-como-m\u00e9trica-de-qualidade-do-modelo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo em C \u2014 c\u00e1lculo expl\u00edcito do erro m\u00e9dio&quot;,&quot;value&quot;:&quot;exemplo-em-c-c\u00e1lculo-expl\u00edcito-do-erro-m\u00e9dio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;PE e estabilidade num\u00e9rica&quot;,&quot;value&quot;:&quot;pe-e-estabilidade-num\u00e9rica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o final no pipeline&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-final-no-pipeline&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conclus\u00e3o desta se\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;conclus\u00e3o-desta-se\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;8 \u2014 LPCC Extraction Pipeline (Pipeline de Extra\u00e7\u00e3o de LPCC)&quot;,&quot;value&quot;:&quot;8-lpcc-extraction-pipeline-pipeline-de-extra\u00e7\u00e3o-de-lpcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Vis\u00e3o geral do pipeline&quot;,&quot;value&quot;:&quot;vis\u00e3o-geral-do-pipeline&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Etapa 1 \u2014 Janelamento do sinal&quot;,&quot;value&quot;:&quot;etapa-1-janelamento-do-sinal&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Etapa 2 \u2014 Autocorrela\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;etapa-2-autocorrela\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Etapa 3 \u2014 Levinson\u2013Durbin&quot;,&quot;value&quot;:&quot;etapa-3-levinsondurbin&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Etapa 4 \u2014 Convers\u00e3o LPC \u2192 LPCC&quot;,&quot;value&quot;:&quot;etapa-4-convers\u00e3o-lpc-\u2192-lpcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Etapa 5 \u2014 Vetor de caracter\u00edsticas&quot;,&quot;value&quot;:&quot;etapa-5-vetor-de-caracter\u00edsticas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo completo \u2014 pipeline integrado em C&quot;,&quot;value&quot;:&quot;exemplo-completo-pipeline-integrado-em-c&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Considera\u00e7\u00f5es num\u00e9ricas e de engenharia&quot;,&quot;value&quot;:&quot;considera\u00e7\u00f5es-num\u00e9ricas-e-de-engenharia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;9 \u2014 LPCC \u00d7 MFCC (Compara\u00e7\u00e3o Conceitual e Pr\u00e1tica)&quot;,&quot;value&quot;:&quot;9-lpcc-\u00d7-mfcc-compara\u00e7\u00e3o-conceitual-e-pr\u00e1tica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que significa MFCC&quot;,&quot;value&quot;:&quot;o-que-significa-mfcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Diferen\u00e7a filos\u00f3fica entre LPCC e MFCC&quot;,&quot;value&quot;:&quot;diferen\u00e7a-filos\u00f3fica-entre-lpcc-e-mfcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;LPCC \u2014 modelo f\u00edsico\/matem\u00e1tico&quot;,&quot;value&quot;:&quot;lpcc-modelo-f\u00edsicomatem\u00e1tico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;MFCC \u2014 modelo perceptual&quot;,&quot;value&quot;:&quot;mfcc-modelo-perceptual&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Pipeline comparativo&quot;,&quot;value&quot;:&quot;pipeline-comparativo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;LPCC&quot;,&quot;value&quot;:&quot;lpcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;MFCC&quot;,&quot;value&quot;:&quot;mfcc&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Complexidade computacional&quot;,&quot;value&quot;:&quot;complexidade-computacional&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Sensibilidade a ru\u00eddo e n\u00e3o-linearidades&quot;,&quot;value&quot;:&quot;sensibilidade-a-ru\u00eddo-e-n\u00e3o-linearidades&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Interpretabilidade dos coeficientes&quot;,&quot;value&quot;:&quot;interpretabilidade-dos-coeficientes&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo pr\u00e1tico de escolha&quot;,&quot;value&quot;:&quot;exemplo-pr\u00e1tico-de-escolha&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Ponto cr\u00edtico raramente discutido&quot;,&quot;value&quot;:&quot;ponto-cr\u00edtico-raramente-discutido&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;10 \u2014 Aplica\u00e7\u00f5es do LPCC (Linear Prediction Cepstral Coefficients)&quot;,&quot;value&quot;:&quot;10-aplica\u00e7\u00f5es-do-lpcc-linear-prediction-cepstral-coefficients&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Por que LPCC \u00e9 usado na pr\u00e1tica&quot;,&quot;value&quot;:&quot;por-que-lpcc-\u00e9-usado-na-pr\u00e1tica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1. Reconhecimento e classifica\u00e7\u00e3o de fala (cl\u00e1ssico)&quot;,&quot;value&quot;:&quot;1-reconhecimento-e-classifica\u00e7\u00e3o-de-fala-cl\u00e1ssico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2. Diagn\u00f3stico vibroac\u00fastico e monitoramento de condi\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;2-diagn\u00f3stico-vibroac\u00fastico-e-monitoramento-de-condi\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3. Detec\u00e7\u00e3o de anomalias (Anomaly Detection)&quot;,&quot;value&quot;:&quot;3-detec\u00e7\u00e3o-de-anomalias-anomaly-detection&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4. Classifica\u00e7\u00e3o com Machine Learning cl\u00e1ssico&quot;,&quot;value&quot;:&quot;4-classifica\u00e7\u00e3o-com-machine-learning-cl\u00e1ssico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5. Monitoramento em tempo real (edge \/ firmware)&quot;,&quot;value&quot;:&quot;5-monitoramento-em-tempo-real-edge-firmware&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6. Aplica\u00e7\u00f5es em energia e eletromagnetismo&quot;,&quot;value&quot;:&quot;6-aplica\u00e7\u00f5es-em-energia-e-eletromagnetismo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7. Por que LPCC \u00e9 subestimado hoje&quot;,&quot;value&quot;:&quot;7-por-que-lpcc-\u00e9-subestimado-hoje&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo conceitual de uso do LPCC em classifica\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;exemplo-conceitual-de-uso-do-lpcc-em-classifica\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conclus\u00e3o&quot;,&quot;value&quot;:&quot;conclus\u00e3o&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="#1-lpc-linear-predictive-coding">1 — LPC (Linear Predictive Coding)</a><ul class="eb-toc__list"><li><a href="#o-que-significa-lpc">O que significa LPC</a><li><a href="#eb-table-content-2">Intuição física e de sinal</a><li><a href="#eb-table-content-3">Modelo matemático do LPC</a><li><a href="#eb-table-content-4">Por que o LPC é importante para LPCC</a><li><a href="#eb-table-content-5">Implementação conceitual do LPC em C (visão geral)</a><li><a href="#eb-table-content-6">Exemplo em C — cálculo da autocorrelação</a><li><a href="#eb-table-content-7">Observações práticas para sistemas embarcados</a></li></ul><li><a href="#2-lpcc-linear-prediction-cepstral-coefficients">2 — LPCC (Linear Prediction Cepstral Coefficients)</a><ul class="eb-toc__list"><li><a href="#o-que-significa-lpcc">O que significa LPCC</a><li><a href="#eb-table-content-10">O que é o domínio cepstral (intuição)</a><li><a href="#eb-table-content-11">Relação matemática entre LPC e LPCC</a><li><a href="#eb-table-content-12">Por que LPCC é preferível ao LPC em Machine Learning</a><li><a href="#eb-table-content-13">Implementação em C — LPC → LPCC</a><li><a href="#eb-table-content-14">Observações importantes sobre o código</a><li><a href="#complexidade-computacional">Complexidade computacional</a></li></ul><li><a href="#3-cepstrum">3 — CEPSTRUM</a><ul class="eb-toc__list"><li><a href="#o-que-significa-cepstrum">O que significa Cepstrum</a><li><a href="#eb-table-content-18">Intuição física do Cepstrum</a><li><a href="#eb-table-content-19">Cepstrum “clássico” vs Cepstrum via LPC</a><ul class="eb-toc__list"><li><a href="#eb-table-content-20">1. Cepstrum via FFT (cepstrum clássico)</a><li><a href="#2-cepstrum-via-lpc-lpcc">2. Cepstrum via LPC (LPCC)</a></li></ul><li><a href="#eb-table-content-22">Por que o Cepstrum é tão poderoso</a><li><a href="#eb-table-content-23">Quefrência: interpretação correta</a><li><a href="#eb-table-content-24">Conexão direta com LPCC</a></li></ul><li><a href="#4-lp-linear-prediction">4 — LP (Linear Prediction)</a><ul class="eb-toc__list"><li><a href="#o-que-significa-lp">O que significa LP</a><li><a href="#eb-table-content-27">Predição linear como modelo autoregressivo (AR)</a><li><a href="#eb-table-content-28">Interpretação como filtro digital</a><li><a href="#estabilidade-do-modelo-lp">Estabilidade do modelo LP</a><li><a href="#escolha-da-ordem-do-modelo-p">Escolha da ordem do modelo (p)</a><li><a href="#eb-table-content-31">Relação direta entre LP, LPC e LPCC</a><li><a href="#eb-table-content-32">Exemplo conceitual em C — erro de predição</a></li></ul><li><a href="#5-ac-autocorrelation">5 — AC (Autocorrelation)</a><ul class="eb-toc__list"><li><a href="#o-que-significa-ac">O que significa AC</a><li><a href="#eb-table-content-35">Definição matemática da autocorrelação</a><li><a href="#eb-table-content-36">Por que a autocorrelação é usada em LPC</a><ul class="eb-toc__list"><li><a href="#1-garante-estabilidade-do-filtro-lpc">1. Garante estabilidade do filtro LPC</a><li><a href="#eb-table-content-38">2. Reduz sensibilidade a ruído</a><li><a href="#eb-table-content-39">3. Conecta LP a mínimos quadrados</a></li></ul><li><a href="#eb-table-content-40">Equações de Yule-Walker</a><li><a href="#eb-table-content-41">Interpretação física da autocorrelação</a><li><a href="#eb-table-content-42">Autocorrelação e estacionariedade</a><li><a href="#eb-table-content-43">Implementação em C — autocorrelação (revisão prática)</a><li><a href="#eb-table-content-44">Consequências práticas em sistemas embarcados</a></li></ul><li><a href="#6-lda-levinsondurbin-algorithm">6 — LDA (Levinson–Durbin Algorithm)</a><ul class="eb-toc__list"><li><a href="#o-que-significa-lda-neste-contexto">O que significa LDA neste contexto</a><li><a href="#eb-table-content-47">Por que Levinson–Durbin é essencial</a><li><a href="#estrutura-recursiva-do-algoritmo">Estrutura recursiva do algoritmo</a><li><a href="#eb-table-content-49">Interpretação física do coeficiente de reflexão</a><li><a href="#eb-table-content-50">Implementação completa em C — Levinson–Durbin</a><li><a href="#eb-table-content-51">Observações importantes sobre o código</a><li><a href="#papel-do-levinsondurbin-no-pipeline-completo">Papel do Levinson–Durbin no pipeline completo</a></li></ul><li><a href="#7-pe-prediction-error">7 — PE (Prediction Error)</a><ul class="eb-toc__list"><li><a href="#o-que-significa-pe">O que significa PE</a><li><a href="#eb-table-content-55">Energia do erro de predição</a><li><a href="#eb-table-content-56">Interpretação física do erro de predição</a><ul class="eb-toc__list"><li><a href="#em-fala">Em fala</a><li><a href="#eb-table-content-58">Em vibração mecânica</a></li></ul><li><a href="#eb-table-content-59">Relação direta entre PE e LPCC (coeficiente c₀)</a><li><a href="#eb-table-content-60">PE como métrica de qualidade do modelo</a><li><a href="#eb-table-content-61">Exemplo em C — cálculo explícito do erro médio</a><li><a href="#eb-table-content-62">PE e estabilidade numérica</a><li><a href="#eb-table-content-63">Relação final no pipeline</a><li><a href="#eb-table-content-64">Conclusão desta seção</a></li></ul><li><a href="#eb-table-content-65">8 — LPCC Extraction Pipeline (Pipeline de Extração de LPCC)</a><ul class="eb-toc__list"><li><a href="#eb-table-content-66">Visão geral do pipeline</a><li><a href="#etapa-1-janelamento-do-sinal">Etapa 1 — Janelamento do sinal</a><li><a href="#eb-table-content-68">Etapa 2 — Autocorrelação</a><li><a href="#etapa-3-levinsondurbin">Etapa 3 — Levinson–Durbin</a><li><a href="#eb-table-content-70">Etapa 4 — Conversão LPC → LPCC</a><li><a href="#eb-table-content-71">Etapa 5 — Vetor de características</a><li><a href="#exemplo-completo-pipeline-integrado-em-c">Exemplo completo — pipeline integrado em C</a><li><a href="#eb-table-content-73">Considerações numéricas e de engenharia</a></li></ul><li><a href="#eb-table-content-74">9 — LPCC × MFCC (Comparação Conceitual e Prática)</a><ul class="eb-toc__list"><li><a href="#o-que-significa-mfcc">O que significa MFCC</a><li><a href="#eb-table-content-76">Diferença filosófica entre LPCC e MFCC</a><ul class="eb-toc__list"><li><a href="#eb-table-content-77">LPCC — modelo físico/matemático</a><li><a href="#mfcc-modelo-perceptual">MFCC — modelo perceptual</a></li></ul><li><a href="#pipeline-comparativo">Pipeline comparativo</a><ul class="eb-toc__list"><li><a href="#lpcc">LPCC</a><li><a href="#mfcc">MFCC</a></li></ul><li><a href="#complexidade-computacional">Complexidade computacional</a><li><a href="#eb-table-content-83">Sensibilidade a ruído e não-linearidades</a><li><a href="#interpretabilidade-dos-coeficientes">Interpretabilidade dos coeficientes</a><li><a href="#eb-table-content-85">Exemplo prático de escolha</a><li><a href="#eb-table-content-86">Ponto crítico raramente discutido</a></li></ul><li><a href="#eb-table-content-87">10 — Aplicações do LPCC (Linear Prediction Cepstral Coefficients)</a><ul class="eb-toc__list"><li><a href="#eb-table-content-88">Por que LPCC é usado na prática</a><li><a href="#eb-table-content-89">1. Reconhecimento e classificação de fala (clássico)</a><li><a href="#eb-table-content-90">2. Diagnóstico vibroacústico e monitoramento de condição</a><li><a href="#eb-table-content-91">3. Detecção de anomalias (Anomaly Detection)</a><li><a href="#eb-table-content-92">4. Classificação com Machine Learning clássico</a><li><a href="#5-monitoramento-em-tempo-real-edge-firmware">5. Monitoramento em tempo real (edge / firmware)</a><li><a href="#eb-table-content-94">6. Aplicações em energia e eletromagnetismo</a><li><a href="#eb-table-content-95">7. Por que LPCC é subestimado hoje</a><li><a href="#eb-table-content-96">Exemplo conceitual de uso do LPCC em classificação</a></li></ul><li><a href="#eb-table-content-97">Conclusão</a></ul></div></div></div></div></div>


<h2 class="wp-block-heading">1 — <strong>LPC (Linear Predictive Coding)</strong></h2>



<h3 class="wp-block-heading">O que significa LPC</h3>



<p class="wp-block-paragraph"><strong>LPC</strong> é o acrônimo de <strong>Linear Predictive Coding</strong> (<em>Codificação Preditiva Linear</em>).<br>Trata-se de um método matemático usado para <strong>modelar sinais</strong>, especialmente sinais de fala e áudio, assumindo que <strong>cada amostra do sinal pode ser aproximada como uma combinação linear de amostras passadas</strong>.</p>



<p class="wp-block-paragraph">Em termos simples:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">o LPC tenta responder à pergunta<br><em>“Dado o passado recente do sinal, qual é o melhor valor para a próxima amostra?”</em></p>
</blockquote>



<p class="wp-block-paragraph">Essa ideia é central em processamento de fala, reconhecimento de padrões acústicos e, mais recentemente, em pipelines de <strong>extração de características cepstrais</strong>, como o <strong>LPCC</strong>.</p>



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



<h3 class="wp-block-heading">Intuição física e de sinal</h3>



<p class="wp-block-paragraph">No contexto de fala (mas não limitado a ele), o LPC modela o sinal como:</p>



<ul class="wp-block-list">
<li>Uma <strong>fonte de excitação</strong> (ex.: vibração das cordas vocais)</li>



<li>Um <strong>filtro linear</strong> (trato vocal, cavidade acústica, ou sistema ressonante)</li>
</ul>



<p class="wp-block-paragraph">Matematicamente, o sinal é tratado como a saída de um <strong>filtro tudo-polo (all-pole)</strong> excitado por um sinal simples.</p>



<p class="wp-block-paragraph">Isso é importante porque:</p>



<ul class="wp-block-list">
<li>Formantes (ressonâncias) aparecem naturalmente nos polos do modelo</li>



<li>O modelo é <strong>compacto</strong>, <strong>computacionalmente eficiente</strong> e <strong>estável</strong></li>
</ul>



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



<h3 class="wp-block-heading">Modelo matemático do LPC</h3>



<p class="wp-block-paragraph">O sinal discreto ( x[n] ) é modelado como:</p>



<p class="wp-block-paragraph">\[<br>x[n] = -\sum_{k=1}^{p} a_k , x[n-k] + e[n]<br>\]



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



<ul class="wp-block-list">
<li>\( a_k \) → coeficientes LPC</li>



<li>\( p \) → ordem do modelo</li>



<li>\( e[n] \) → erro de predição (resíduo)</li>
</ul>



<p class="wp-block-paragraph">O objetivo do LPC é <strong>escolher os coeficientes \( a_k \)</strong> que <strong>minimizam a energia média do erro</strong>.</p>



<p class="wp-block-paragraph">Isso leva diretamente às <strong>Equações de Yule-Walker</strong>, resolvidas normalmente pelo <strong>algoritmo de Levinson-Durbin</strong> — que veremos em código C mais à frente.</p>



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



<h3 class="wp-block-heading">Por que o LPC é importante para LPCC</h3>



<p class="wp-block-paragraph">Aqui está o ponto-chave que conecta esta seção ao restante do artigo:</p>



<ul class="wp-block-list">
<li><strong>LPCC (Linear Prediction Cepstral Coefficients)</strong> <strong>não existem sem LPC</strong></li>



<li>O LPC fornece:
<ul class="wp-block-list">
<li>Os <strong>coeficientes do filtro</strong></li>



<li>A <strong>estrutura espectral</strong></li>
</ul>
</li>



<li>O LPCC transforma esses coeficientes em um <strong>domínio cepstral</strong>, mais adequado para:
<ul class="wp-block-list">
<li>Reconhecimento de padrões</li>



<li>Classificação</li>



<li>Machine Learning clássico</li>
</ul>
</li>
</ul>



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



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>LPC modela o sistema</strong><br><strong>LPCC descreve o sistema</strong></p>
</blockquote>



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



<h3 class="wp-block-heading">Implementação conceitual do LPC em C (visão geral)</h3>



<p class="wp-block-paragraph">Antes do código completo, o pipeline típico em C é:</p>



<ol class="wp-block-list">
<li>Janela do sinal (ex.: Hamming)</li>



<li>Cálculo da autocorrelação</li>



<li>Levinson-Durbin → coeficientes LPC</li>



<li>Conversão LPC → LPCC (próxima seção futura)</li>
</ol>



<p class="wp-block-paragraph">Nesta seção, focamos apenas no <strong>LPC puro</strong>.</p>



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



<h3 class="wp-block-heading">Exemplo em C — cálculo da autocorrelação</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;stddef.h>

/**
 * Calcula a autocorrelação de um sinal
 * x      : sinal de entrada
 * N      : número de amostras
 * p      : ordem LPC
 * r      : vetor de autocorrelação (tamanho p+1)
 */
void autocorrelation(const float *x, size_t N, size_t p, float *r)
{
    for (size_t k = 0; k &lt;= p; k++) {
        r&#91;k&#93; = 0.0f;
        for (size_t n = k; n &lt; N; n++) {
            r&#91;k&#93; += x&#91;n&#93; * x&#91;n - k&#93;;
        }
    }
}
</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">#include &lt;stddef.h&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">/**</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">*</span><span style="color: #D8DEE9FF"> Calcula a autocorrelação de um sinal</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">*</span><span style="color: #D8DEE9FF"> x      : sinal de entrada</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">*</span><span style="color: #D8DEE9FF"> N      : número de amostras</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">*</span><span style="color: #D8DEE9FF"> p      : ordem LPC</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">*</span><span style="color: #D8DEE9FF"> r      : vetor de autocorrelação (tamanho p+1)</span></span>
<span class="line"><span style="color: #D8DEE9FF"> */</span></span>
<span class="line"><span style="color: #D8DEE9FF">void autocorrelation(const float *x, size_t N, size_t p, float *r)</span></span>
<span class="line"><span style="color: #D8DEE9FF">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    for (size_t k = 0; k &lt;= p; k++) {</span></span>
<span class="line"><span style="color: #D8DEE9FF">        r</span><span style="color: #ECEFF4">&#91;</span><span style="color: #88C0D0">k</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> = 0.0f;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        for (size_t n = k; n &lt; N; n++) {</span></span>
<span class="line"><span style="color: #D8DEE9FF">            r</span><span style="color: #ECEFF4">&#91;</span><span style="color: #88C0D0">k</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> += x</span><span style="color: #ECEFF4">&#91;</span><span style="color: #88C0D0">n</span><span style="color: #ECEFF4">&#93;</span><span style="color: #D8DEE9FF"> * x&#91;n - k&#93;;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        }</span></span>
<span class="line"><span style="color: #D8DEE9FF">    }</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Esse vetor <code>r[k]</code> é exatamente o que alimenta o algoritmo de <strong>Levinson-Durbin</strong>, que gera os coeficientes LPC.</p>



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



<h3 class="wp-block-heading">Observações práticas para sistemas embarcados</h3>



<p class="wp-block-paragraph">Do ponto de vista de firmware e IoT:</p>



<ul class="wp-block-list">
<li>LPC é <strong>extremamente viável</strong> em microcontroladores</li>



<li>Complexidade: ( O(p^2) )</li>



<li>Pode ser executado:
<ul class="wp-block-list">
<li>Em <strong>tempo real</strong></li>



<li>Com <strong>DMA + buffers circulares</strong></li>



<li>Integrado a pipelines FreeRTOS ou Zephyr</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph">Isso explica por que LPC/LPCC ainda são relevantes mesmo em tempos de deep learning.</p><p>The post <a href="https://mcu.tec.br/algoritimos/dsp/lpcc-linear-prediction-cepstral-coefficients-fundamentos-algoritmos-e-aplicacoes-em-sistemas-embarcados/">LPCC (Linear Prediction Cepstral Coefficients): Fundamentos, Algoritmos e Aplicações em Sistemas Embarcados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1254</post-id>	</item>
		<item>
		<title>Detecção de Assobio Humano com o Algoritmo de Goertzel no RP2040</title>
		<link>https://mcu.tec.br/algoritimos/dsp/deteccao-de-assobio-humano-com-o-algoritmo-de-goertzel-no-rp2040/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=deteccao-de-assobio-humano-com-o-algoritmo-de-goertzel-no-rp2040</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Thu, 29 Jan 2026 22:37:21 +0000</pubDate>
				<category><![CDATA[DSP]]></category>
		<category><![CDATA[algoritmo goertzel]]></category>
		<category><![CDATA[análise espectral]]></category>
		<category><![CDATA[áudio embarcado]]></category>
		<category><![CDATA[BitDogLab]]></category>
		<category><![CDATA[detecção de assobio]]></category>
		<category><![CDATA[DSP embarcado]]></category>
		<category><![CDATA[firmware em c]]></category>
		<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[processamento digital de sinais]]></category>
		<category><![CDATA[RP2040]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1125</guid>

					<description><![CDATA[<p>Este artigo apresenta uma implementação completa e didática do algoritmo de Goertzel para detecção de assobio humano em microcontroladores RP2040, dando continuidade à série de processamento digital de sinais iniciada com filtros baseados em Séries de Taylor e cepstrum. O conteúdo explora os fundamentos matemáticos do Goertzel, sua interpretação como um filtro ressonante discreto e sua aplicação prática em tempo real usando ADC, temporização estável, remoção de offset DC e análise espectral pontual. O projeto é implementado integralmente em linguagem C, sem bibliotecas externas de DSP, e demonstra como detectar a frequência fundamental e harmônicos de um assobio, gerar um score robusto e acionar um LED de forma confiável. Ideal para engenheiros e estudantes que desejam aprofundar conhecimentos em DSP embarcado, otimização de firmware e detecção acústica em sistemas de recursos limitados.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/dsp/deteccao-de-assobio-humano-com-o-algoritmo-de-goertzel-no-rp2040/">Detecção de Assobio Humano com o Algoritmo de Goertzel no RP2040</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<h3 class="wp-block-heading">Continuação da série: <a href="https://mcu.tec.br/?p=1115" title="">Filtragem Digital, Cepstrum e Detecção Acústica em MCU</a></h3>


<div class="root-eb-toc-84t2n wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-84t2n "><div class="eb-toc-container eb-toc-84t2n  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;:3,&quot;content&quot;:&quot;Continua\u00e7\u00e3o da s\u00e9rie: Filtragem Digital, Cepstrum e Detec\u00e7\u00e3o Ac\u00fastica em MCU&quot;,&quot;text&quot;:&quot;Continua\u00e7\u00e3o da s\u00e9rie: Filtragem Digital, Cepstrum e Detec\u00e7\u00e3o Ac\u00fastica em MCU&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1. Introdu\u00e7\u00e3o \u2014 Por que Goertzel?&quot;,&quot;text&quot;:&quot;1. Introdu\u00e7\u00e3o \u2014 Por que Goertzel?&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.1 Estrat\u00e9gia geral adotada neste artigo&quot;,&quot;text&quot;:&quot;1.1 Estrat\u00e9gia geral adotada neste artigo&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.2 Quando Goertzel \u00e9 a escolha correta (e quando n\u00e3o \u00e9)&quot;,&quot;text&quot;:&quot;1.2 Quando Goertzel \u00e9 a escolha correta (e quando n\u00e3o \u00e9)&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.3 Rela\u00e7\u00e3o direta com o artigo anterior&quot;,&quot;text&quot;:&quot;1.3 Rela\u00e7\u00e3o direta com o artigo anterior&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.4 O que voc\u00ea ter\u00e1 ao final deste artigo&quot;,&quot;text&quot;:&quot;1.4 O que voc\u00ea ter\u00e1 ao final deste artigo&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;2 \u2014 Fundamentos matem\u00e1ticos do algoritmo de Goertzel (do zero, passo a passo)&quot;,&quot;text&quot;:&quot;2 \u2014 Fundamentos matem\u00e1ticos do algoritmo de Goertzel (do zero, passo a passo)&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.1 Onde o Goertzel se encaixa no DSP cl\u00e1ssico&quot;,&quot;text&quot;:&quot;2.1 Onde o Goertzel se encaixa no DSP cl\u00e1ssico&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.2 A DFT vista como um \u00fanico bin&quot;,&quot;text&quot;:&quot;2.2 A DFT vista como um \u00fanico bin&quot;,&quot;link&quot;:&quot;eb-table-content-8&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.3 A ideia-chave: um oscilador ressonante discreto&quot;,&quot;text&quot;:&quot;2.3 A ideia-chave: um oscilador ressonante discreto&quot;,&quot;link&quot;:&quot;23-a-ideia-chave-um-oscilador-ressonante-discreto&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.4 Extraindo a energia da frequ\u00eancia&quot;,&quot;text&quot;:&quot;2.4 Extraindo a energia da frequ\u00eancia&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.5 Rela\u00e7\u00e3o com filtros IIR de segunda ordem&quot;,&quot;text&quot;:&quot;2.5 Rela\u00e7\u00e3o com filtros IIR de segunda ordem&quot;,&quot;link&quot;:&quot;eb-table-content-11&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.6 Escolha de (N) e resolu\u00e7\u00e3o em frequ\u00eancia&quot;,&quot;text&quot;:&quot;2.6 Escolha de (N) e resolu\u00e7\u00e3o em frequ\u00eancia&quot;,&quot;link&quot;:&quot;eb-table-content-12&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.7 Como mapeamos frequ\u00eancia real \u2192 \u00edndice (k)&quot;,&quot;text&quot;:&quot;2.7 Como mapeamos frequ\u00eancia real \u2192 \u00edndice (k)&quot;,&quot;link&quot;:&quot;eb-table-content-13&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.8 O que vamos detectar no assobio&quot;,&quot;text&quot;:&quot;2.8 O que vamos detectar no assobio&quot;,&quot;link&quot;:&quot;28-o-que-vamos-detectar-no-assobio&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;3 \u2014 Implementa\u00e7\u00e3o b\u00e1sica do algoritmo de Goertzel em C (isolado, incremental e test\u00e1vel)&quot;,&quot;text&quot;:&quot;3 \u2014 Implementa\u00e7\u00e3o b\u00e1sica do algoritmo de Goertzel em C (isolado, incremental e test\u00e1vel)&quot;,&quot;link&quot;:&quot;eb-table-content-15&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.1 Estrutura de estado do Goertzel&quot;,&quot;text&quot;:&quot;3.1 Estrutura de estado do Goertzel&quot;,&quot;link&quot;:&quot;31-estrutura-de-estado-do-goertzel&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.2 Inicializa\u00e7\u00e3o do detector Goertzel&quot;,&quot;text&quot;:&quot;3.2 Inicializa\u00e7\u00e3o do detector Goertzel&quot;,&quot;link&quot;:&quot;eb-table-content-17&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.3 Passo recursivo do Goertzel (n\u00facleo do algoritmo)&quot;,&quot;text&quot;:&quot;3.3 Passo recursivo do Goertzel (n\u00facleo do algoritmo)&quot;,&quot;link&quot;:&quot;eb-table-content-18&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.4 C\u00e1lculo da energia da frequ\u00eancia&quot;,&quot;text&quot;:&quot;3.4 C\u00e1lculo da energia da frequ\u00eancia&quot;,&quot;link&quot;:&quot;eb-table-content-19&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.5 Reset do estado (para novo frame)&quot;,&quot;text&quot;:&quot;3.5 Reset do estado (para novo frame)&quot;,&quot;link&quot;:&quot;35-reset-do-estado-para-novo-frame&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.6 Teste isolado com sinal sint\u00e9tico (valida\u00e7\u00e3o conceitual)&quot;,&quot;text&quot;:&quot;3.6 Teste isolado com sinal sint\u00e9tico (valida\u00e7\u00e3o conceitual)&quot;,&quot;link&quot;:&quot;eb-table-content-21&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.7 O que aprendemos at\u00e9 aqui&quot;,&quot;text&quot;:&quot;3.7 O que aprendemos at\u00e9 aqui&quot;,&quot;link&quot;:&quot;eb-table-content-22&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;4 \u2014 Goertzel em tempo real no RP2040: ADC + frames + m\u00faltiplas frequ\u00eancias (fundamental e harm\u00f4nicos)&quot;,&quot;text&quot;:&quot;4 \u2014 Goertzel em tempo real no RP2040: ADC + frames + m\u00faltiplas frequ\u00eancias (fundamental e harm\u00f4nicos)&quot;,&quot;link&quot;:&quot;eb-table-content-23&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.1 Definindo o frame e a taxa de amostragem&quot;,&quot;text&quot;:&quot;4.1 Definindo o frame e a taxa de amostragem&quot;,&quot;link&quot;:&quot;41-definindo-o-frame-e-a-taxa-de-amostragem&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.2 Estrat\u00e9gia \u201cGoertzel multibanda\u201d&quot;,&quot;text&quot;:&quot;4.2 Estrat\u00e9gia \u201cGoertzel multibanda\u201d&quot;,&quot;link&quot;:&quot;eb-table-content-25&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.3 Aquisi\u00e7\u00e3o em tempo real (ADC + timer), igual ao artigo anterior&quot;,&quot;text&quot;:&quot;4.3 Aquisi\u00e7\u00e3o em tempo real (ADC + timer), igual ao artigo anterior&quot;,&quot;link&quot;:&quot;eb-table-content-26&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;4.3.1 Buffer de frame (o mesmo padr\u00e3o)&quot;,&quot;text&quot;:&quot;4.3.1 Buffer de frame (o mesmo padr\u00e3o)&quot;,&quot;link&quot;:&quot;eb-table-content-27&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;4.3.2 Leitura ADC normalizada&quot;,&quot;text&quot;:&quot;4.3.2 Leitura ADC normalizada&quot;,&quot;link&quot;:&quot;432-leitura-adc-normalizada&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.4 Pr\u00e9-processamento m\u00ednimo: remo\u00e7\u00e3o de DC por m\u00e9dia m\u00f3vel (mais robusto)&quot;,&quot;text&quot;:&quot;4.4 Pr\u00e9-processamento m\u00ednimo: remo\u00e7\u00e3o de DC por m\u00e9dia m\u00f3vel (mais robusto)&quot;,&quot;link&quot;:&quot;eb-table-content-29&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.5 Varredura com Goertzel (faixa 800\u20133000 Hz)&quot;,&quot;text&quot;:&quot;4.5 Varredura com Goertzel (faixa 800\u20133000 Hz)&quot;,&quot;link&quot;:&quot;45-varredura-com-goertzel-faixa-8003000-hz&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;4.5.1 Fun\u00e7\u00e3o: pot\u00eancia Goertzel para uma frequ\u00eancia f0 em um frame&quot;,&quot;text&quot;:&quot;4.5.1 Fun\u00e7\u00e3o: pot\u00eancia Goertzel para uma frequ\u00eancia f0 em um frame&quot;,&quot;link&quot;:&quot;eb-table-content-31&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.6 Encontrando o candidato de fundamental (pico na faixa)&quot;,&quot;text&quot;:&quot;4.6 Encontrando o candidato de fundamental (pico na faixa)&quot;,&quot;link&quot;:&quot;46-encontrando-o-candidato-de-fundamental-pico-na-faixa&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.7 Confirma\u00e7\u00e3o por harm\u00f4nicos (2f0 e 3f0)&quot;,&quot;text&quot;:&quot;4.7 Confirma\u00e7\u00e3o por harm\u00f4nicos (2f0 e 3f0)&quot;,&quot;link&quot;:&quot;eb-table-content-33&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.8 Integra\u00e7\u00e3o: montar o \u201cprocessador de frame\u201d (ainda sem LED)&quot;,&quot;text&quot;:&quot;4.8 Integra\u00e7\u00e3o: montar o \u201cprocessador de frame\u201d (ainda sem LED)&quot;,&quot;link&quot;:&quot;eb-table-content-34&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;5 \u2014 Decisor completo + LED + otimiza\u00e7\u00f5es (coeficientes pr\u00e9-computados, EMA, histerese) e integra\u00e7\u00e3o no RP2040&quot;,&quot;text&quot;:&quot;5 \u2014 Decisor completo + LED + otimiza\u00e7\u00f5es (coeficientes pr\u00e9-computados, EMA, histerese) e integra\u00e7\u00e3o no RP2040&quot;,&quot;link&quot;:&quot;eb-table-content-35&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.1 Otimiza\u00e7\u00e3o essencial: pr\u00e9-computar os detectores da varredura&quot;,&quot;text&quot;:&quot;5.1 Otimiza\u00e7\u00e3o essencial: pr\u00e9-computar os detectores da varredura&quot;,&quot;link&quot;:&quot;eb-table-content-36&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;5.1.1 Estrutura do \u201cdetector preparado\u201d&quot;,&quot;text&quot;:&quot;5.1.1 Estrutura do \u201cdetector preparado\u201d&quot;,&quot;link&quot;:&quot;511-estrutura-do-detector-preparado&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;5.1.2 Construindo a lista de bins (800\u20133000 Hz, passo 2 bins)&quot;,&quot;text&quot;:&quot;5.1.2 Construindo a lista de bins (800\u20133000 Hz, passo 2 bins)&quot;,&quot;link&quot;:&quot;512-construindo-a-lista-de-bins-8003000-hz-passo-2-bins&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.2 Goertzel \u201cr\u00e1pido\u201d usando coeff pr\u00e9-calculado&quot;,&quot;text&quot;:&quot;5.2 Goertzel \u201cr\u00e1pido\u201d usando coeff pr\u00e9-calculado&quot;,&quot;link&quot;:&quot;eb-table-content-39&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.3 Encontrar o melhor candidato f0 (varredura)&quot;,&quot;text&quot;:&quot;5.3 Encontrar o melhor candidato f0 (varredura)&quot;,&quot;link&quot;:&quot;53-encontrar-o-melhor-candidato-f0-varredura&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.4 Harm\u00f4nicos com c\u00e1lculo \u201con demand\u201d&quot;,&quot;text&quot;:&quot;5.4 Harm\u00f4nicos com c\u00e1lculo \u201con demand\u201d&quot;,&quot;link&quot;:&quot;eb-table-content-41&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.5 Crit\u00e9rio espectral composto (score)&quot;,&quot;text&quot;:&quot;5.5 Crit\u00e9rio espectral composto (score)&quot;,&quot;link&quot;:&quot;eb-table-content-42&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.6 Decis\u00e3o robusta com EMA + histerese&quot;,&quot;text&quot;:&quot;5.6 Decis\u00e3o robusta com EMA + histerese&quot;,&quot;link&quot;:&quot;eb-table-content-43&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.7 Integra\u00e7\u00e3o de tempo real (ADC + DC-block + frame)&quot;,&quot;text&quot;:&quot;5.7 Integra\u00e7\u00e3o de tempo real (ADC + DC-block + frame)&quot;,&quot;link&quot;:&quot;eb-table-content-44&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;5.7.1 DC-block&quot;,&quot;text&quot;:&quot;5.7.1 DC-block&quot;,&quot;link&quot;:&quot;571-dc-block&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;5.7.2 Estado global e callback de amostragem&quot;,&quot;text&quot;:&quot;5.7.2 Estado global e callback de amostragem&quot;,&quot;link&quot;:&quot;572-estado-global-e-callback-de-amostragem&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;5.7.3 Loop processa frame e atualiza LED&quot;,&quot;text&quot;:&quot;5.7.3 Loop processa frame e atualiza LED&quot;,&quot;link&quot;:&quot;573-loop-processa-frame-e-atualiza-led&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;5 \u2014 Decisor completo + LED + otimiza\u00e7\u00f5es (coeficientes pr\u00e9-computados, EMA, histerese) e integra\u00e7\u00e3o no RP2040&quot;,&quot;text&quot;:&quot;5 \u2014 Decisor completo + LED + otimiza\u00e7\u00f5es (coeficientes pr\u00e9-computados, EMA, histerese) e integra\u00e7\u00e3o no RP2040&quot;,&quot;link&quot;:&quot;eb-table-content-48&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.1 Otimiza\u00e7\u00e3o essencial: pr\u00e9-computar os detectores da varredura&quot;,&quot;text&quot;:&quot;5.1 Otimiza\u00e7\u00e3o essencial: pr\u00e9-computar os detectores da varredura&quot;,&quot;link&quot;:&quot;eb-table-content-49&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;5.1.1 Estrutura do \u201cdetector preparado\u201d&quot;,&quot;text&quot;:&quot;5.1.1 Estrutura do \u201cdetector preparado\u201d&quot;,&quot;link&quot;:&quot;511-estrutura-do-detector-preparado&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;5.1.2 Construindo a lista de bins (800\u20133000 Hz, passo 2 bins)&quot;,&quot;text&quot;:&quot;5.1.2 Construindo a lista de bins (800\u20133000 Hz, passo 2 bins)&quot;,&quot;link&quot;:&quot;512-construindo-a-lista-de-bins-8003000-hz-passo-2-bins&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.2 Goertzel \u201cr\u00e1pido\u201d usando coeff pr\u00e9-calculado&quot;,&quot;text&quot;:&quot;5.2 Goertzel \u201cr\u00e1pido\u201d usando coeff pr\u00e9-calculado&quot;,&quot;link&quot;:&quot;eb-table-content-52&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.3 Encontrar o melhor candidato f0 (varredura)&quot;,&quot;text&quot;:&quot;5.3 Encontrar o melhor candidato f0 (varredura)&quot;,&quot;link&quot;:&quot;53-encontrar-o-melhor-candidato-f0-varredura&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.4 Harm\u00f4nicos com c\u00e1lculo \u201con demand\u201d&quot;,&quot;text&quot;:&quot;5.4 Harm\u00f4nicos com c\u00e1lculo \u201con demand\u201d&quot;,&quot;link&quot;:&quot;eb-table-content-54&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.5 Crit\u00e9rio espectral composto (score)&quot;,&quot;text&quot;:&quot;5.5 Crit\u00e9rio espectral composto (score)&quot;,&quot;link&quot;:&quot;eb-table-content-55&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.6 Decis\u00e3o robusta com EMA + histerese&quot;,&quot;text&quot;:&quot;5.6 Decis\u00e3o robusta com EMA + histerese&quot;,&quot;link&quot;:&quot;eb-table-content-56&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.7 Integra\u00e7\u00e3o de tempo real (ADC + DC-block + frame)&quot;,&quot;text&quot;:&quot;5.7 Integra\u00e7\u00e3o de tempo real (ADC + DC-block + frame)&quot;,&quot;link&quot;:&quot;eb-table-content-57&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;5.7.1 DC-block&quot;,&quot;text&quot;:&quot;5.7.1 DC-block&quot;,&quot;link&quot;:&quot;571-dc-block&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;5.7.2 Estado global e callback de amostragem&quot;,&quot;text&quot;:&quot;5.7.2 Estado global e callback de amostragem&quot;,&quot;link&quot;:&quot;572-estado-global-e-callback-de-amostragem&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;5.7.3 Loop processa frame e atualiza LED&quot;,&quot;text&quot;:&quot;5.7.3 Loop processa frame e atualiza LED&quot;,&quot;link&quot;:&quot;573-loop-processa-frame-e-atualiza-led&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;6 \u2014 C\u00f3digo completo e funcional (BitDogLab \/ RP2040) com Goertzel: detec\u00e7\u00e3o de assobio + LED&quot;,&quot;text&quot;:&quot;6 \u2014 C\u00f3digo completo e funcional (BitDogLab \/ RP2040) com Goertzel: detec\u00e7\u00e3o de assobio + LED&quot;,&quot;link&quot;:&quot;eb-table-content-61&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;7 \u2014 Calibra\u00e7\u00e3o pr\u00e1tica, compara\u00e7\u00e3o com o artigo anterior, encerramento e SEO&quot;,&quot;text&quot;:&quot;7 \u2014 Calibra\u00e7\u00e3o pr\u00e1tica, compara\u00e7\u00e3o com o artigo anterior, encerramento e SEO&quot;,&quot;link&quot;:&quot;eb-table-content-62&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.1 Calibra\u00e7\u00e3o pr\u00e1tica (engenharia de campo, n\u00e3o de laborat\u00f3rio)&quot;,&quot;text&quot;:&quot;7.1 Calibra\u00e7\u00e3o pr\u00e1tica (engenharia de campo, n\u00e3o de laborat\u00f3rio)&quot;,&quot;link&quot;:&quot;eb-table-content-63&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.2 Boas escolhas vs. m\u00e1s escolhas (espec\u00edfico do Goertzel)&quot;,&quot;text&quot;:&quot;7.2 Boas escolhas vs. m\u00e1s escolhas (espec\u00edfico do Goertzel)&quot;,&quot;link&quot;:&quot;eb-table-content-64&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.3 Compara\u00e7\u00e3o direta com o artigo anterior (Taylor + Cepstrum)&quot;,&quot;text&quot;:&quot;7.3 Compara\u00e7\u00e3o direta com o artigo anterior (Taylor + Cepstrum)&quot;,&quot;link&quot;:&quot;eb-table-content-65&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.4 Encerramento&quot;,&quot;text&quot;:&quot;7.4 Encerramento&quot;,&quot;link&quot;:&quot;74-encerramento&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Continua\u00e7\u00e3o da s\u00e9rie: Filtragem Digital, Cepstrum e Detec\u00e7\u00e3o Ac\u00fastica em MCU&quot;,&quot;value&quot;:&quot;continua\u00e7\u00e3o-da-s\u00e9rie-filtragem-digital-cepstrum-e-detec\u00e7\u00e3o-ac\u00fastica-em-mcu&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1. Introdu\u00e7\u00e3o \u2014 Por que Goertzel?&quot;,&quot;value&quot;:&quot;1-introdu\u00e7\u00e3o-por-que-goertzel&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.1 Estrat\u00e9gia geral adotada neste artigo&quot;,&quot;value&quot;:&quot;11-estrat\u00e9gia-geral-adotada-neste-artigo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.2 Quando Goertzel \u00e9 a escolha correta (e quando n\u00e3o \u00e9)&quot;,&quot;value&quot;:&quot;12-quando-goertzel-\u00e9-a-escolha-correta-e-quando-n\u00e3o-\u00e9&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.3 Rela\u00e7\u00e3o direta com o artigo anterior&quot;,&quot;value&quot;:&quot;13-rela\u00e7\u00e3o-direta-com-o-artigo-anterior&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.4 O que voc\u00ea ter\u00e1 ao final deste artigo&quot;,&quot;value&quot;:&quot;14-o-que-voc\u00ea-ter\u00e1-ao-final-deste-artigo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2 \u2014 Fundamentos matem\u00e1ticos do algoritmo de Goertzel (do zero, passo a passo)&quot;,&quot;value&quot;:&quot;2-fundamentos-matem\u00e1ticos-do-algoritmo-de-goertzel-do-zero-passo-a-passo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.1 Onde o Goertzel se encaixa no DSP cl\u00e1ssico&quot;,&quot;value&quot;:&quot;21-onde-o-goertzel-se-encaixa-no-dsp-cl\u00e1ssico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.2 A DFT vista como um \u00fanico bin&quot;,&quot;value&quot;:&quot;22-a-dft-vista-como-um-\u00fanico-bin&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.3 A ideia-chave: um oscilador ressonante discreto&quot;,&quot;value&quot;:&quot;23-a-ideia-chave-um-oscilador-ressonante-discreto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.4 Extraindo a energia da frequ\u00eancia&quot;,&quot;value&quot;:&quot;24-extraindo-a-energia-da-frequ\u00eancia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.5 Rela\u00e7\u00e3o com filtros IIR de segunda ordem&quot;,&quot;value&quot;:&quot;25-rela\u00e7\u00e3o-com-filtros-iir-de-segunda-ordem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.6 Escolha de (N) e resolu\u00e7\u00e3o em frequ\u00eancia&quot;,&quot;value&quot;:&quot;26-escolha-de-n-e-resolu\u00e7\u00e3o-em-frequ\u00eancia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.7 Como mapeamos frequ\u00eancia real \u2192 \u00edndice (k)&quot;,&quot;value&quot;:&quot;27-como-mapeamos-frequ\u00eancia-real-\u2192-\u00edndice-k&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.8 O que vamos detectar no assobio&quot;,&quot;value&quot;:&quot;28-o-que-vamos-detectar-no-assobio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3 \u2014 Implementa\u00e7\u00e3o b\u00e1sica do algoritmo de Goertzel em C (isolado, incremental e test\u00e1vel)&quot;,&quot;value&quot;:&quot;3-implementa\u00e7\u00e3o-b\u00e1sica-do-algoritmo-de-goertzel-em-c-isolado-incremental-e-test\u00e1vel&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.1 Estrutura de estado do Goertzel&quot;,&quot;value&quot;:&quot;31-estrutura-de-estado-do-goertzel&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.2 Inicializa\u00e7\u00e3o do detector Goertzel&quot;,&quot;value&quot;:&quot;32-inicializa\u00e7\u00e3o-do-detector-goertzel&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.3 Passo recursivo do Goertzel (n\u00facleo do algoritmo)&quot;,&quot;value&quot;:&quot;33-passo-recursivo-do-goertzel-n\u00facleo-do-algoritmo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.4 C\u00e1lculo da energia da frequ\u00eancia&quot;,&quot;value&quot;:&quot;34-c\u00e1lculo-da-energia-da-frequ\u00eancia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.5 Reset do estado (para novo frame)&quot;,&quot;value&quot;:&quot;35-reset-do-estado-para-novo-frame&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.6 Teste isolado com sinal sint\u00e9tico (valida\u00e7\u00e3o conceitual)&quot;,&quot;value&quot;:&quot;36-teste-isolado-com-sinal-sint\u00e9tico-valida\u00e7\u00e3o-conceitual&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.7 O que aprendemos at\u00e9 aqui&quot;,&quot;value&quot;:&quot;37-o-que-aprendemos-at\u00e9-aqui&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4 \u2014 Goertzel em tempo real no RP2040: ADC + frames + m\u00faltiplas frequ\u00eancias (fundamental e harm\u00f4nicos)&quot;,&quot;value&quot;:&quot;4-goertzel-em-tempo-real-no-rp2040-adc-frames-m\u00faltiplas-frequ\u00eancias-fundamental-e-harm\u00f4nicos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.1 Definindo o frame e a taxa de amostragem&quot;,&quot;value&quot;:&quot;41-definindo-o-frame-e-a-taxa-de-amostragem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.2 Estrat\u00e9gia \u201cGoertzel multibanda\u201d&quot;,&quot;value&quot;:&quot;42-estrat\u00e9gia-goertzel-multibanda&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.3 Aquisi\u00e7\u00e3o em tempo real (ADC + timer), igual ao artigo anterior&quot;,&quot;value&quot;:&quot;43-aquisi\u00e7\u00e3o-em-tempo-real-adc-timer-igual-ao-artigo-anterior&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.3.1 Buffer de frame (o mesmo padr\u00e3o)&quot;,&quot;value&quot;:&quot;431-buffer-de-frame-o-mesmo-padr\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.3.2 Leitura ADC normalizada&quot;,&quot;value&quot;:&quot;432-leitura-adc-normalizada&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.4 Pr\u00e9-processamento m\u00ednimo: remo\u00e7\u00e3o de DC por m\u00e9dia m\u00f3vel (mais robusto)&quot;,&quot;value&quot;:&quot;44-pr\u00e9-processamento-m\u00ednimo-remo\u00e7\u00e3o-de-dc-por-m\u00e9dia-m\u00f3vel-mais-robusto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.5 Varredura com Goertzel (faixa 800\u20133000 Hz)&quot;,&quot;value&quot;:&quot;45-varredura-com-goertzel-faixa-8003000-hz&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.5.1 Fun\u00e7\u00e3o: pot\u00eancia Goertzel para uma frequ\u00eancia f0 em um frame&quot;,&quot;value&quot;:&quot;451-fun\u00e7\u00e3o-pot\u00eancia-goertzel-para-uma-frequ\u00eancia-f0-em-um-frame&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.6 Encontrando o candidato de fundamental (pico na faixa)&quot;,&quot;value&quot;:&quot;46-encontrando-o-candidato-de-fundamental-pico-na-faixa&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.7 Confirma\u00e7\u00e3o por harm\u00f4nicos (2f0 e 3f0)&quot;,&quot;value&quot;:&quot;47-confirma\u00e7\u00e3o-por-harm\u00f4nicos-2f0-e-3f0&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.8 Integra\u00e7\u00e3o: montar o \u201cprocessador de frame\u201d (ainda sem LED)&quot;,&quot;value&quot;:&quot;48-integra\u00e7\u00e3o-montar-o-processador-de-frame-ainda-sem-led&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5 \u2014 Decisor completo + LED + otimiza\u00e7\u00f5es (coeficientes pr\u00e9-computados, EMA, histerese) e integra\u00e7\u00e3o no RP2040&quot;,&quot;value&quot;:&quot;5-decisor-completo-led-otimiza\u00e7\u00f5es-coeficientes-pr\u00e9-computados-ema-histerese-e-integra\u00e7\u00e3o-no-rp2040&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.1 Otimiza\u00e7\u00e3o essencial: pr\u00e9-computar os detectores da varredura&quot;,&quot;value&quot;:&quot;51-otimiza\u00e7\u00e3o-essencial-pr\u00e9-computar-os-detectores-da-varredura&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.1.1 Estrutura do \u201cdetector preparado\u201d&quot;,&quot;value&quot;:&quot;511-estrutura-do-detector-preparado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.1.2 Construindo a lista de bins (800\u20133000 Hz, passo 2 bins)&quot;,&quot;value&quot;:&quot;512-construindo-a-lista-de-bins-8003000-hz-passo-2-bins&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.2 Goertzel \u201cr\u00e1pido\u201d usando coeff pr\u00e9-calculado&quot;,&quot;value&quot;:&quot;52-goertzel-r\u00e1pido-usando-coeff-pr\u00e9-calculado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.3 Encontrar o melhor candidato f0 (varredura)&quot;,&quot;value&quot;:&quot;53-encontrar-o-melhor-candidato-f0-varredura&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.4 Harm\u00f4nicos com c\u00e1lculo \u201con demand\u201d&quot;,&quot;value&quot;:&quot;54-harm\u00f4nicos-com-c\u00e1lculo-on-demand&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.5 Crit\u00e9rio espectral composto (score)&quot;,&quot;value&quot;:&quot;55-crit\u00e9rio-espectral-composto-score&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.6 Decis\u00e3o robusta com EMA + histerese&quot;,&quot;value&quot;:&quot;56-decis\u00e3o-robusta-com-ema-histerese&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.7 Integra\u00e7\u00e3o de tempo real (ADC + DC-block + frame)&quot;,&quot;value&quot;:&quot;57-integra\u00e7\u00e3o-de-tempo-real-adc-dc-block-frame&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.7.1 DC-block&quot;,&quot;value&quot;:&quot;571-dc-block&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.7.2 Estado global e callback de amostragem&quot;,&quot;value&quot;:&quot;572-estado-global-e-callback-de-amostragem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.7.3 Loop processa frame e atualiza LED&quot;,&quot;value&quot;:&quot;573-loop-processa-frame-e-atualiza-led&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5 \u2014 Decisor completo + LED + otimiza\u00e7\u00f5es (coeficientes pr\u00e9-computados, EMA, histerese) e integra\u00e7\u00e3o no RP2040&quot;,&quot;value&quot;:&quot;5-decisor-completo-led-otimiza\u00e7\u00f5es-coeficientes-pr\u00e9-computados-ema-histerese-e-integra\u00e7\u00e3o-no-rp2040&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.1 Otimiza\u00e7\u00e3o essencial: pr\u00e9-computar os detectores da varredura&quot;,&quot;value&quot;:&quot;51-otimiza\u00e7\u00e3o-essencial-pr\u00e9-computar-os-detectores-da-varredura&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.1.1 Estrutura do \u201cdetector preparado\u201d&quot;,&quot;value&quot;:&quot;511-estrutura-do-detector-preparado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.1.2 Construindo a lista de bins (800\u20133000 Hz, passo 2 bins)&quot;,&quot;value&quot;:&quot;512-construindo-a-lista-de-bins-8003000-hz-passo-2-bins&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.2 Goertzel \u201cr\u00e1pido\u201d usando coeff pr\u00e9-calculado&quot;,&quot;value&quot;:&quot;52-goertzel-r\u00e1pido-usando-coeff-pr\u00e9-calculado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.3 Encontrar o melhor candidato f0 (varredura)&quot;,&quot;value&quot;:&quot;53-encontrar-o-melhor-candidato-f0-varredura&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.4 Harm\u00f4nicos com c\u00e1lculo \u201con demand\u201d&quot;,&quot;value&quot;:&quot;54-harm\u00f4nicos-com-c\u00e1lculo-on-demand&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.5 Crit\u00e9rio espectral composto (score)&quot;,&quot;value&quot;:&quot;55-crit\u00e9rio-espectral-composto-score&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.6 Decis\u00e3o robusta com EMA + histerese&quot;,&quot;value&quot;:&quot;56-decis\u00e3o-robusta-com-ema-histerese&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.7 Integra\u00e7\u00e3o de tempo real (ADC + DC-block + frame)&quot;,&quot;value&quot;:&quot;57-integra\u00e7\u00e3o-de-tempo-real-adc-dc-block-frame&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.7.1 DC-block&quot;,&quot;value&quot;:&quot;571-dc-block&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.7.2 Estado global e callback de amostragem&quot;,&quot;value&quot;:&quot;572-estado-global-e-callback-de-amostragem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.7.3 Loop processa frame e atualiza LED&quot;,&quot;value&quot;:&quot;573-loop-processa-frame-e-atualiza-led&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6 \u2014 C\u00f3digo completo e funcional (BitDogLab \/ RP2040) com Goertzel: detec\u00e7\u00e3o de assobio + LED&quot;,&quot;value&quot;:&quot;6-c\u00f3digo-completo-e-funcional-bitdoglab-rp2040-com-goertzel-detec\u00e7\u00e3o-de-assobio-led&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7 \u2014 Calibra\u00e7\u00e3o pr\u00e1tica, compara\u00e7\u00e3o com o artigo anterior, encerramento e SEO&quot;,&quot;value&quot;:&quot;7-calibra\u00e7\u00e3o-pr\u00e1tica-compara\u00e7\u00e3o-com-o-artigo-anterior-encerramento-e-seo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.1 Calibra\u00e7\u00e3o pr\u00e1tica (engenharia de campo, n\u00e3o de laborat\u00f3rio)&quot;,&quot;value&quot;:&quot;71-calibra\u00e7\u00e3o-pr\u00e1tica-engenharia-de-campo-n\u00e3o-de-laborat\u00f3rio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.2 Boas escolhas vs. m\u00e1s escolhas (espec\u00edfico do Goertzel)&quot;,&quot;value&quot;:&quot;72-boas-escolhas-vs-m\u00e1s-escolhas-espec\u00edfico-do-goertzel&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.3 Compara\u00e7\u00e3o direta com o artigo anterior (Taylor + Cepstrum)&quot;,&quot;value&quot;:&quot;73-compara\u00e7\u00e3o-direta-com-o-artigo-anterior-taylor-cepstrum&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.4 Encerramento&quot;,&quot;value&quot;:&quot;74-encerramento&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">Continuação da série: Filtragem Digital, Cepstrum e Detecção Acústica em MCU</a><li><a href="#eb-table-content-1">1. Introdução — Por que Goertzel?</a><li><a href="#eb-table-content-2">1.1 Estratégia geral adotada neste artigo</a><li><a href="#eb-table-content-3">1.2 Quando Goertzel é a escolha correta (e quando não é)</a><li><a href="#eb-table-content-4">1.3 Relação direta com o artigo anterior</a><li><a href="#eb-table-content-5">1.4 O que você terá ao final deste artigo</a><li><a href="#eb-table-content-6">2 — Fundamentos matemáticos do algoritmo de Goertzel (do zero, passo a passo)</a><ul class="eb-toc__list"><li><a href="#eb-table-content-7">2.1 Onde o Goertzel se encaixa no DSP clássico</a><li><a href="#eb-table-content-8">2.2 A DFT vista como um único bin</a><li><a href="#23-a-ideia-chave-um-oscilador-ressonante-discreto">2.3 A ideia-chave: um oscilador ressonante discreto</a><li><a href="#eb-table-content-10">2.4 Extraindo a energia da frequência</a><li><a href="#eb-table-content-11">2.5 Relação com filtros IIR de segunda ordem</a><li><a href="#eb-table-content-12">2.6 Escolha de (N) e resolução em frequência</a><li><a href="#eb-table-content-13">2.7 Como mapeamos frequência real → índice (k)</a><li><a href="#28-o-que-vamos-detectar-no-assobio">2.8 O que vamos detectar no assobio</a></li></ul><li><a href="#eb-table-content-15">3 — Implementação básica do algoritmo de Goertzel em C (isolado, incremental e testável)</a><ul class="eb-toc__list"><li><a href="#31-estrutura-de-estado-do-goertzel">3.1 Estrutura de estado do Goertzel</a><li><a href="#eb-table-content-17">3.2 Inicialização do detector Goertzel</a><li><a href="#eb-table-content-18">3.3 Passo recursivo do Goertzel (núcleo do algoritmo)</a><li><a href="#eb-table-content-19">3.4 Cálculo da energia da frequência</a><li><a href="#35-reset-do-estado-para-novo-frame">3.5 Reset do estado (para novo frame)</a><li><a href="#eb-table-content-21">3.6 Teste isolado com sinal sintético (validação conceitual)</a><li><a href="#eb-table-content-22">3.7 O que aprendemos até aqui</a></li></ul><li><a href="#eb-table-content-23">4 — Goertzel em tempo real no RP2040: ADC + frames + múltiplas frequências (fundamental e harmônicos)</a><ul class="eb-toc__list"><li><a href="#41-definindo-o-frame-e-a-taxa-de-amostragem">4.1 Definindo o frame e a taxa de amostragem</a><li><a href="#eb-table-content-25">4.2 Estratégia “Goertzel multibanda”</a><li><a href="#eb-table-content-26">4.3 Aquisição em tempo real (ADC + timer), igual ao artigo anterior</a><ul class="eb-toc__list"><li><a href="#eb-table-content-27">4.3.1 Buffer de frame (o mesmo padrão)</a><li><a href="#432-leitura-adc-normalizada">4.3.2 Leitura ADC normalizada</a></li></ul><li><a href="#eb-table-content-29">4.4 Pré-processamento mínimo: remoção de DC por média móvel (mais robusto)</a><li><a href="#45-varredura-com-goertzel-faixa-8003000-hz">4.5 Varredura com Goertzel (faixa 800–3000 Hz)</a><ul class="eb-toc__list"><li><a href="#eb-table-content-31">4.5.1 Função: potência Goertzel para uma frequência f0 em um frame</a></li></ul><li><a href="#46-encontrando-o-candidato-de-fundamental-pico-na-faixa">4.6 Encontrando o candidato de fundamental (pico na faixa)</a><li><a href="#eb-table-content-33">4.7 Confirmação por harmônicos (2f0 e 3f0)</a><li><a href="#eb-table-content-34">4.8 Integração: montar o “processador de frame” (ainda sem LED)</a></li></ul><li><a href="#eb-table-content-35">5 — Decisor completo + LED + otimizações (coeficientes pré-computados, EMA, histerese) e integração no RP2040</a><ul class="eb-toc__list"><li><a href="#eb-table-content-36">5.1 Otimização essencial: pré-computar os detectores da varredura</a><ul class="eb-toc__list"><li><a href="#511-estrutura-do-detector-preparado">5.1.1 Estrutura do “detector preparado”</a><li><a href="#512-construindo-a-lista-de-bins-8003000-hz-passo-2-bins">5.1.2 Construindo a lista de bins (800–3000 Hz, passo 2 bins)</a></li></ul><li><a href="#eb-table-content-39">5.2 Goertzel “rápido” usando coeff pré-calculado</a><li><a href="#53-encontrar-o-melhor-candidato-f0-varredura">5.3 Encontrar o melhor candidato f0 (varredura)</a><li><a href="#eb-table-content-41">5.4 Harmônicos com cálculo “on demand”</a><li><a href="#eb-table-content-42">5.5 Critério espectral composto (score)</a><li><a href="#eb-table-content-43">5.6 Decisão robusta com EMA + histerese</a><li><a href="#eb-table-content-44">5.7 Integração de tempo real (ADC + DC-block + frame)</a><ul class="eb-toc__list"><li><a href="#571-dc-block">5.7.1 DC-block</a><li><a href="#572-estado-global-e-callback-de-amostragem">5.7.2 Estado global e callback de amostragem</a><li><a href="#573-loop-processa-frame-e-atualiza-led">5.7.3 Loop processa frame e atualiza LED</a></li></ul></li></ul><li><a href="#eb-table-content-48">5 — Decisor completo + LED + otimizações (coeficientes pré-computados, EMA, histerese) e integração no RP2040</a><ul class="eb-toc__list"><li><a href="#eb-table-content-49">5.1 Otimização essencial: pré-computar os detectores da varredura</a><ul class="eb-toc__list"><li><a href="#511-estrutura-do-detector-preparado">5.1.1 Estrutura do “detector preparado”</a><li><a href="#512-construindo-a-lista-de-bins-8003000-hz-passo-2-bins">5.1.2 Construindo a lista de bins (800–3000 Hz, passo 2 bins)</a></li></ul><li><a href="#eb-table-content-52">5.2 Goertzel “rápido” usando coeff pré-calculado</a><li><a href="#53-encontrar-o-melhor-candidato-f0-varredura">5.3 Encontrar o melhor candidato f0 (varredura)</a><li><a href="#eb-table-content-54">5.4 Harmônicos com cálculo “on demand”</a><li><a href="#eb-table-content-55">5.5 Critério espectral composto (score)</a><li><a href="#eb-table-content-56">5.6 Decisão robusta com EMA + histerese</a><li><a href="#eb-table-content-57">5.7 Integração de tempo real (ADC + DC-block + frame)</a><ul class="eb-toc__list"><li><a href="#571-dc-block">5.7.1 DC-block</a><li><a href="#572-estado-global-e-callback-de-amostragem">5.7.2 Estado global e callback de amostragem</a><li><a href="#573-loop-processa-frame-e-atualiza-led">5.7.3 Loop processa frame e atualiza LED</a></li></ul></li></ul><li><a href="#eb-table-content-61">6 — Código completo e funcional (BitDogLab / RP2040) com Goertzel: detecção de assobio + LED</a><li><a href="#eb-table-content-62">7 — Calibração prática, comparação com o artigo anterior, encerramento e SEO</a><ul class="eb-toc__list"><li><a href="#eb-table-content-63">7.1 Calibração prática (engenharia de campo, não de laboratório)</a><li><a href="#eb-table-content-64">7.2 Boas escolhas vs. más escolhas (específico do Goertzel)</a><li><a href="#eb-table-content-65">7.3 Comparação direta com o artigo anterior (Taylor + Cepstrum)</a><li><a href="#74-encerramento">7.4 Encerramento</a></li></ul></ul></div></div></div></div></div>


<h3 class="wp-block-heading">1. Introdução — Por que Goertzel?</h3>



<p class="wp-block-paragraph">No artigo anterior desta série, exploramos uma abordagem baseada em <strong>filtragem digital construída com Séries de Taylor</strong>, seguida pelo <strong>cálculo do cepstrum</strong>, para identificar a periodicidade característica de um assobio humano. Aquela estratégia privilegiou uma análise <strong>global do espectro</strong>, permitindo identificar a estrutura harmônica do sinal de forma robusta, mesmo em ambientes com ruído.</p>



<p class="wp-block-paragraph">Neste novo artigo, damos continuidade direta a essa série, adotando <strong>uma estratégia complementar e mais enxuta</strong>: o <strong>algoritmo de Goertzel</strong>. Em vez de calcular todo o espectro via FFT, o Goertzel permite <strong>extrair seletivamente a energia de frequências específicas</strong>, tornando-o ideal para microcontroladores com recursos limitados — como o RP2040 — quando o interesse está restrito a <strong>faixas bem definidas</strong>.</p>



<p class="wp-block-paragraph">O assobio humano típico apresenta uma frequência fundamental relativamente estável, geralmente entre <strong>800 Hz e 3000 Hz</strong>, com harmônicos previsíveis. O algoritmo de Goertzel explora exatamente esse cenário:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><em>“Eu sei qual frequência quero detectar — e só ela importa.”</em></p>
</blockquote>



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



<h3 class="wp-block-heading">1.1 Estratégia geral adotada neste artigo</h3>



<p class="wp-block-paragraph">A arquitetura de processamento deste artigo será:</p>



<ol class="wp-block-list">
<li><strong>Aquisição do sinal acústico</strong> (ADC do RP2040)</li>



<li><strong>Pré-processamento simples</strong> (remoção de DC e normalização)</li>



<li><strong>Aplicação do algoritmo de Goertzel</strong> para:
<ul class="wp-block-list">
<li>Frequência fundamental</li>



<li>Harmônicos selecionados</li>
</ul>
</li>



<li><strong>Construção de um critério de decisão espectral</strong></li>



<li><strong>Confirmação temporal</strong> (evitar falsos positivos)</li>



<li><strong>Acionamento de um LED</strong> quando o assobio é detectado</li>
</ol>



<p class="wp-block-paragraph">Diferentemente do artigo anterior:</p>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Não calcularemos FFT</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Não calcularemos cepstrum</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Usaremos <strong>análise espectral pontual</strong></li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Menor uso de RAM e CPU</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Menor latência</li>
</ul>



<p class="wp-block-paragraph">Isso permite uma comparação clara entre duas filosofias de DSP embarcado:</p>



<ul class="wp-block-list">
<li><strong>FFT + Cepstrum → análise estrutural</strong></li>



<li><strong>Goertzel → análise dirigida por frequência</strong></li>
</ul>



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



<h3 class="wp-block-heading">1.2 Quando Goertzel é a escolha correta (e quando não é)</h3>



<p class="wp-block-paragraph"><strong>Goertzel é uma excelente escolha quando:</strong></p>



<ul class="wp-block-list">
<li>Você conhece as frequências de interesse</li>



<li>O número de frequências é pequeno</li>



<li>O MCU possui RAM limitada</li>



<li>A latência precisa ser baixa</li>



<li>O sistema é reativo (event-driven)</li>
</ul>



<p class="wp-block-paragraph"><strong>Goertzel NÃO é a melhor escolha quando:</strong></p>



<ul class="wp-block-list">
<li>A frequência fundamental varia muito</li>



<li>Você precisa analisar o espectro completo</li>



<li>O sinal tem múltiplas fontes concorrentes</li>



<li>A estrutura harmônica é desconhecida</li>
</ul>



<p class="wp-block-paragraph">Este artigo assume explicitamente o <strong>caso ideal para Goertzel</strong>:<br><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;" /> <em>detectar um fenômeno acústico específico e conhecido</em>.</p>



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



<h3 class="wp-block-heading">1.3 Relação direta com o artigo anterior</h3>



<p class="wp-block-paragraph">Este artigo <strong>não substitui</strong> o anterior — ele o <strong>complementa</strong>.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Artigo anterior</th><th>Este artigo</th></tr></thead><tbody><tr><td>Séries de Taylor</td><td>Goertzel</td></tr><tr><td>FFT + Cepstrum</td><td>Análise pontual</td></tr><tr><td>Estrutura harmônica global</td><td>Frequência-alvo</td></tr><tr><td>Mais matemática</td><td>Mais eficiência</td></tr><tr><td>Mais flexível</td><td>Mais determinístico</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">A ideia da série é exatamente essa: <strong>mostrar estratégias diferentes para o mesmo problema</strong>, permitindo ao engenheiro escolher conscientemente.</p>



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



<h3 class="wp-block-heading">1.4 O que você terá ao final deste artigo</h3>



<p class="wp-block-paragraph">Ao final deste artigo, você terá:</p>



<ul class="wp-block-list">
<li>Um <strong>detector de assobio funcional</strong></li>



<li>Código <strong>100% em C</strong>, portátil</li>



<li>Execução em <strong>tempo real no RP2040</strong></li>



<li>Arquitetura reutilizável para:
<ul class="wp-block-list">
<li>DTMF</li>



<li>Tons de controle</li>



<li>Alarmes acústicos</li>



<li>Interfaces sonoras simples</li>
</ul>
</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/algoritimos/dsp/deteccao-de-assobio-humano-com-o-algoritmo-de-goertzel-no-rp2040/">Detecção de Assobio Humano com o Algoritmo de Goertzel no RP2040</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1125</post-id>	</item>
	</channel>
</rss>
