<?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>engenharia de software embarcado - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/engenharia-de-software-embarcado/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Sat, 03 May 2025 20:56:33 +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>engenharia de software embarcado - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Interfaces Sensoriais Desacopladas: Modularidade e Testabilidade em Sistemas Embarcados</title>
		<link>https://mcu.tec.br/algoritimos/interfaces-sensoriais-desacopladas-modularidade-e-testabilidade-em-sistemas-embarcados/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=interfaces-sensoriais-desacopladas-modularidade-e-testabilidade-em-sistemas-embarcados</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sun, 04 May 2025 20:49:20 +0000</pubDate>
				<category><![CDATA[Algoritimos]]></category>
		<category><![CDATA[abstração de hardware]]></category>
		<category><![CDATA[abstração de sensores]]></category>
		<category><![CDATA[arquitetura de sensores]]></category>
		<category><![CDATA[arquitetura desacoplada]]></category>
		<category><![CDATA[desacoplamento de sensores]]></category>
		<category><![CDATA[desenvolvimento embarcado]]></category>
		<category><![CDATA[design modular para sensores]]></category>
		<category><![CDATA[drivers de sensores]]></category>
		<category><![CDATA[engenharia de firmware]]></category>
		<category><![CDATA[engenharia de software embarcado]]></category>
		<category><![CDATA[estratégia de teste de firmware]]></category>
		<category><![CDATA[firmware modular]]></category>
		<category><![CDATA[HAL em microcontroladores]]></category>
		<category><![CDATA[independência de hardware]]></category>
		<category><![CDATA[integração de sensores]]></category>
		<category><![CDATA[interfaces genéricas em C]]></category>
		<category><![CDATA[interfaces sensoriais desacopladas]]></category>
		<category><![CDATA[leitura de sensores em C]]></category>
		<category><![CDATA[manutenção de sistemas embarcados]]></category>
		<category><![CDATA[mock de sensores em C]]></category>
		<category><![CDATA[padrão adapter C]]></category>
		<category><![CDATA[padrões de projeto em C]]></category>
		<category><![CDATA[padronização de sensores]]></category>
		<category><![CDATA[ponteiros de função em C]]></category>
		<category><![CDATA[reutilização de código embarcado]]></category>
		<category><![CDATA[sensor API em microcontroladores]]></category>
		<category><![CDATA[sensor driver isolation]]></category>
		<category><![CDATA[sensor físico]]></category>
		<category><![CDATA[sensor plug-and-play]]></category>
		<category><![CDATA[sensor virtual]]></category>
		<category><![CDATA[sensores embarcados]]></category>
		<category><![CDATA[sensores intercambiáveis]]></category>
		<category><![CDATA[simulação de sensores]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[teste de sensores simulados]]></category>
		<category><![CDATA[testes em sistemas embarcados]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=487</guid>

					<description><![CDATA[<p>Este artigo explora o conceito de interfaces sensoriais desacopladas no contexto de sistemas embarcados. Através de exemplos práticos e padrões de projeto consagrados como Adapter, Proxy e Bridge, o leitor aprenderá como implementar sensores modulares e facilmente substituíveis. O texto detalha os benefícios do desacoplamento, apresenta estratégias reais de implementação em C e mostra como sensores simulados podem ser utilizados em testes e simulações. Ideal para engenheiros de firmware, estudantes e profissionais que desenvolvem sistemas confiáveis e escaláveis.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/interfaces-sensoriais-desacopladas-modularidade-e-testabilidade-em-sistemas-embarcados/">Interfaces Sensoriais Desacopladas: Modularidade e Testabilidade em Sistemas Embarcados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Imagine que você está projetando um sistema embarcado para monitorar a qualidade do ar. Esse sistema inclui sensores de gás, umidade e temperatura, que alimentam dados para um microcontrolador. Agora, suponha que, por alguma razão, o fabricante do sensor de gás decida descontinuar o componente. Se o seu código estiver diretamente acoplado à interface e protocolo daquele sensor específico, a substituição por um novo modelo exigirá alterações profundas e arriscadas em todo o sistema.</p>



<p class="wp-block-paragraph">Por isso, surge o conceito de <strong>interfaces sensoriais desacopladas</strong>. Essa abordagem se baseia em separar a lógica de aquisição e processamento de dados do sensor da lógica de aplicação que consome esses dados. Essa separação é feita através de interfaces bem definidas que permitem que o sensor seja substituído, atualizado ou simulado sem afetar o restante do sistema. Trata-se de uma prática essencial em arquitetura de software para sistemas embarcados, especialmente quando se busca reusabilidade, escalabilidade e manutenção simplificada.</p>



<p class="wp-block-paragraph">No contexto de sistemas em tempo real e embarcados, essa técnica é frequentemente associada a padrões de projeto como <em>Proxy</em>, <em>Observer</em>, <em>Adapter</em> e até <em>Component-Based Architecture</em>. O conceito também está fortemente alinhado aos princípios de desenvolvimento dirigidos por interface (interface-driven development), que promovem a padronização e o isolamento de dependências de hardware.</p>



<h3 class="wp-block-heading">Problema a Ser Resolvido</h3>



<p class="wp-block-paragraph">O desenvolvimento de sistemas embarcados muitas vezes parte da integração direta entre sensores e o restante da aplicação, especialmente em projetos de pequeno porte ou provas de conceito. Essa abordagem, ainda que funcional em curto prazo, se revela problemática à medida que o sistema cresce ou sofre manutenções.</p>



<p class="wp-block-paragraph">O acoplamento direto entre o código da aplicação e os drivers dos sensores cria uma relação de dependência forte. Isso significa que qualquer modificação no sensor — seja por substituição do modelo, mudança no protocolo de comunicação (como de I2C para SPI), alteração no intervalo de amostragem ou até mesmo diferenças sutis de precisão — exige uma reestruturação que pode afetar não apenas o código do driver, mas também partes significativas da lógica de negócio.</p>



<p class="wp-block-paragraph">Além disso, sensores reais são recursos físicos sujeitos a falhas, desgaste ou simplesmente indisponibilidade em fases iniciais do projeto. Isso dificulta o desenvolvimento paralelo e o uso de simulações ou testes automatizados, pois a ausência de uma interface desacoplada impede a substituição do sensor por um gerador de dados sintéticos ou módulo de simulação.</p>



<p class="wp-block-paragraph">Outro ponto crítico é a portabilidade. Sistemas embarcados muitas vezes são projetados para migrar entre plataformas — de um microcontrolador AVR para um STM32, por exemplo — e sem uma abstração clara entre o hardware sensor e o restante do sistema, esse processo se torna custoso, trabalhoso e propenso a erros.</p>



<p class="wp-block-paragraph">Portanto, o problema reside no risco técnico e na inflexibilidade associados ao acoplamento direto entre sensores e aplicação. A ausência de uma interface sensorial desacoplada limita a evolução do projeto, a sua testabilidade, a reutilização de componentes e até a resiliência frente a falhas de fornecimento ou alteração tecnológica.</p>



<h3 class="wp-block-heading">Princípios e Estrutura de Interfaces Sensoriais Desacopladas</h3>



<p class="wp-block-paragraph">A estrutura de uma interface sensorial desacoplada repousa sobre um princípio fundamental da engenharia de software: <strong>programar para uma interface, não para uma implementação</strong>. Na prática, isso significa que o código da aplicação não deve conhecer os detalhes de funcionamento de um sensor específico, mas apenas interagir com ele por meio de um contrato (interface) bem definido.</p>



<p class="wp-block-paragraph">Essa estrutura pode ser visualizada em três camadas principais:</p>



<ol class="wp-block-list">
<li><strong>Interface Sensorial Abstrata</strong><br>Trata-se de uma definição genérica, usualmente expressa em termos de uma <em>classe abstrata</em> (em C++) ou uma <em>estrutura com ponteiros para funções</em> (em C). Ela define operações como <code>read_data()</code>, <code>initialize()</code>, <code>shutdown()</code> ou <code>calibrate()</code>. Essas operações são independentes do protocolo físico, fabricante ou modelo do sensor.</li>



<li><strong>Implementações Concretas</strong><br>Cada sensor específico implementa essa interface com suas particularidades. Por exemplo, um sensor de temperatura TMP36 usando ADC terá uma implementação diferente de um DHT22 que usa sinal digital com temporização. Ainda assim, ambos expõem a mesma interface, o que garante que a aplicação possa alternar entre eles sem ser reescrita.</li>



<li><strong>Camada de Aplicação</strong><br>A lógica da aplicação consome os dados de forma padronizada, podendo inclusive fazer uso de sensores simulados (mocks) para testes, sensores virtuais em ambientes de simulação ou sensores reais conectados via drivers físicos. A aplicação permanece imune às mudanças que ocorram abaixo da interface.</li>
</ol>



<p class="wp-block-paragraph"><strong>Exemplo prático em C:</strong><br>Imagine um sistema com dois sensores de temperatura diferentes:</p>



<pre class="wp-block-preformatted">cCopiarEditar<code>typedef struct {
    float (*read_temperature)(void);
    void (*initialize)(void);
} TempSensorInterface;

float tmp36_read() { /* leitura via ADC */ }
void tmp36_init() { /* init ADC */ }

float dht22_read() { /* leitura digital */ }
void dht22_init() { /* init DHT protocolo */ }

TempSensorInterface tmp36 = { tmp36_read, tmp36_init };
TempSensorInterface dht22 = { dht22_read, dht22_init };

// No código da aplicação:
void use_sensor(TempSensorInterface* sensor) {
    sensor-&gt;initialize();
    float temp = sensor-&gt;read_temperature();
    printf("Temperatura: %.2f °C\n", temp);
}
</code></pre>



<p class="wp-block-paragraph">Dessa forma, a aplicação <code>use_sensor()</code> pode receber qualquer sensor que implemente essa interface, inclusive um sensor simulado para teste de software:</p>



<pre class="wp-block-preformatted">cCopiarEditar<code>float fake_temp_read() { return 25.0; }
void fake_temp_init() {}

TempSensorInterface simulated = { fake_temp_read, fake_temp_init };
</code></pre>



<p class="wp-block-paragraph">A flexibilidade dessa estrutura permite que a lógica da aplicação continue funcional independentemente de mudanças no hardware ou no ambiente de desenvolvimento.</p>



<h3 class="wp-block-heading">Vantagens e Benefícios do Desacoplamento Sensorial</h3>



<p class="wp-block-paragraph">A adoção de interfaces sensoriais desacopladas oferece uma série de vantagens concretas para o desenvolvimento de sistemas embarcados, tanto do ponto de vista técnico quanto estratégico. Vamos explorar esses benefícios em três dimensões: <strong>manutenção e evolução do sistema</strong>, <strong>testabilidade e qualidade de software</strong>, e <strong>reutilização e escalabilidade</strong>.</p>



<h4 class="wp-block-heading">1. Manutenção e Evolução do Sistema</h4>



<p class="wp-block-paragraph">Ao desacoplar sensores da lógica de aplicação, torna-se possível substituir, atualizar ou até eliminar sensores físicos sem reescrever o código de alto nível. Isso é particularmente valioso quando um sensor se torna obsoleto, sofre alterações de firmware ou precisa ser adaptado para diferentes ambientes (por exemplo, substituição de um sensor de temperatura interno por um sensor externo com sonda).</p>



<p class="wp-block-paragraph">Além disso, o desacoplamento torna o sistema mais <strong>resiliente à obsolescência tecnológica</strong>. Em aplicações industriais, onde o ciclo de vida de um produto pode se estender por décadas, ter a flexibilidade para trocar componentes sem comprometer o sistema é vital.</p>



<h4 class="wp-block-heading">2. Testabilidade e Qualidade de Software</h4>



<p class="wp-block-paragraph">Com interfaces desacopladas, é trivial introduzir <strong>sensores simulados</strong> (mocks) ou <strong>fontes de dados gravadas</strong> durante o desenvolvimento e os testes. Isso permite:</p>



<ul class="wp-block-list">
<li>Realizar testes unitários automatizados sem necessidade de hardware.</li>



<li>Reproduzir comportamentos específicos como falhas, valores fora da faixa, ruído ou latência artificial.</li>



<li>Executar o sistema completo em modo de simulação, facilitando a integração com interfaces gráficas ou softwares de visualização.</li>
</ul>



<p class="wp-block-paragraph">Dessa forma, o ciclo de desenvolvimento se torna mais rápido e confiável, com menos dependência de acesso ao hardware físico.</p>



<h4 class="wp-block-heading">3. Reutilização e Escalabilidade</h4>



<p class="wp-block-paragraph">Projetos que seguem a filosofia de desacoplamento sensorial tendem a gerar <strong>módulos reutilizáveis</strong>. Um módulo de leitura de temperatura, por exemplo, pode ser aproveitado em diversos projetos distintos — desde um termômetro portátil até um sistema de climatização industrial — desde que ambos adotem a mesma interface.</p>



<p class="wp-block-paragraph">Além disso, esse modelo permite escalar o sistema com facilidade. É possível, por exemplo, combinar sensores físicos com sensores virtuais (como estimativas baseadas em modelo matemático) sem alterar a aplicação. Em arquiteturas distribuídas, também é comum abstrair sensores remotos conectados por BLE, Wi-Fi ou CAN bus como se fossem sensores locais, graças ao uso de interfaces desacopladas.</p>



<p class="wp-block-paragraph">Em resumo, as interfaces sensoriais desacopladas promovem <strong>robustez, adaptabilidade, portabilidade, testabilidade e reusabilidade</strong>, pilares fundamentais de qualquer projeto de engenharia bem estruturado.</p>



<h3 class="wp-block-heading">Padrões de Projeto Relacionados</h3>



<p class="wp-block-paragraph">A construção de interfaces sensoriais desacopladas se fundamenta em diversos padrões clássicos de projeto de software. Estes padrões oferecem soluções comprovadas para os problemas de acoplamento, encapsulamento e extensão modular. A seguir, destacamos os mais relevantes no contexto de sistemas embarcados.</p>



<h4 class="wp-block-heading">1. <strong>Adapter (Adaptador)</strong></h4>



<p class="wp-block-paragraph">O padrão Adapter permite que uma classe com uma interface incompatível seja utilizada em um sistema que espera uma interface específica. No contexto sensorial, é comum criar adaptadores que convertem o protocolo e os métodos de sensores legados ou heterogêneos para um formato comum esperado pela aplicação.</p>



<p class="wp-block-paragraph">Por exemplo, se um sensor de temperatura comunica-se via UART e outro via I2C, mas ambos devem expor a função <code>read_temperature()</code>, o Adapter pode encapsular os detalhes de protocolo, oferecendo uma interface unificada.</p>



<h4 class="wp-block-heading">2. <strong>Proxy (Representante ou Substituto)</strong></h4>



<p class="wp-block-paragraph">O padrão Proxy é útil quando queremos adicionar funcionalidades extras ao acesso ao sensor, como cache de dados, limitação de frequência de leitura ou monitoramento de consumo. Um proxy pode também ser utilizado para representar sensores virtuais, como estimativas ou simulações, que respondem da mesma forma que os sensores físicos.</p>



<p class="wp-block-paragraph">Em testes, proxies podem substituir sensores reais por componentes simulados sem que a aplicação perceba a diferença.</p>



<h4 class="wp-block-heading">3. <strong>Bridge (Ponte)</strong></h4>



<p class="wp-block-paragraph">Bridge é um padrão que separa uma abstração de sua implementação, permitindo que ambas evoluam independentemente. Aplicado a sensores, permite que o tipo de dado (por exemplo, temperatura, pressão, umidade) seja desacoplado do meio de aquisição (SPI, ADC, rede), tornando o código altamente modular e reutilizável.</p>



<h4 class="wp-block-heading">4. <strong>Observer (Observador)</strong></h4>



<p class="wp-block-paragraph">No caso de sensores que disparam eventos (por exemplo, detecção de movimento ou alarme de fumaça), o padrão Observer permite que vários módulos da aplicação se registrem como ouvintes (listeners) e reajam de forma assíncrona à chegada dos dados. Isso torna o sistema reativo e desacoplado de polling explícito.</p>



<h4 class="wp-block-heading">5. <strong>Strategy (Estratégia)</strong></h4>



<p class="wp-block-paragraph">Quando múltiplos algoritmos de interpretação de dados sensoriais são possíveis (por exemplo, diferentes filtros ou calibrações), o padrão Strategy permite alternar dinamicamente a forma como os dados são processados, mantendo a leitura desacoplada da lógica de decisão.</p>



<h4 class="wp-block-heading">6. <strong>Factory Method (Fábrica)</strong></h4>



<p class="wp-block-paragraph">A criação de sensores pode ser encapsulada em fábricas, o que permite decidir dinamicamente qual sensor será instanciado com base em configurações externas, detecção automática ou parâmetros de compilação.</p>



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



<p class="wp-block-paragraph">Esses padrões não são mutuamente exclusivos. Um sistema robusto frequentemente utiliza uma combinação deles para atingir níveis elevados de modularidade e confiabilidade. Em um sistema real, pode-se ter sensores instanciados por uma fábrica, acessados por meio de proxies, encapsulados por adaptadores e monitorados por observadores, tudo operando sob uma ponte entre abstrações e implementações.</p>



<h3 class="wp-block-heading">Estratégias de Implementação em Sistemas Embarcados</h3>



<p class="wp-block-paragraph">A implementação prática de interfaces sensoriais desacopladas em sistemas embarcados exige atenção a aspectos como limitações de recursos, tempo real, e integração com periféricos específicos. A seguir, apresento estratégias concretas que equilibram desempenho, modularidade e simplicidade.</p>



<h4 class="wp-block-heading">1. <strong>Uso de Ponteiros para Funções em C</strong></h4>



<p class="wp-block-paragraph">Linguagens como C, muito comuns em sistemas embarcados, não possuem suporte nativo a interfaces e polimorfismo. Para contornar isso, uma prática comum é o uso de <strong>estruturas contendo ponteiros para funções</strong>, simulando uma interface de acesso. Cada driver de sensor implementa seus próprios métodos, que são então atribuídos à estrutura comum.</p>



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



<pre class="wp-block-preformatted">cCopiarEditar<code>typedef struct {
    void (*init)(void);
    float (*read_value)(void);
} SensorInterface;

SensorInterface temp_sensor = {
    .init = tmp36_init,
    .read_value = tmp36_read
};
</code></pre>



<p class="wp-block-paragraph">Isso permite que a aplicação invoque <code>temp_sensor.read_value()</code> sem saber qual sensor físico está por trás.</p>



<h4 class="wp-block-heading">2. <strong>Camada HAL (Hardware Abstraction Layer)</strong></h4>



<p class="wp-block-paragraph">Outra estratégia é a introdução de uma <strong>camada de abstração de hardware (HAL)</strong>, que separa os registros e periféricos do microcontrolador da lógica de negócio. A HAL define funções genéricas como <code>HAL_Read_Temperature()</code>, enquanto implementações específicas para cada sensor são feitas em módulos independentes.</p>



<p class="wp-block-paragraph">Essa abordagem facilita a portabilidade entre diferentes plataformas (por exemplo, trocar um STM32 por um RP2040) e promove reuso de código.</p>



<h4 class="wp-block-heading">3. <strong>Separação por Arquivos e Convenção de Interface</strong></h4>



<p class="wp-block-paragraph">Organizar os sensores em arquivos distintos, cada um com sua própria implementação da interface, ajuda a manter o projeto organizado. É comum ter uma convenção onde cada sensor implementa funções como:</p>



<pre class="wp-block-preformatted">cCopiarEditar<code>void sensorX_init(void);
float sensorX_read(void);
</code></pre>



<p class="wp-block-paragraph">Essas funções são então registradas em tempo de inicialização ou via uma fábrica sensorial que escolhe o driver conforme configuração de tempo de compilação ou leitura de EEPROM/flash.</p>



<h4 class="wp-block-heading">4. <strong>Tabelas de Dispositivos e Auto-Detecção</strong></h4>



<p class="wp-block-paragraph">Em sistemas mais avançados, pode-se montar uma <strong>tabela de sensores disponíveis</strong>. Cada entrada aponta para a interface e metadados do sensor (ID, fabricante, tipo, intervalo de leitura). Isso facilita a criação de sistemas auto-configuráveis ou modulares, onde os sensores podem ser adicionados ou removidos dinamicamente.</p>



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



<pre class="wp-block-preformatted">cCopiarEditar<code>typedef struct {
    const char* name;
    SensorInterface* interface;
} SensorEntry;

SensorEntry sensors[] = {
    { "TMP36", &amp;tmp36_interface },
    { "DHT22", &amp;dht22_interface },
};
</code></pre>



<h4 class="wp-block-heading">5. <strong>Simulação e Testes com Sensores Virtuais</strong></h4>



<p class="wp-block-paragraph">Durante o desenvolvimento ou em sistemas com <em>failover</em>, sensores virtuais ou simulados podem ser utilizados. Basta substituir o ponteiro de função real por uma função que gera dados sintéticos:</p>



<pre class="wp-block-preformatted">cCopiarEditar<code>float simulated_read() { return 22.5 + sin(time_now()); }
</code></pre>



<p class="wp-block-paragraph">Isso permite testes offline ou uso em ambiente de simulação gráfica.</p>



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



<p class="wp-block-paragraph">A escolha da melhor estratégia depende do contexto do projeto, mas todas partilham o objetivo de criar uma separação clara entre <em>quem coleta os dados</em> e <em>quem usa os dados</em>, favorecendo manutenção, testes e evolução.</p>



<h3 class="wp-block-heading">Modelo de Amostragem e Exemplo Completo</h3>



<p class="wp-block-paragraph">Para consolidar os conceitos apresentados, vejamos um exemplo prático de como implementar uma interface sensorial desacoplada em um sistema embarcado simples, escrito em C. Suponhamos que temos dois sensores de temperatura disponíveis: o TMP36 (analógico) e o DHT22 (digital). Nosso sistema precisa apenas ler a temperatura e exibi-la, sem se importar com os detalhes de aquisição.</p>



<h4 class="wp-block-heading">Etapa 1: Definindo a Interface Sensorial</h4>



<p class="wp-block-paragraph">Criamos uma estrutura que representa nossa interface genérica de sensor de temperatura:</p>



<pre class="wp-block-preformatted">cCopiarEditar<code>typedef struct {
    void (*init)(void);
    float (*read_temperature)(void);
} TemperatureSensor;
</code></pre>



<p class="wp-block-paragraph">Essa estrutura define um contrato que qualquer sensor de temperatura precisa seguir: uma função de inicialização e uma função de leitura.</p>



<h4 class="wp-block-heading">Etapa 2: Implementações Concretas</h4>



<p class="wp-block-paragraph"><strong>TMP36 (analógico via ADC):</strong></p>



<pre class="wp-block-preformatted">cCopiarEditar<code>#include "adc_driver.h"

void tmp36_init(void) {
    adc_init();
}

float tmp36_read_temperature(void) {
    int adc_value = adc_read(); // valor entre 0 e 1023
    float voltage = (adc_value * 3.3f) / 1023.0f;
    return (voltage - 0.5f) * 100.0f; // fórmula do TMP36
}

TemperatureSensor tmp36_sensor = {
    .init = tmp36_init,
    .read_temperature = tmp36_read_temperature
};
</code></pre>



<p class="wp-block-paragraph"><strong>DHT22 (digital via protocolo):</strong></p>



<pre class="wp-block-preformatted">cCopiarEditar<code>#include "dht_driver.h"

void dht22_init(void) {
    dht_setup();
}

float dht22_read_temperature(void) {
    return dht_get_temperature();
}

TemperatureSensor dht22_sensor = {
    .init = dht22_init,
    .read_temperature = dht22_read_temperature
};
</code></pre>



<h4 class="wp-block-heading">Etapa 3: Aplicação Usando Interface Desacoplada</h4>



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

void run_temperature_app(TemperatureSensor* sensor) {
    sensor-&gt;init();
    while (1) {
        float temp = sensor-&gt;read_temperature();
        printf("Temperatura atual: %.2f °C\n", temp);
        delay_ms(1000);
    }
}
</code></pre>



<p class="wp-block-paragraph">A função <code>run_temperature_app()</code> é completamente desacoplada da origem dos dados. Podemos executar:</p>



<pre class="wp-block-preformatted">cCopiarEditar<code>run_temperature_app(&amp;tmp36_sensor);
// ou
run_temperature_app(&amp;dht22_sensor);
// ou até
run_temperature_app(&amp;simulated_sensor);
</code></pre>



<h4 class="wp-block-heading">Etapa 4: Sensor Simulado para Testes</h4>



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

float simulated_temperature(void) {
    static int t = 0;
    t++;
    return 25.0f + 2.0f * sinf(t * 0.1f); // variação senoidal
}

void simulated_init(void) {
    // nada a fazer
}

TemperatureSensor simulated_sensor = {
    .init = simulated_init,
    .read_temperature = simulated_temperature
};
</code></pre>



<p class="wp-block-paragraph">Esse sensor pode ser usado em testes automatizados, ambientes virtuais ou para demonstrar o sistema em laboratório sem hardware real.</p>



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



<h3 class="wp-block-heading">Conclusão</h3>



<p class="wp-block-paragraph">Interfaces sensoriais desacopladas representam uma abordagem elegante, robusta e escalável para o desenvolvimento de sistemas embarcados. Elas permitem que aplicações sejam mais modulares, testáveis e adaptáveis às inevitáveis mudanças de hardware que ocorrem ao longo do ciclo de vida de um produto.</p>



<p class="wp-block-paragraph">Ao adotar esse modelo, engenheiros embarcados reduzem o risco de retrabalho, promovem reutilização de código e constroem sistemas mais resilientes — qualidades essenciais em projetos industriais, acadêmicos ou comerciais.</p><p>The post <a href="https://mcu.tec.br/algoritimos/interfaces-sensoriais-desacopladas-modularidade-e-testabilidade-em-sistemas-embarcados/">Interfaces Sensoriais Desacopladas: Modularidade e Testabilidade 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">487</post-id>	</item>
	</channel>
</rss>
