<?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>automação industrial - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/automacao-industrial/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Wed, 04 Feb 2026 20:08:01 +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>automação industrial - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Titan RA8P1: Placa com Cortex-M85 para AIoT, Ethernet, RT-Thread e Depuração CMSIS-DAP</title>
		<link>https://mcu.tec.br/microcontroladores/renesas/titan-ra8p1-placa-com-cortex-m85-para-aiot-ethernet-rt-thread-e-depuracao-cmsis-dap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=titan-ra8p1-placa-com-cortex-m85-para-aiot-ethernet-rt-thread-e-depuracao-cmsis-dap</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Wed, 04 Feb 2026 20:07:55 +0000</pubDate>
				<category><![CDATA[RENESAS]]></category>
		<category><![CDATA[AIoT]]></category>
		<category><![CDATA[Armv8.1-M]]></category>
		<category><![CDATA[automação industrial]]></category>
		<category><![CDATA[CMSIS-DAP]]></category>
		<category><![CDATA[Cortex-M]]></category>
		<category><![CDATA[Cortex-M85]]></category>
		<category><![CDATA[depuração SWD]]></category>
		<category><![CDATA[Ethernet embarcado]]></category>
		<category><![CDATA[GDB]]></category>
		<category><![CDATA[Helium MVE]]></category>
		<category><![CDATA[microcontrolador de alto desempenho]]></category>
		<category><![CDATA[Renesas RA8P1]]></category>
		<category><![CDATA[RT-Thread]]></category>
		<category><![CDATA[RT-Thread Studio]]></category>
		<category><![CDATA[sistemas embarcados avançados]]></category>
		<category><![CDATA[Titan RA8P1]]></category>
		<category><![CDATA[TrustZone-M]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1261</guid>

					<description><![CDATA[<p>A Titan RA8P1 é uma placa de desenvolvimento avançada baseada no microcontrolador Renesas RA8P1 com núcleo Arm Cortex-M85, projetada para aplicações modernas de AIoT, automação industrial e sistemas embarcados de alto desempenho. O artigo apresenta uma análise técnica detalhada da arquitetura Armv8.1-M, das extensões vetoriais Helium (MVE), dos recursos de segurança como TrustZone-M e do conjunto robusto de periféricos integrados, incluindo Ethernet, UART, SPI, I²C, ADCs de alta resolução, timers avançados e GPIOs para expansão. Também é discutido o ecossistema de software fornecido pelo RT-Thread, com BSP oficial, exemplos práticos e integração total com a RT-Thread Studio, permitindo desenvolvimento escalável e profissional. O texto aprofunda o fluxo de depuração via CMSIS-DAP, compatível com GDB e IDEs modernas, destacando como esse padrão facilita análise de firmware, debug em tempo real e manutenção de sistemas complexos. A Titan RA8P1 é apresentada como uma plataforma sólida para pesquisa aplicada, prototipação e produtos finais, unindo desempenho, determinismo, conectividade e segurança em um único ambiente de desenvolvimento.</p>
<p>The post <a href="https://mcu.tec.br/microcontroladores/renesas/titan-ra8p1-placa-com-cortex-m85-para-aiot-ethernet-rt-thread-e-depuracao-cmsis-dap/">Titan RA8P1: Placa com Cortex-M85 para AIoT, Ethernet, RT-Thread e Depuração CMSIS-DAP</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-ha4pb wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-ha4pb "><div class="eb-toc-container eb-toc-ha4pb  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 microcontrolador RA8P1 e a arquitetura Cortex-M85&quot;,&quot;text&quot;:&quot;O microcontrolador RA8P1 e a arquitetura Cortex-M85&quot;,&quot;link&quot;:&quot;o-microcontrolador-ra8p1-e-a-arquitetura-cortex-m85&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Perif\u00e9ricos e interfaces dispon\u00edveis na Titan RA8P1&quot;,&quot;text&quot;:&quot;Perif\u00e9ricos e interfaces dispon\u00edveis na Titan RA8P1&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Suporte de software, BSP oficial e RT-Thread Studio&quot;,&quot;text&quot;:&quot;Suporte de software, BSP oficial e RT-Thread Studio&quot;,&quot;link&quot;:&quot;suporte-de-software-bsp-oficial-e-rt-thread-studio&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Depura\u00e7\u00e3o, CMSIS-DAP e fluxo profissional de debug&quot;,&quot;text&quot;:&quot;Depura\u00e7\u00e3o, CMSIS-DAP e fluxo profissional de debug&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Cen\u00e1rios de aplica\u00e7\u00e3o, posicionamento t\u00e9cnico e conclus\u00e3o&quot;,&quot;text&quot;:&quot;Cen\u00e1rios de aplica\u00e7\u00e3o, posicionamento t\u00e9cnico e conclus\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;O microcontrolador RA8P1 e a arquitetura Cortex-M85&quot;,&quot;value&quot;:&quot;o-microcontrolador-ra8p1-e-a-arquitetura-cortex-m85&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Perif\u00e9ricos e interfaces dispon\u00edveis na Titan RA8P1&quot;,&quot;value&quot;:&quot;perif\u00e9ricos-e-interfaces-dispon\u00edveis-na-titan-ra8p1&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Suporte de software, BSP oficial e RT-Thread Studio&quot;,&quot;value&quot;:&quot;suporte-de-software-bsp-oficial-e-rt-thread-studio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Depura\u00e7\u00e3o, CMSIS-DAP e fluxo profissional de debug&quot;,&quot;value&quot;:&quot;depura\u00e7\u00e3o-cmsis-dap-e-fluxo-profissional-de-debug&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Cen\u00e1rios de aplica\u00e7\u00e3o, posicionamento t\u00e9cnico e conclus\u00e3o&quot;,&quot;value&quot;:&quot;cen\u00e1rios-de-aplica\u00e7\u00e3o-posicionamento-t\u00e9cnico-e-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="#o-microcontrolador-ra8p1-e-a-arquitetura-cortex-m85">O microcontrolador RA8P1 e a arquitetura Cortex-M85</a><li><a href="#eb-table-content-1">Periféricos e interfaces disponíveis na Titan RA8P1</a><li><a href="#suporte-de-software-bsp-oficial-e-rt-thread-studio">Suporte de software, BSP oficial e RT-Thread Studio</a><li><a href="#eb-table-content-3">Depuração, CMSIS-DAP e fluxo profissional de debug</a><li><a href="#eb-table-content-4">Cenários de aplicação, posicionamento técnico e conclusão</a></ul></div></div></div></div></div>


<p class="wp-block-paragraph">A Titan RA8P1 é uma placa de desenvolvimento avançada concebida para explorar todo o potencial da família RA8 da <strong>Renesas</strong>, combinando alto desempenho em tempo real, recursos modernos de segurança e suporte nativo a aplicações de AIoT. No centro da placa está o microcontrolador RA8P1, baseado no núcleo Arm Cortex-M85, que representa uma mudança importante no patamar de desempenho dos microcontroladores clássicos, aproximando-os de cenários antes restritos a MPUs, mas mantendo o determinismo e a simplicidade típicos de sistemas embarcados bare-metal ou RTOS.</p>



<p class="wp-block-paragraph">A proposta da Titan RA8P1 vai além de “mais uma placa de avaliação”. Ela foi pensada como uma plataforma de referência para desenvolvimento profissional, com foco explícito em sistemas conectados, aplicações industriais, edge AI e prototipação rápida de produtos. Isso se reflete tanto no conjunto de periféricos disponíveis quanto na infraestrutura de software que a acompanha, com integração direta ao ecossistema do <strong>RT-Thread</strong>, incluindo BSP oficial, exemplos prontos e suporte completo pela RT-Thread Studio.</p>



<p class="wp-block-paragraph">Do ponto de vista de hardware, a placa expõe uma quantidade generosa de interfaces de comunicação, recursos de temporização avançados, aceleração matemática e mecanismos de segurança embarcados. Esse conjunto permite desenvolver desde aplicações tradicionais de controle e automação até pipelines mais sofisticados de aquisição de sinais, inferência local e comunicação segura com a nuvem. A presença de recursos como Ethernet, múltiplas interfaces seriais e suporte a memória externa posiciona a Titan RA8P1 como uma base sólida para gateways IoT e dispositivos industriais conectados.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="720" height="494" src="https://mcu.tec.br/wp-content/uploads/2026/02/image-2.png" alt="" class="wp-image-1263" srcset="https://mcu.tec.br/wp-content/uploads/2026/02/image-2.png 720w, https://mcu.tec.br/wp-content/uploads/2026/02/image-2-300x206.png 300w" sizes="(max-width: 720px) 100vw, 720px" /></figure>
</div>


<p class="wp-block-paragraph">Outro ponto que merece destaque já nesta introdução é a preocupação com o ciclo completo de desenvolvimento. A Titan RA8P1 oferece suporte a depuração profissional via CMSIS-DAP, integrando-se de forma transparente a IDEs modernas e a fluxos baseados em GDB. Isso reduz drasticamente o atrito entre protótipo e produto final, permitindo que o desenvolvedor trabalhe com breakpoints, inspeção de registradores, análise de memória e trace de forma confiável, algo essencial em projetos de maior complexidade técnica.</p><p>The post <a href="https://mcu.tec.br/microcontroladores/renesas/titan-ra8p1-placa-com-cortex-m85-para-aiot-ethernet-rt-thread-e-depuracao-cmsis-dap/">Titan RA8P1: Placa com Cortex-M85 para AIoT, Ethernet, RT-Thread e Depuração CMSIS-DAP</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1261</post-id>	</item>
		<item>
		<title>STM32V8: o novo microcontrolador da ST com Cortex-M85, PCM e tecnologia 18 nm FD-SOI</title>
		<link>https://mcu.tec.br/microcontroladores/stm32/stm32v8-o-novo-microcontrolador-da-st-com-cortex-m85-pcm-e-tecnologia-18-nm-fd-soi/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=stm32v8-o-novo-microcontrolador-da-st-com-cortex-m85-pcm-e-tecnologia-18-nm-fd-soi</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Tue, 16 Dec 2025 21:32:02 +0000</pubDate>
				<category><![CDATA[STM32]]></category>
		<category><![CDATA[automação industrial]]></category>
		<category><![CDATA[Cortex-M85]]></category>
		<category><![CDATA[DSP embarcado]]></category>
		<category><![CDATA[Edge AI]]></category>
		<category><![CDATA[FD-SOI 18 nm]]></category>
		<category><![CDATA[inteligência artificial embarcada]]></category>
		<category><![CDATA[memória PCM]]></category>
		<category><![CDATA[microcontrolador de alto desempenho]]></category>
		<category><![CDATA[microcontrolador ST]]></category>
		<category><![CDATA[Renesas RA8M1]]></category>
		<category><![CDATA[sistemas embarcados avançados]]></category>
		<category><![CDATA[stm32]]></category>
		<category><![CDATA[STM32V8]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1032</guid>

					<description><![CDATA[<p>O STM32V8 é a nova família de microcontroladores de alto desempenho da STMicroelectronics, baseada no núcleo Arm Cortex-M85 e fabricada em tecnologia avançada de 18 nm FD-SOI com memória não volátil do tipo PCM integrada. Este artigo apresenta uma análise técnica e prática do STM32V8, explorando sua arquitetura de fabricação, sistema de memória, capacidades de DSP e inteligência artificial embarcada, além de suas aplicações em automação industrial, edge computing, robótica e sistemas ciberfísicos. Também é realizada uma comparação objetiva com o Renesas RA8M1, destacando diferenças em arquitetura, memória, eficiência energética e escalabilidade tecnológica. O conteúdo é voltado a engenheiros, desenvolvedores de firmware e profissionais de sistemas embarcados que buscam compreender os avanços que definem a próxima geração de microcontroladores.</p>
<p>The post <a href="https://mcu.tec.br/microcontroladores/stm32/stm32v8-o-novo-microcontrolador-da-st-com-cortex-m85-pcm-e-tecnologia-18-nm-fd-soi/">STM32V8: o novo microcontrolador da ST com Cortex-M85, PCM e tecnologia 18 nm FD-SOI</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2 class="wp-block-heading"><strong>o surgimento do STM32V8 e uma nova geração de microcontroladores de alto desempenho</strong></h2>



<p class="wp-block-paragraph">A STMicroelectronics anunciou recentemente a família <strong>STM32V8</strong>, marcando um avanço significativo na evolução dos microcontroladores de uso geral e industrial. Diferentemente das gerações anteriores da linha STM32, o STM32V8 foi concebido desde a origem para atender aplicações que exigem <strong>altíssimo desempenho computacional</strong>, <strong>baixa latência</strong>, <strong>eficiência energética</strong> e <strong>capacidade de executar algoritmos avançados</strong>, incluindo inteligência artificial embarcada, controle em tempo real e processamento digital de sinais.</p>



<p class="wp-block-paragraph">O grande diferencial tecnológico do STM32V8 está no uso de um <strong>processo de fabricação em 18 nm FD-SOI (Fully Depleted Silicon On Insulator)</strong>, aliado à integração de <strong>memória não volátil do tipo PCM (Phase-Change Memory)</strong> diretamente no chip. Essa combinação permite à ST superar limitações clássicas dos microcontroladores baseados em Flash tradicional, como latência de acesso à memória, consumo energético elevado durante escrita e restrições de escalabilidade em nós tecnológicos mais avançados.</p>



<p class="wp-block-paragraph">No núcleo computacional, o STM32V8 é baseado no <strong>Arm Cortex-M85</strong>, atualmente o núcleo mais poderoso da família Cortex-M. Esse núcleo oferece suporte nativo a <strong>extensões Helium (M-Profile Vector Extension)</strong> para aceleração de DSP (Processamento Digital de Sinais) e workloads de machine learning, além de um pipeline mais profundo e recursos avançados de predição e paralelismo interno. Com frequências de operação significativamente mais altas que gerações anteriores, o STM32V8 se posiciona como um microcontrolador que começa a ocupar o espaço tradicionalmente reservado a microprocessadores de entrada, porém mantendo as vantagens de um MCU: determinismo, baixo consumo e integração periférica.</p>



<p class="wp-block-paragraph">Do ponto de vista prático, a ST posiciona o STM32V8 para aplicações como <strong>controle industrial avançado</strong>, <strong>robótica</strong>, <strong>automação predial e fabril</strong>, <strong>dispositivos médicos</strong>, <strong>edge AI</strong>, <strong>sensoriamento inteligente</strong> e <strong>sistemas ciberfísicos</strong>. O objetivo é permitir que arquiteturas antes dependentes de SoCs com Linux ou coprocessadores externos possam ser implementadas em um único microcontrolador, reduzindo custo, consumo, complexidade de software e requisitos de certificação.</p>



<p class="wp-block-paragraph">Essa nova família não substitui as linhas STM32 já consolidadas (como STM32F, G, H ou U), mas inaugura uma <strong>nova classe de MCU dentro do portfólio da ST</strong>, voltada explicitamente para aplicações que exigem o máximo desempenho possível dentro do ecossistema Cortex-M. Nas próximas seções, serão detalhados os pilares tecnológicos do STM32V8, começando pela sua <strong>arquitetura de fabricação e sistema de memória</strong>, e posteriormente avançando para núcleo, periféricos, segurança e uma comparação técnica objetiva com o <strong>Renesas RA8M1</strong>.</p>



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



<h2 class="wp-block-heading"><strong>Seção 2 – Tecnologia de Fabricação do STM32V8: 18 nm FD-SOI e Memória PCM</strong></h2>



<p class="wp-block-paragraph">Um dos aspectos mais disruptivos do <strong>STM32V8</strong> não está apenas no núcleo Cortex-M85, mas principalmente na <strong>tecnologia de fabricação adotada pela STMicroelectronics</strong>. Pela primeira vez em microcontroladores de uso geral, a ST emprega um processo <strong>18 nm FD-SOI (Fully Depleted Silicon On Insulator)</strong> combinado com <strong>memória não volátil do tipo PCM (Phase-Change Memory)</strong> integrada no próprio chip. Essa escolha tem implicações diretas em desempenho, consumo, confiabilidade e escalabilidade tecnológica.</p>



<p class="wp-block-paragraph">A tecnologia <strong>FD-SOI</strong> difere significativamente do CMOS convencional utilizado em processos mais antigos (40 nm, 65 nm, 90 nm). No FD-SOI, o transistor é construído sobre uma camada isolante extremamente fina, o que reduz drasticamente correntes parasitas, melhora o controle eletrostático do canal e diminui a variabilidade dos transistores. Na prática, isso se traduz em <strong>menor consumo dinâmico e estático</strong>, <strong>maior frequência de operação</strong> e <strong>melhor comportamento térmico</strong>, fatores críticos para sistemas embarcados que operam 24/7 ou em ambientes industriais severos.</p>



<p class="wp-block-paragraph">Outro benefício importante do FD-SOI é a possibilidade de <strong>body biasing dinâmico</strong>, técnica que permite ajustar o limiar de tensão dos transistores por software ou hardware. Isso dá ao projetista a capacidade de <strong>priorizar desempenho ou eficiência energética em tempo real</strong>, algo particularmente relevante em aplicações que alternam entre modos de processamento intenso e estados de baixo consumo. Em um microcontrolador de alto desempenho como o STM32V8, esse recurso amplia significativamente a flexibilidade arquitetural do sistema.</p>



<p class="wp-block-paragraph">Complementando o processo de 18 nm, a ST substituiu a Flash tradicional por <strong>memória PCM (Phase-Change Memory)</strong>. Diferente da Flash, a PCM não depende de tunelamento de elétrons através de óxidos finos, o que elimina vários gargalos clássicos: latência elevada de leitura, alto consumo durante escrita e desgaste acelerado com ciclos de programação/apagamento. A PCM permite <strong>leituras praticamente tão rápidas quanto SRAM</strong>, com <strong>maior densidade</strong> e <strong>excelente retenção de dados</strong>, mesmo em temperaturas elevadas.</p>



<p class="wp-block-paragraph">Do ponto de vista prático de firmware, a presença da PCM impacta diretamente a forma como o código é executado. O STM32V8 consegue operar em <strong>execução direta da memória não volátil (XIP – Execute In Place)</strong> sem as penalidades comuns da Flash, reduzindo ou até eliminando a necessidade de copiar rotinas críticas para RAM. Isso simplifica o linker script, reduz o uso de SRAM e melhora o determinismo temporal — um ponto fundamental para <strong>RTOS, controle em tempo real e aplicações safety-critical</strong>.</p>



<p class="wp-block-paragraph">Além disso, a PCM é naturalmente mais adequada a nós tecnológicos avançados, o que garante <strong>longevidade à família STM32V8</strong>. Enquanto a Flash enfrenta sérias dificuldades de escalabilidade abaixo de 28 nm, a PCM se mantém viável em processos ainda menores, preparando o caminho para futuras evoluções da linha sem rupturas arquiteturais. Para desenvolvedores e fabricantes de equipamentos, isso significa <strong>maior segurança de investimento e continuidade de plataforma</strong>.</p>



<p class="wp-block-paragraph">Na próxima seção, entraremos no coração computacional do STM32V8, analisando em detalhes o <strong>núcleo Arm Cortex-M85</strong>, suas extensões vetoriais, impacto prático em DSP e inteligência artificial embarcada, e como isso redefine o limite do que se espera de um microcontrolador.</p>



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



<h2 class="wp-block-heading"><strong>Núcleo Arm Cortex-M85 no STM32V8: Desempenho, DSP e Inteligência Artificial Embarcada</strong></h2>



<p class="wp-block-paragraph">No centro do <strong>STM32V8</strong> está o <strong>Arm Cortex-M85</strong>, atualmente o núcleo mais avançado da família Cortex-M. Sua adoção não representa apenas um incremento incremental de desempenho, mas sim uma mudança de patamar naquilo que é possível executar em um microcontrolador sem recorrer a microprocessadores ou aceleradores externos. A ST posiciona o STM32V8 como uma plataforma capaz de consolidar <strong>controle em tempo real, processamento de sinais e inferência de modelos de inteligência artificial</strong> em um único dispositivo.</p>



<p class="wp-block-paragraph">O Cortex-M85 introduz um pipeline mais profundo e otimizado em relação a núcleos anteriores como o Cortex-M7 ou M33, permitindo frequências de operação significativamente mais altas. No contexto do STM32V8, isso se traduz em um MCU capaz de executar centenas de milhões de instruções por segundo, mantendo características fundamentais de sistemas embarcados, como <strong>determinismo temporal</strong>, <strong>interrupções de baixa latência</strong> e <strong>execução previsível</strong>, essenciais para aplicações industriais, automotivas e médicas.</p>



<p class="wp-block-paragraph">Um dos principais diferenciais técnicos do Cortex-M85 é o suporte nativo às <strong>extensões Helium</strong>, também conhecidas como <strong>M-Profile Vector Extension (MVE)</strong>. Essas extensões introduzem um conjunto de instruções vetoriais SIMD (Single Instruction, Multiple Data), permitindo que operações matemáticas sejam executadas em paralelo sobre múltiplos dados. Na prática, isso acelera de forma expressiva algoritmos de <strong>DSP</strong>, como filtros FIR e IIR, FFTs, convoluções, correlação e operações matriciais, amplamente utilizadas em controle, áudio, vibração, sensores e comunicações industriais.</p>



<p class="wp-block-paragraph">No campo da <strong>inteligência artificial embarcada</strong>, o impacto é ainda mais relevante. O Cortex-M85 foi projetado para executar inferência de redes neurais leves diretamente no MCU, especialmente modelos de <strong>machine learning para edge computing</strong>, como classificadores, detectores de padrões e modelos de regressão. Quando combinado com bibliotecas otimizadas como <strong>CMSIS-DSP</strong> e <strong>CMSIS-NN</strong>, o STM32V8 passa a executar modelos treinados em frameworks como TensorFlow Lite Micro com desempenho antes restrito a SoCs mais complexos.</p>



<p class="wp-block-paragraph">Do ponto de vista prático de desenvolvimento, isso significa que tarefas como <strong>detecção de anomalias</strong>, <strong>classificação de sinais</strong>, <strong>reconhecimento de padrões em sensores</strong>, <strong>monitoramento preditivo</strong> e <strong>processamento inteligente de dados</strong> podem ser implementadas diretamente no microcontrolador, sem dependência de sistemas operacionais complexos ou unidades externas de processamento. Além de reduzir consumo e custo, essa abordagem melhora a confiabilidade do sistema e reduz latências críticas.</p>



<p class="wp-block-paragraph">Outro aspecto importante do Cortex-M85 é o avanço nos mecanismos de <strong>segurança e isolamento</strong>, especialmente quando combinado com arquiteturas compatíveis com <strong>TrustZone para Cortex-M</strong>. Embora o foco principal do STM32V8 seja desempenho, a presença de recursos modernos de proteção de memória, execução segura e separação de contextos torna o dispositivo adequado a aplicações conectadas, onde segurança cibernética é um requisito básico e não opcional.</p>



<p class="wp-block-paragraph">Em síntese, o núcleo Cortex-M85 transforma o STM32V8 em um microcontrolador que atua como uma <strong>plataforma computacional completa</strong>, capaz de unificar controle, processamento de sinais e inteligência artificial. Na próxima seção, será analisada a <strong>arquitetura de memória e subsistema de interconexão</strong> do STM32V8, explorando como a combinação de PCM, SRAM e barramentos internos sustenta esse nível de desempenho de forma determinística e eficiente.</p>



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



<h2 class="wp-block-heading"><strong>Arquitetura de Memória e Execução no STM32V8</strong></h2>



<p class="wp-block-paragraph">O desempenho elevado do <strong>STM32V8</strong> não é resultado apenas do núcleo Cortex-M85 ou do processo de fabricação em 18 nm, mas da forma como a <strong>arquitetura de memória</strong> foi projetada para sustentar cargas computacionais intensas com previsibilidade temporal. A ST adotou uma abordagem que combina <strong>memória PCM de alta velocidade</strong>, <strong>SRAM interna otimizada</strong> e um <strong>subsistema de barramentos de alta largura de banda</strong>, criando uma base sólida para aplicações em tempo real, DSP e inteligência artificial embarcada.</p>



<p class="wp-block-paragraph">A <strong>memória PCM (Phase-Change Memory)</strong> atua como principal memória não volátil do sistema, substituindo completamente a Flash tradicional. Diferente da Flash, cujo acesso pode introduzir estados de espera (wait states) em altas frequências, a PCM oferece <strong>latência significativamente menor e mais previsível</strong>, permitindo que o núcleo execute código diretamente da memória não volátil com impacto mínimo no desempenho. Isso reduz a necessidade de técnicas clássicas, como cópia de código crítico para RAM, simplificando o projeto de firmware e melhorando o determinismo.</p>



<p class="wp-block-paragraph">A <strong>SRAM interna</strong> complementa a PCM, sendo utilizada para dados, pilhas, heaps, buffers de comunicação e estruturas temporárias exigidas por algoritmos de DSP e IA. No STM32V8, essa SRAM é distribuída de forma estratégica no mapa de memória, permitindo acessos paralelos e reduzindo contenções no barramento. Essa organização é particularmente importante quando múltiplos mestres — como o núcleo, DMA e aceleradores internos — competem por acesso à memória.</p>



<p class="wp-block-paragraph">O subsistema de interconexão interna do STM32V8 foi projetado para acompanhar o aumento de desempenho do núcleo. Barramentos de alta velocidade interligam o Cortex-M85 às memórias e periféricos, garantindo <strong>baixa latência em acessos críticos</strong> e <strong>previsibilidade temporal</strong>. Para aplicações em tempo real, essa previsibilidade é tão importante quanto a velocidade bruta, pois garante que interrupções, tarefas de RTOS e rotinas de controle cumpram seus prazos de execução.</p>



<p class="wp-block-paragraph">Do ponto de vista prático, essa arquitetura favorece fortemente o uso de <strong>RTOS como FreeRTOS ou Zephyr</strong>, permitindo que múltiplas tarefas executem algoritmos complexos sem interferências imprevisíveis. Em sistemas de controle avançado, por exemplo, é possível isolar tarefas de aquisição de sensores, processamento vetorial e comunicação, mantendo comportamento determinístico mesmo sob carga elevada.</p>



<p class="wp-block-paragraph">Outro ponto relevante é o impacto dessa arquitetura na <strong>eficiência energética</strong>. A menor latência da PCM reduz o tempo total de execução das instruções, permitindo que o microcontrolador entre mais rapidamente em estados de baixo consumo. Aliado aos recursos do FD-SOI, como body biasing dinâmico, o STM32V8 consegue equilibrar alto desempenho com consumo otimizado, algo essencial em aplicações industriais e embarcadas que operam continuamente.</p>



<p class="wp-block-paragraph">Em resumo, a arquitetura de memória do STM32V8 foi concebida para remover gargalos históricos dos microcontroladores de alto desempenho, oferecendo uma plataforma onde execução direta da memória, acesso previsível e alto paralelismo são características intrínsecas. Na próxima seção, o foco será a <strong>integração de periféricos, interfaces e capacidades de sistema</strong>, analisando como o STM32V8 se posiciona em aplicações reais de automação, controle e edge computing.</p>



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



<h2 class="wp-block-heading"><strong>Periféricos, Interfaces e Aplicações Práticas do STM32V8</strong></h2>



<p class="wp-block-paragraph">Além do avanço significativo em núcleo, processo de fabricação e arquitetura de memória, o <strong>STM32V8</strong> foi concebido como um microcontrolador altamente integrado, capaz de atender sistemas complexos sem a necessidade de circuitos externos adicionais. A ST mantém a filosofia histórica da família STM32: oferecer um <strong>ecossistema robusto de periféricos</strong>, com forte integração a ferramentas de software e suporte de longo prazo, agora elevado a um novo patamar de desempenho.</p>



<p class="wp-block-paragraph">Embora a publicação oficial foque principalmente nos avanços tecnológicos de processo e memória, o posicionamento do STM32V8 indica claramente a presença de um conjunto completo de <strong>periféricos de alto desempenho</strong>, incluindo temporizadores avançados, interfaces de comunicação industriais e subsistemas de conversão analógica. Esses recursos são essenciais para aplicações que combinam <strong>controle em tempo real</strong>, <strong>aquisição de sinais</strong> e <strong>processamento intensivo</strong> em um único dispositivo.</p>



<p class="wp-block-paragraph">No contexto de controle e automação, temporizadores de alta resolução e baixo jitter permitem a implementação de <strong>controle de motores</strong>, <strong>conversores de potência</strong>, <strong>robótica</strong> e <strong>sistemas mecatrônicos</strong> com precisão elevada. A capacidade de executar algoritmos complexos diretamente no MCU possibilita a adoção de técnicas mais sofisticadas, como controle preditivo, observadores de estado e filtragem adaptativa, sem comprometer os requisitos temporais do sistema.</p>



<p class="wp-block-paragraph">As <strong>interfaces de comunicação</strong> desempenham um papel central no posicionamento do STM32V8 em aplicações modernas. Protocolos seriais de alta velocidade, combinados com suporte a comunicação determinística, tornam o dispositivo adequado para <strong>redes industriais</strong>, <strong>sistemas distribuídos</strong> e <strong>edge computing</strong>. Em aplicações conectadas, o alto desempenho do núcleo Cortex-M85 permite que pilhas de comunicação, criptografia e segurança sejam executadas em paralelo com tarefas de controle e processamento de sinais.</p>



<p class="wp-block-paragraph">Um aspecto particularmente relevante é a viabilidade prática de consolidar múltiplas funções em um único microcontrolador. Em projetos tradicionais, seria comum dividir responsabilidades entre um MCU de controle e um processador dedicado a processamento de sinais ou inferência de IA. Com o STM32V8, essa separação se torna desnecessária em muitos casos, reduzindo <strong>custo de hardware</strong>, <strong>consumo energético</strong>, <strong>complexidade de software</strong> e <strong>pontos potenciais de falha</strong>.</p>



<p class="wp-block-paragraph">Do ponto de vista de desenvolvimento, o STM32V8 se beneficia diretamente do ecossistema já consolidado da ST, incluindo <strong>STM32Cube</strong>, bibliotecas HAL e LL, suporte a <strong>RTOS</strong>, além de integração com ferramentas de depuração e profiling. Isso reduz significativamente a curva de aprendizado, permitindo que equipes que já dominam a família STM32 migrem para o STM32V8 sem ruptura conceitual, mesmo diante de uma arquitetura significativamente mais avançada.</p>



<p class="wp-block-paragraph">Em aplicações práticas, o STM32V8 se posiciona como uma plataforma ideal para <strong>manutenção preditiva</strong>, <strong>monitoramento inteligente</strong>, <strong>processamento de sinais vibroacústicos</strong>, <strong>edge AI industrial</strong>, <strong>instrumentação avançada</strong> e <strong>sistemas ciberfísicos</strong>. A capacidade de executar algoritmos complexos localmente, com baixa latência e alto grau de determinismo, atende diretamente às demandas atuais da Indústria 4.0 e de sistemas embarcados inteligentes.</p>



<p class="wp-block-paragraph">Na próxima seção, será apresentada uma <strong>comparação técnica objetiva entre o STM32V8 e o Renesas RA8M1</strong>, destacando semelhanças, diferenças arquiteturais e cenários em que cada plataforma se mostra mais adequada.</p>



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



<h2 class="wp-block-heading"><strong>Seção 6 – Comparação Técnica: STM32V8 versus Renesas RA8M1</strong></h2>



<p class="wp-block-paragraph">A comparação entre o <strong>STM32V8</strong>, da STMicroelectronics, e o <strong>Renesas RA8M1</strong> é particularmente relevante porque ambos são baseados no <strong>núcleo Arm Cortex-M85</strong> e se posicionam no segmento de <strong>microcontroladores de altíssimo desempenho</strong>. Apesar dessa similaridade fundamental, as duas plataformas adotam <strong>estratégias arquiteturais distintas</strong>, refletindo visões diferentes sobre escalabilidade, memória, eficiência energética e foco de aplicação.</p>



<p class="wp-block-paragraph">Do ponto de vista de <strong>núcleo e capacidade computacional</strong>, ambos utilizam o Cortex-M85 com suporte às extensões Helium (MVE), o que garante excelente desempenho em DSP e workloads de machine learning. No entanto, o STM32V8 se beneficia diretamente do processo de fabricação em <strong>18 nm FD-SOI</strong>, permitindo frequências mais elevadas e melhor controle de consumo dinâmico em comparação ao RA8M1, que é fabricado em um processo CMOS mais convencional. Na prática, isso favorece o STM32V8 em aplicações que exigem desempenho sustentado com controle térmico rigoroso.</p>



<p class="wp-block-paragraph">A diferença mais marcante entre as duas plataformas está no <strong>sistema de memória não volátil</strong>. O Renesas RA8M1 utiliza <strong>Flash embutida tradicional</strong>, complementada por uma quantidade significativa de SRAM. Essa abordagem é madura, amplamente conhecida e bem suportada por ferramentas, mas impõe limitações de latência e escalabilidade em altas frequências. O STM32V8, por outro lado, elimina a Flash e adota <strong>memória PCM</strong>, oferecendo menor latência de acesso, maior previsibilidade temporal e melhor adequação a nós tecnológicos avançados. Para aplicações em tempo real estrito, essa diferença é particularmente relevante.</p>



<p class="wp-block-paragraph">Em termos de <strong>arquitetura de execução</strong>, o STM32V8 apresenta vantagens claras na execução direta da memória não volátil (XIP) sem penalidades significativas, enquanto o RA8M1 pode exigir estratégias adicionais, como cache ou cópia seletiva de código para RAM, em aplicações mais exigentes. Isso impacta diretamente a complexidade do firmware e o esforço de otimização por parte do desenvolvedor.</p>



<p class="wp-block-paragraph">No campo da <strong>eficiência energética</strong>, ambos os dispositivos são projetados para aplicações embarcadas modernas, mas o uso de FD-SOI no STM32V8 introduz recursos adicionais, como <strong>body biasing dinâmico</strong>, que permitem ajustes finos entre desempenho e consumo em tempo de execução. O RA8M1 mantém uma abordagem mais tradicional, eficiente e confiável, porém com menor flexibilidade nesse aspecto específico.</p>



<p class="wp-block-paragraph">Do ponto de vista de <strong>ecossistema e maturidade</strong>, o RA8M1 se beneficia da forte integração com o <strong>Renesas Flexible Software Package (FSP)</strong>, oferecendo uma pilha de software bem estruturada e voltada para aplicações industriais e comerciais. O STM32V8, por sua vez, herda o vasto ecossistema <strong>STM32Cube</strong>, amplamente difundido, com suporte consolidado a RTOS, middleware e ferramentas de desenvolvimento, o que pode representar uma vantagem estratégica para equipes já familiarizadas com o universo STM32.</p>



<p class="wp-block-paragraph">Em síntese, o <strong>Renesas RA8M1</strong> se apresenta como uma plataforma robusta, madura e altamente capaz para aplicações industriais de alto desempenho, enquanto o <strong>STM32V8</strong> avança além, explorando novas tecnologias de fabricação e memória para atingir um nível superior de desempenho, previsibilidade e escalabilidade futura. A escolha entre as duas soluções dependerá diretamente dos requisitos do projeto, especialmente no que se refere a latência, consumo, longevidade tecnológica e complexidade de software aceitável.</p>



<p class="wp-block-paragraph">Na próxima e última seção, será apresentada a <strong>conclusão do artigo</strong>, seguida da <strong>lista de fontes utilizadas</strong>, conforme solicitado.</p>



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



<h2 class="wp-block-heading"><strong>Seção 7 – Conclusão e Fontes</strong></h2>



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



<p class="wp-block-paragraph">O <strong>STM32V8</strong> representa um marco importante na evolução dos microcontroladores, não apenas dentro do portfólio da STMicroelectronics, mas no mercado de sistemas embarcados como um todo. Ao combinar o núcleo <strong>Arm Cortex-M85</strong> com um processo de fabricação avançado em <strong>18 nm FD-SOI</strong> e a adoção inédita de <strong>memória PCM</strong>, a ST redefine os limites tradicionais entre microcontroladores e microprocessadores de entrada. Essa abordagem permite alcançar níveis de desempenho, eficiência energética e previsibilidade temporal que antes exigiam arquiteturas mais complexas.</p>



<p class="wp-block-paragraph">Do ponto de vista técnico, o STM32V8 se destaca pela execução eficiente de <strong>DSP e inteligência artificial embarcada</strong>, suportada por extensões vetoriais Helium e por uma arquitetura de memória capaz de sustentar altas taxas de processamento sem os gargalos clássicos da Flash. Para o desenvolvedor, isso se traduz em projetos mais simples, com menor necessidade de otimizações manuais, cópias de código para RAM ou uso de dispositivos auxiliares.</p>



<p class="wp-block-paragraph">Na comparação com o <strong>Renesas RA8M1</strong>, fica evidente que ambas as plataformas ocupam o topo do segmento Cortex-M. Entretanto, o STM32V8 adota uma postura mais agressiva em termos de inovação tecnológica, priorizando escalabilidade futura, menor latência e maior flexibilidade energética. Já o RA8M1 se posiciona como uma solução madura, robusta e alinhada a arquiteturas tradicionais, o que pode ser uma vantagem em projetos que valorizam estabilidade e continuidade de design.</p>



<p class="wp-block-paragraph">Em aplicações práticas, o STM32V8 surge como uma plataforma especialmente atraente para <strong>automação industrial avançada</strong>, <strong>edge AI</strong>, <strong>manutenção preditiva</strong>, <strong>instrumentação inteligente</strong>, <strong>robótica</strong> e <strong>sistemas ciberfísicos</strong>, onde alto desempenho, determinismo e integração são requisitos fundamentais. Seu lançamento sinaliza uma tendência clara: o futuro dos microcontroladores passa pela convergência entre computação intensiva, eficiência energética e inteligência embarcada.</p>



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



<h3 class="wp-block-heading"><strong>Fontes Utilizadas</strong></h3>



<ol class="wp-block-list">
<li><strong>STMicroelectronics – Press Release</strong><br><em>ST unveils STM32V8 microcontroller with embedded phase-change memory on 18nm FD-SOI technology</em><br>Disponível em:<br><a href="https://newsroom.st.com/media-center/press-item.html/p4733.html">https://newsroom.st.com/media-center/press-item.html/p4733.html</a></li>



<li><strong>Renesas Electronics – RA8M1 Product Page</strong><br><em>RA8M1 – 480 MHz Arm Cortex-M85 MCU</em><br>Disponível em:<br><a href="https://www.renesas.com/en/products/ra8m1">https://www.renesas.com/en/products/ra8m1</a></li>
</ol><p>The post <a href="https://mcu.tec.br/microcontroladores/stm32/stm32v8-o-novo-microcontrolador-da-st-com-cortex-m85-pcm-e-tecnologia-18-nm-fd-soi/">STM32V8: o novo microcontrolador da ST com Cortex-M85, PCM e tecnologia 18 nm FD-SOI</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1032</post-id>	</item>
		<item>
		<title>Por que sensores industriais usam 0–10 V e 4–20 mA? Fundamentos, fórmulas e aplicações práticas</title>
		<link>https://mcu.tec.br/infraestrutura/por-que-sensores-industriais-usam-0-10-v-e-4-20-ma-fundamentos-formulas-e-aplicacoes-praticas/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=por-que-sensores-industriais-usam-0-10-v-e-4-20-ma-fundamentos-formulas-e-aplicacoes-praticas</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sat, 13 Dec 2025 19:05:21 +0000</pubDate>
				<category><![CDATA[Infraestrutura]]></category>
		<category><![CDATA[0-10V]]></category>
		<category><![CDATA[4-20mA]]></category>
		<category><![CDATA[ADC]]></category>
		<category><![CDATA[automação industrial]]></category>
		<category><![CDATA[entrada analógica]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[instrumentação industrial]]></category>
		<category><![CDATA[loop de corrente]]></category>
		<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[ruído eletromagnético]]></category>
		<category><![CDATA[sensores industriais]]></category>
		<category><![CDATA[sinais analógicos]]></category>
		<category><![CDATA[stm32]]></category>
		<category><![CDATA[zero vivo]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1003</guid>

					<description><![CDATA[<p>Entenda por que sensores industriais utilizam os padrões 0–10 V e 4–20 mA. Este artigo explica os fundamentos elétricos, a matemática do escalonamento, imunidade a ruído, zero vivo, integração com microcontroladores e critérios técnicos de escolha. Um guia didático e minucioso para engenheiros, estudantes e profissionais de automação industrial que desejam projetar sistemas embarcados mais confiáveis e robustos.</p>
<p>The post <a href="https://mcu.tec.br/infraestrutura/por-que-sensores-industriais-usam-0-10-v-e-4-20-ma-fundamentos-formulas-e-aplicacoes-praticas/">Por que sensores industriais usam 0–10 V e 4–20 mA? Fundamentos, fórmulas e aplicações práticas</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2 class="wp-block-heading">Visão geral: por que a indústria padronizou 0–10 V e 4–20 mA</h2>



<p class="wp-block-paragraph">Em automação industrial, o “problema real” não é só medir uma grandeza (pressão, nível, vazão, temperatura), e sim <strong>transportar essa informação com confiabilidade</strong> por cabos longos, passando perto de motores, inversores de frequência, contatores e ambientes com aterramento imperfeito. Por isso, o setor convergiu para <strong>dois padrões analógicos</strong> simples, baratos e robustos: <strong>tensão (tipicamente 0–10 V)</strong> e <strong>corrente (tipicamente 4–20 mA)</strong>. Ambos representam a mesma ideia: um sensor transforma uma variável física em um sinal elétrico proporcional; a diferença está em <em>como</em> esse sinal “sobrevive” ao mundo industrial.</p>



<p class="wp-block-paragraph">O padrão <strong>0–10 V</strong> é muito comum quando as distâncias são moderadas, o cabeamento é bem controlado e o custo/complexidade precisa ser mínimo. Ele é intuitivo: a variável medida vira uma tensão proporcional na entrada analógica do CLP/DAQ. A relação básica de escalonamento (linear) é:</p>



<p class="wp-block-paragraph">\[<br>y = y_{\min} + \frac{(V &#8211; V_{\min})}{(V_{\max}-V_{\min})},(y_{\max}-y_{\min})<br>\]



<p class="wp-block-paragraph">Para 0–10 V, fica:</p>



<p class="wp-block-paragraph">\[<br>y = y_{\min} + \frac{V}{10},(y_{\max}-y_{\min})<br>\]



<p class="wp-block-paragraph">Já o padrão <strong>4–20 mA</strong> nasceu para vencer o que “mata” sinais de tensão no campo: <strong>queda de tensão no cabo, variações de resistência de contato, ruído acoplado e diferenças de referência de terra</strong>. Em um loop de corrente, o receptor não “confia” tanto em uma tensão absoluta; ele mede a corrente, e a corrente é <strong>a mesma ao longo de todo o circuito em série</strong> (pela própria natureza do loop), desde que o transmissor tenha tensão de alimentação suficiente para manter a conformidade. O escalonamento típico é:</p>



<p class="wp-block-paragraph">\[<br>y = y_{\min} + \frac{(I-4,\text{mA})}{16,\text{mA}},(y_{\max}-y_{\min})<br>\]



<p class="wp-block-paragraph">O “4 mA” (e não 0 mA) é intencional: é o chamado <strong>zero vivo</strong>. Assim, <strong>0 mA pode significar falha</strong> (fio rompido, transmissor sem alimentação), enquanto 4 mA significa “medindo zero da grandeza, mas o circuito está vivo”. Esse detalhe sozinho reduz diagnósticos ambíguos e melhora manutenção.</p>



<p class="wp-block-paragraph">Na prática, a escolha vira um trade-off objetivo:</p>



<ul class="wp-block-list">
<li><strong>0–10 V</strong> tende a ser simples, barato, fácil de interfacear, porém mais sensível a ruído e a problemas de referência/aterramento em longas distâncias.</li>



<li><strong>4–20 mA</strong> tende a ser mais robusto para cabos longos e ambientes agressivos, e ainda oferece diagnóstico de falha via “zero vivo”, ao custo de exigir loop, alimentação e resistor de carga (burden) adequados.</li>
</ul>



<p class="wp-block-paragraph">Observação importante (para conectar com arquitetura de sistemas reais): a indústria adota esses padrões porque eles reduzem risco sistêmico e tornam o comportamento mais previsível em campo — uma lógica muito alinhada à mentalidade de projeto de sistemas embarcados/tempo real, onde decisões de arquitetura existem para otimizar confiabilidade sob restrições práticas.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="474" height="237" src="https://mcu.tec.br/wp-content/uploads/2025/12/image-31.png" alt="" class="wp-image-1006" srcset="https://mcu.tec.br/wp-content/uploads/2025/12/image-31.png 474w, https://mcu.tec.br/wp-content/uploads/2025/12/image-31-300x150.png 300w" sizes="(max-width: 474px) 100vw, 474px" /></figure>



<h2 class="wp-block-heading">Padrão 0–10 V em detalhe técnico (vantagens, limites e matemática do erro)</h2>



<p class="wp-block-paragraph">O padrão <strong>0–10 V</strong> representa a variável medida como uma <strong>tensão proporcional</strong> aplicada à entrada analógica do sistema de aquisição (CLP, módulo de I/O, microcontrolador). Do ponto de vista elétrico, isso significa que o sensor funciona como uma <strong>fonte de tensão</strong> (idealmente) e o equipamento de leitura como uma <strong>carga de alta impedância</strong>. Quanto maior a impedância de entrada, menor a corrente drenada do sensor e menor o erro introduzido.</p>



<h3 class="wp-block-heading">Modelo elétrico simplificado</h3>



<p class="wp-block-paragraph">Na prática, o sensor não é uma fonte ideal: ele pode ser modelado como uma fonte de tensão \(V_s\) em série com uma resistência interna \(R_s\). O cabo adiciona uma resistência \(R_c\) e a entrada do conversor A/D (ADC) possui uma impedância \(R_{in}\).</p>



<p class="wp-block-paragraph">\[<br>V_{med} = V_s \cdot \frac{R_{in}}{R_s + R_c + R_{in}}<br>\]



<p class="wp-block-paragraph">Se \(R_{in} \gg (R_s + R_c)\), o termo tende a 1 e o erro é desprezível. Em ambientes industriais, módulos analógicos costumam ter <strong>impedâncias de entrada entre 100 kΩ e 1 MΩ</strong>, justamente para minimizar esse efeito. Já cabos longos, com seções pequenas, aumentam \(R_c\) e tornam o sistema mais sensível a erro.</p>



<h3 class="wp-block-heading">Influência do ruído eletromagnético</h3>



<p class="wp-block-paragraph">Outro ponto crítico do 0–10 V é o <strong>acoplamento de ruído</strong>. Um campo eletromagnético variável (por exemplo, próximo a motores ou inversores de frequência) pode induzir uma tensão espúria no cabo. Como o sinal é uma tensão absoluta, qualquer interferência somada ao sinal aparece diretamente na medição:</p>



<p class="wp-block-paragraph">\[<br>V_{ADC} = V_{sinal} + V_{ruído}<br>\]



<p class="wp-block-paragraph">Mesmo alguns poucos milivolts podem ser relevantes. Em um sensor escalado de 0–10 V para 0–100 bar, por exemplo, <strong>10 mV equivalem a 0,1 bar</strong>. Em aplicações de precisão, isso não é desprezível.</p>



<p class="wp-block-paragraph">Por isso, boas práticas são praticamente obrigatórias:</p>



<ul class="wp-block-list">
<li>uso de <strong>cabos blindados</strong>;</li>



<li>referência de <strong>terra bem definida</strong> (sensor e receptor compartilham o mesmo GND);</li>



<li>filtragem analógica simples, como um <strong>filtro RC passa-baixa</strong> antes do ADC.</li>
</ul>



<p class="wp-block-paragraph">O corte de um filtro RC típico é dado por:</p>



<p class="wp-block-paragraph">\[<br>f_c = \frac{1}{2\pi RC}<br>\]



<p class="wp-block-paragraph">Esse filtro reduz ruído de alta frequência, mas introduz atraso de fase, algo que precisa ser considerado em sistemas de controle em malha fechada.</p>



<h3 class="wp-block-heading">Resolução e relação com o ADC</h3>



<p class="wp-block-paragraph">Quando o sinal 0–10 V entra em um ADC de \(N\) bits, a menor variação detectável (LSB – <em>Least Significant Bit</em>) é:</p>



<p class="wp-block-paragraph">\[<br>\Delta V = \frac{10\ \text{V}}{2^N}<br>\]



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



<ul class="wp-block-list">
<li>ADC de 10 bits: \(\Delta V \approx 9{,}77\ \text{mV}\)</li>



<li>ADC de 12 bits: \(\Delta V \approx 2{,}44\ \text{mV}\)</li>
</ul>



<p class="wp-block-paragraph">Esse valor define o limite teórico de resolução do sistema. Na prática, ruído, offset e erro de ganho costumam dominar antes mesmo do limite do ADC.</p>



<h3 class="wp-block-heading">Quando 0–10 V faz sentido</h3>



<p class="wp-block-paragraph">O padrão 0–10 V é muito usado quando:</p>



<ul class="wp-block-list">
<li>as <strong>distâncias são curtas</strong> (painel ou máquina compacta);</li>



<li>o ambiente eletromagnético é relativamente controlado;</li>



<li>há necessidade de <strong>baixo custo</strong> e simplicidade;</li>



<li>o sistema já possui entradas analógicas de alta impedância e boa referência de terra.</li>
</ul>



<p class="wp-block-paragraph">É exatamente nesses limites — ruído, referência de terra e distância — que o padrão 0–10 V começa a perder espaço para o <strong>4–20 mA</strong>, que trata esses problemas de forma estrutural, e não apenas mitigativa.</p>



<h2 class="wp-block-heading">Padrão 4–20 mA: robustez elétrica, “zero vivo” e imunidade a ruído</h2>



<p class="wp-block-paragraph">O padrão <strong>4–20 mA</strong> foi adotado em larga escala porque resolve, de forma estrutural, problemas que no 0–10 V exigem cuidados adicionais. Aqui, a variável física não é representada por uma tensão absoluta, mas por uma <strong>corrente proporcional</strong>, que circula em um <strong>loop em série</strong> envolvendo transmissor, cabo, carga (burden) e fonte de alimentação. A grande vantagem é simples e poderosa: <strong>a corrente é a mesma em todos os pontos do loop</strong>, independentemente da resistência do cabo, desde que o transmissor tenha tensão suficiente para manter o regime.</p>



<h3 class="wp-block-heading">Modelo elétrico do loop de corrente</h3>



<p class="wp-block-paragraph">Um loop típico pode ser modelado como:</p>



<ul class="wp-block-list">
<li>fonte de alimentação \(V_{loop}\),</li>



<li>transmissor de corrente (sensor),</li>



<li>resistência do cabo \(R_c\),</li>



<li>resistência de carga \(R_b\) (burden resistor, onde a corrente é convertida em tensão),</li>



<li>eventualmente dispositivos intermediários (isoladores, barreiras).</li>
</ul>



<p class="wp-block-paragraph">A tensão total necessária para o loop funcionar corretamente é:</p>



<p class="wp-block-paragraph">\[<br>V_{loop} \ge V_{tx} + I \cdot (R_c + R_b)<br>\]



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



<ul class="wp-block-list">
<li>\(V_{tx}\) é a tensão mínima de conformidade do transmissor,</li>



<li>\(I\) é a corrente do loop (entre 4 e 20 mA).</li>
</ul>



<p class="wp-block-paragraph">Se essa condição for satisfeita, <strong>a corrente permanece correta</strong>, mesmo com variações de resistência do cabo, oxidação de contatos ou distâncias longas.</p>



<h3 class="wp-block-heading">O conceito de “zero vivo” (4 mA)</h3>



<p class="wp-block-paragraph">Diferentemente de um sistema 0–20 mA, o uso de <strong>4 mA como zero</strong> não é arbitrário. Ele resolve dois problemas fundamentais:</p>



<ol class="wp-block-list">
<li><strong>Detecção de falhas</strong>
<ul class="wp-block-list">
<li>0 mA → fio rompido, transmissor sem alimentação ou falha grave.</li>



<li>4 mA → zero físico medido, sistema operando normalmente.</li>
</ul>
</li>



<li><strong>Alimentação do próprio sensor</strong><br>Em muitos casos, o transmissor é <strong>alimentado pelo próprio loop</strong> (<em>loop-powered</em>). Os 4 mA mínimos garantem energia suficiente para a eletrônica interna.</li>
</ol>



<p class="wp-block-paragraph">O escalonamento linear clássico é:</p>



<p class="wp-block-paragraph">\[<br>y = y_{\min} + \frac{(I &#8211; 4,\text{mA})}{16,\text{mA}} \cdot (y_{\max} &#8211; y_{\min})<br>\]



<p class="wp-block-paragraph">Por exemplo, em um sensor de pressão de 0–100 bar:</p>



<ul class="wp-block-list">
<li>4 mA → 0 bar</li>



<li>12 mA → 50 bar</li>



<li>20 mA → 100 bar</li>
</ul>



<h3 class="wp-block-heading">Conversão corrente → tensão (burden resistor)</h3>



<p class="wp-block-paragraph">Na maioria dos sistemas embarcados e CLPs, o ADC mede <strong>tensão</strong>, não corrente. Por isso, usa-se um resistor de carga \(R_b\) para converter corrente em tensão:</p>



<p class="wp-block-paragraph">\[<br>V = I \cdot R_b<br>\]



<p class="wp-block-paragraph">Valores típicos:</p>



<ul class="wp-block-list">
<li>\(R_b = 250,\Omega\) → 4–20 mA vira <strong>1–5 V</strong></li>



<li>\(R_b = 100,\Omega\) → 0,4–2 V</li>
</ul>



<p class="wp-block-paragraph">A escolha de \(R_b\) é crítica:</p>



<ul class="wp-block-list">
<li>valores altos aumentam a tensão disponível para o ADC,</li>



<li>valores altos também aumentam a tensão exigida do loop (impactando a conformidade).</li>
</ul>



<h3 class="wp-block-heading">Imunidade a ruído: por que funciona melhor</h3>



<p class="wp-block-paragraph">Ruídos eletromagnéticos tendem a se manifestar como <strong>tensões induzidas</strong> no cabo. Em um sistema de corrente:</p>



<ul class="wp-block-list">
<li>pequenas tensões parasitas <strong>não alteram significativamente a corrente</strong> do loop;</li>



<li>o transmissor “força” a corrente correta dentro de sua faixa de conformidade.</li>
</ul>



<p class="wp-block-paragraph">Matematicamente, um ruído de tensão \(V_n\) somado ao loop gera uma variação de corrente:</p>



<p class="wp-block-paragraph">\[<br>\Delta I = \frac{V_n}{R_{total}}<br>\]



<p class="wp-block-paragraph">Como \(R_{total}\) costuma ser relativamente alto (centenas de ohms), \(\Delta I\) é pequeno, tornando o sistema naturalmente mais imune.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="520" height="346" src="https://mcu.tec.br/wp-content/uploads/2025/12/image-30.png" alt="" class="wp-image-1004" srcset="https://mcu.tec.br/wp-content/uploads/2025/12/image-30.png 520w, https://mcu.tec.br/wp-content/uploads/2025/12/image-30-300x200.png 300w" sizes="(max-width: 520px) 100vw, 520px" /><figcaption class="wp-element-caption">Obtido em: https://www.newtoncbraga.com.br/projetos/7578-conversor-4-20-ma-para-0-5-v-art1082.html</figcaption></figure>
</div>


<h3 class="wp-block-heading">Quando 4–20 mA é a melhor escolha</h3>



<p class="wp-block-paragraph">O padrão 4–20 mA é preferido quando:</p>



<ul class="wp-block-list">
<li>há <strong>longas distâncias</strong> (dezenas ou centenas de metros);</li>



<li>o ambiente é <strong>eletricamente agressivo</strong>;</li>



<li>é necessário <strong>diagnóstico simples de falhas</strong>;</li>



<li>sensores precisam ser alimentados pelo próprio sinal;</li>



<li>confiabilidade é mais importante que simplicidade.</li>
</ul>



<p class="wp-block-paragraph">Essa robustez explica por que, mesmo com fieldbuses modernos e Ethernet industrial, <strong>4–20 mA continua extremamente atual</strong>.</p>



<h2 class="wp-block-heading">Comparação direta: 0–10 V vs 4–20 mA e impactos no projeto de hardware e firmware</h2>



<p class="wp-block-paragraph">Depois de entender cada padrão isoladamente, a decisão de engenharia passa a ser <strong>comparativa e contextual</strong>. Não existe “melhor padrão absoluto”; existe o <strong>mais adequado ao cenário físico, elétrico e ao nível de confiabilidade exigido</strong>. Aqui vale olhar não só o sensor, mas o <em>sistema completo</em>: cabeamento, entradas analógicas, ADC, referência, firmware e manutenção.</p>



<h3 class="wp-block-heading">Comparação elétrica fundamental</h3>



<p class="wp-block-paragraph">No <strong>0–10 V</strong>, o sistema depende fortemente de uma <strong>referência comum de terra</strong> entre sensor e receptor. Qualquer diferença de potencial entre GNDs aparece diretamente como erro de medição. Em ambientes industriais, isso é frequente devido a:</p>



<ul class="wp-block-list">
<li>correntes de retorno pelo terra,</li>



<li>malhas de aterramento,</li>



<li>equipamentos de potência próximos.</li>
</ul>



<p class="wp-block-paragraph">Já no <strong>4–20 mA</strong>, o loop é essencialmente <strong>diferencial em corrente</strong>. A referência de terra perde importância relativa, porque a variável medida é a corrente no circuito em série. Isso reduz drasticamente problemas de <em>ground loop</em>.</p>



<h3 class="wp-block-heading">Comparação matemática do erro</h3>



<p class="wp-block-paragraph"><strong>Erro por resistência de cabo</strong></p>



<ul class="wp-block-list">
<li>0–10 V:<br>\[<br>\varepsilon_V \approx I_{in} \cdot R_c<br>\]<br>Onde \(I_{in}\) é a corrente drenada pela entrada. Se a impedância de entrada não for suficientemente alta, o erro cresce com o comprimento do cabo.</li>



<li>4–20 mA:<br>\[<br>\varepsilon_I \approx 0 \quad (\text{desde que haja conformidade})<br>\]<br>A resistência do cabo só “consome” tensão, não altera a corrente medida.</li>
</ul>



<p class="wp-block-paragraph"><strong>Erro por ruído</strong></p>



<ul class="wp-block-list">
<li>0–10 V:<br>\[<br>V_{med} = V_{sinal} + V_{ruído}<br>\]</li>



<li>4–20 mA:<br>\[<br>\Delta I = \frac{V_{ruído}}{R_{loop}}<br>\]<br>Com \(R_{loop}\) elevado, a variação de corrente é pequena.</li>
</ul>



<h3 class="wp-block-heading">Impacto no projeto de hardware embarcado</h3>



<p class="wp-block-paragraph"><strong>Entradas analógicas (ADC)</strong></p>



<ul class="wp-block-list">
<li>0–10 V: geralmente exige <strong>divisor resistivo</strong> ou amplificador para adaptar ao range típico do ADC (0–3,3 V ou 0–5 V). Isso adiciona erro de ganho e offset.</li>



<li>4–20 mA: basta um <strong>resistor de precisão</strong> (ex.: 250 Ω, 0,1%) e, opcionalmente, um filtro RC simples. A conversão corrente→tensão é extremamente previsível.</li>
</ul>



<p class="wp-block-paragraph"><strong>Proteção elétrica</strong></p>



<ul class="wp-block-list">
<li>0–10 V: mais sensível a surtos e ESD, pois a entrada “vê” diretamente a tensão do campo.</li>



<li>4–20 mA: o loop naturalmente limita corrente; ainda assim, proteção contra sobretensão é aplicada, mas o sistema tende a ser mais tolerante.</li>
</ul>



<h3 class="wp-block-heading">Impacto no firmware</h3>



<p class="wp-block-paragraph">No firmware, ambos acabam convergindo para a mesma lógica: <strong>ler um ADC e aplicar um escalonamento linear</strong>. A diferença está na confiabilidade do dado bruto.</p>



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



<p class="wp-block-paragraph">\[<br>y = y_{\min} + \frac{(x &#8211; x_{\min})}{(x_{\max} &#8211; x_{\min})}(y_{\max} &#8211; y_{\min})<br>\]



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



<ul class="wp-block-list">
<li>em 0–10 V, (x) é a tensão medida,</li>



<li>em 4–20 mA, (x) é a corrente (ou a tensão no burden resistor).</li>
</ul>



<p class="wp-block-paragraph">No entanto, no <strong>4–20 mA</strong>, o firmware ganha uma vantagem adicional:</p>



<ul class="wp-block-list">
<li>leituras <strong>abaixo de 3,8 mA</strong> podem ser tratadas como <strong>falha de campo</strong>, e não apenas “valor baixo”.<br>Isso simplifica diagnóstico, alarmes e estratégias de <em>fail-safe</em>.</li>
</ul>



<h3 class="wp-block-heading">Critérios práticos de escolha</h3>



<p class="wp-block-paragraph"><strong>Escolha 0–10 V quando:</strong></p>



<ul class="wp-block-list">
<li>o sensor está próximo ao controlador;</li>



<li>o ambiente é pouco ruidoso;</li>



<li>custo e simplicidade são prioritários;</li>



<li>o sistema é mais “máquina local” do que “planta industrial”.</li>
</ul>



<p class="wp-block-paragraph"><strong>Escolha 4–20 mA quando:</strong></p>



<ul class="wp-block-list">
<li>há longas distâncias de cabo;</li>



<li>existe forte interferência eletromagnética;</li>



<li>confiabilidade e diagnóstico são críticos;</li>



<li>sensores precisam ser alimentados pelo próprio sinal;</li>



<li>o sistema faz parte de uma planta industrial maior.</li>
</ul>



<p class="wp-block-paragraph">Essa análise explica por que, mesmo em projetos modernos com microcontroladores avançados e Ethernet industrial, <strong>o front-end analógico 4–20 mA continua sendo padrão de ouro</strong> no chão de fábrica.</p>



<h2 class="wp-block-heading">Integração prática com microcontroladores (STM32, ESP32): cálculo, front-end analógico e firmware</h2>



<p class="wp-block-paragraph">Ao integrar sensores <strong>0–10 V</strong> ou <strong>4–20 mA</strong> a microcontroladores, o desafio deixa de ser conceitual e passa a ser <strong>engenharia de interface</strong>: adaptar níveis elétricos ao ADC, preservar precisão, filtrar ruído e transformar a leitura bruta em uma variável física confiável no firmware.</p>



<h3 class="wp-block-heading">Integração de sensores 0–10 V</h3>



<p class="wp-block-paragraph">A maioria dos microcontroladores (STM32, ESP32, RP2040) possui ADCs com faixa máxima de <strong>3,3 V</strong> (alguns STM32 permitem 5 V externamente, mas o ADC interno continua limitado). Portanto, é necessário <strong>rebaixar a tensão</strong>.</p>



<p class="wp-block-paragraph"><strong>Divisor resistivo</strong><br>A solução mais simples é um divisor:</p>



<p class="wp-block-paragraph">\[<br>V_{ADC} = V_{in} \cdot \frac{R_2}{R_1 + R_2}<br>\]



<p class="wp-block-paragraph">Para mapear 0–10 V em 0–3,3 V:</p>



<p class="wp-block-paragraph">\[<br>\frac{R_2}{R_1 + R_2} = 0{,}33<br>\]



<p class="wp-block-paragraph">Um exemplo prático:</p>



<ul class="wp-block-list">
<li>\(R_1 = 20,k\Omega\)</li>



<li>\(R_2 = 10,k\Omega\)</li>
</ul>



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



<ul class="wp-block-list">
<li>resistores de <strong>1% ou melhor</strong> (idealmente 0,1%);</li>



<li>impedância equivalente não muito alta, para não prejudicar o <em>sample-and-hold</em> do ADC;</li>



<li>uso de <strong>buffer com amplificador operacional</strong> se o cabo for longo ou a fonte tiver alta impedância.</li>
</ul>



<p class="wp-block-paragraph"><strong>Filtragem</strong><br>Um filtro RC simples antes do ADC ajuda muito:</p>



<p class="wp-block-paragraph">\[<br>f_c = \frac{1}{2\pi RC}<br>\]



<p class="wp-block-paragraph">Para sinais lentos (temperatura, nível), cortes entre <strong>5 Hz e 20 Hz</strong> são comuns.</p>



<h3 class="wp-block-heading">Integração de sensores 4–20 mA</h3>



<p class="wp-block-paragraph">Aqui o caminho é mais elegante e previsível.</p>



<p class="wp-block-paragraph"><strong>Resistor de carga (burden)</strong><br>Escolhendo \(R_b = 250,\Omega\):</p>



<p class="wp-block-paragraph">\[<br>V = I \cdot R_b<br>\]



<ul class="wp-block-list">
<li>4 mA → 1,0 V</li>



<li>20 mA → 5,0 V</li>
</ul>



<p class="wp-block-paragraph">Se o ADC for de 3,3 V, duas opções surgem:</p>



<ol class="wp-block-list">
<li>usar \(R_b = 165,\Omega\) → 0,66–3,3 V</li>



<li>manter 250 Ω e usar divisor/buffer.</li>
</ol>



<p class="wp-block-paragraph">A primeira opção costuma ser preferida pela simplicidade.</p>



<p class="wp-block-paragraph"><strong>Potência do resistor</strong><br>A potência dissipada é:</p>



<p class="wp-block-paragraph">\[<br>P = I^2 \cdot R<br>\]



<p class="wp-block-paragraph">No pior caso (20 mA, 250 Ω):</p>



<p class="wp-block-paragraph">\[<br>P = (0{,}02)^2 \cdot 250 = 0{,}1,W<br>\]



<p class="wp-block-paragraph">Logo, usa-se resistor de <strong>0,25 W ou maior</strong>, com baixa deriva térmica.</p>



<h3 class="wp-block-heading">Conversão no firmware</h3>



<p class="wp-block-paragraph">No firmware, a leitura do ADC ((N) bits) gera um valor digital (D):</p>



<p class="wp-block-paragraph">\[<br>V_{ADC} = \frac{D}{2^N &#8211; 1} \cdot V_{ref}<br>\]



<p class="wp-block-paragraph">Para 4–20 mA:</p>



<p class="wp-block-paragraph">\[<br>I = \frac{V_{ADC}}{R_b}<br>\]



<p class="wp-block-paragraph">E o escalonamento final:</p>



<p class="wp-block-paragraph">\[<br>y = y_{\min} + \frac{(I &#8211; 4,\text{mA})}{16,\text{mA}}(y_{\max} &#8211; y_{\min})<br>\]



<p class="wp-block-paragraph">Boas práticas de firmware:</p>



<ul class="wp-block-list">
<li>rejeitar leituras abaixo de <strong>3,8 mA</strong> (falha);</li>



<li>filtrar por média móvel ou filtro IIR simples;</li>



<li>separar claramente <strong>aquisição</strong>, <strong>conversão</strong> e <strong>lógica de controle</strong>.</li>
</ul>



<h3 class="wp-block-heading">Layout e EMC</h3>



<p class="wp-block-paragraph">Independentemente do padrão:</p>



<ul class="wp-block-list">
<li>mantenha trilhas analógicas longe de PWM, clocks e barramentos rápidos;</li>



<li>use <strong>plano de terra contínuo</strong>;</li>



<li>aterramento da blindagem do cabo em <strong>um único ponto</strong>;</li>



<li>considere isolamento galvânico em ambientes severos.</li>
</ul>



<p class="wp-block-paragraph">Esses cuidados fazem mais diferença do que aumentar bits de ADC.</p>



<h2 class="wp-block-heading">Seção 6 — Conclusão técnica: por que 0–10 V e 4–20 mA continuam dominantes na indústria</h2>



<p class="wp-block-paragraph">Mesmo com a evolução de barramentos digitais industriais, Ethernet determinística e sensores inteligentes, os padrões <strong>0–10 V</strong> e <strong>4–20 mA</strong> permanecem amplamente utilizados porque resolvem, de forma simples e comprovada, um problema central da automação: <strong>transportar informação analógica com previsibilidade em ambientes hostis</strong>. Eles não dependem de pilhas de protocolo, não exigem sincronismo complexo e falham de maneira compreensível para técnicos e engenheiros de campo.</p>



<p class="wp-block-paragraph">O <strong>0–10 V</strong> sobrevive pela simplicidade. Ele é direto, fácil de depurar com um multímetro comum e suficiente para aplicações locais, máquinas compactas e painéis onde o controle de aterramento e ruído é viável. Em termos de engenharia, é um padrão que funciona bem quando o sistema é tratado como um todo — sensor, cabo, referência e ADC — e quando as limitações são conscientemente aceitas.</p>



<p class="wp-block-paragraph">Já o <strong>4–20 mA</strong> permanece como referência em confiabilidade porque sua robustez é estrutural, não circunstancial. A imunidade a ruído, a tolerância a longas distâncias, a independência de referência de terra e o conceito de <strong>zero vivo</strong> fazem dele um padrão naturalmente alinhado com requisitos de segurança, manutenção e diagnóstico. Em projetos industriais reais, isso se traduz em menos paradas, menos ambiguidades e decisões mais claras no firmware e na operação.</p>



<p class="wp-block-paragraph">Do ponto de vista de sistemas embarcados, esses padrões também ensinam uma lição importante: <strong>engenharia de sinal vem antes de sofisticação de processamento</strong>. Um ADC de alta resolução ou um algoritmo avançado não compensam um front-end mal escolhido. É por isso que, mesmo em arquiteturas modernas com STM32, ESP32 ou SoCs industriais, o caminho analógico clássico continua sendo a fundação.</p>



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



<ul class="wp-block-list">
<li>0–10 V é uma solução eficiente quando simplicidade e proximidade física são garantidas.</li>



<li>4–20 mA é a escolha natural quando confiabilidade, diagnóstico e ambiente industrial severo entram em jogo.</li>



<li>a escolha correta reduz complexidade no hardware, no firmware e na manutenção ao longo de toda a vida útil do sistema.</li>
</ul>



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



<h2 class="wp-block-heading">Materiais para SEO</h2>



<h3 class="wp-block-heading">Título do artigo</h3>



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



<h3 class="wp-block-heading">Frase chave foco</h3>



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



<p class="wp-block-paragraph"></p><p>The post <a href="https://mcu.tec.br/infraestrutura/por-que-sensores-industriais-usam-0-10-v-e-4-20-ma-fundamentos-formulas-e-aplicacoes-praticas/">Por que sensores industriais usam 0–10 V e 4–20 mA? Fundamentos, fórmulas e aplicações práticas</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1003</post-id>	</item>
		<item>
		<title>Sistema PID e Diferenças entre Sistemas de Controle Aberto e Fechado</title>
		<link>https://mcu.tec.br/algoritimos/sistema-pid-e-diferencas-entre-sistemas-de-controle-aberto-e-fechado/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sistema-pid-e-diferencas-entre-sistemas-de-controle-aberto-e-fechado</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Thu, 13 Mar 2025 21:38:44 +0000</pubDate>
				<category><![CDATA[Algoritimos]]></category>
		<category><![CDATA[algoritmo PID em C]]></category>
		<category><![CDATA[automação industrial]]></category>
		<category><![CDATA[código PID em C]]></category>
		<category><![CDATA[controle aberto]]></category>
		<category><![CDATA[controle derivativo]]></category>
		<category><![CDATA[controle fechado]]></category>
		<category><![CDATA[controle integral]]></category>
		<category><![CDATA[controle PID]]></category>
		<category><![CDATA[controle proporcional]]></category>
		<category><![CDATA[engenharia de controle]]></category>
		<category><![CDATA[estabilidade do sistema]]></category>
		<category><![CDATA[implementação de PID]]></category>
		<category><![CDATA[otimização de controle]]></category>
		<category><![CDATA[programação embarcada]]></category>
		<category><![CDATA[sistemas de controle]]></category>
		<category><![CDATA[sistemas de feedback]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=120</guid>

					<description><![CDATA[<p>Descubra como funciona o controlador PID, suas aplicações e a diferença entre sistemas de controle aberto e fechado. Veja um exemplo prático de implementação do algoritmo em C com código documentado.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/sistema-pid-e-diferencas-entre-sistemas-de-controle-aberto-e-fechado/">Sistema PID e Diferenças entre Sistemas de Controle Aberto e Fechado</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">O controle PID (Proporcional-Integral-Derivativo) é um dos métodos mais amplamente utilizados na automação e controle de processos industriais. Sua aplicação se dá em sistemas onde se deseja controlar uma variável de saída a partir de uma entrada desejada, minimizando erros e garantindo estabilidade. Este artigo apresenta os fundamentos do controle PID, explora as diferenças entre sistemas de controle aberto e fechado e fornece uma implementação prática do algoritmo em linguagem C, com explicações detalhadas e documentação apropriada.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="585" src="https://mcu.tec.br/wp-content/uploads/2025/03/image-2-1024x585.png" alt="" class="wp-image-122" srcset="https://mcu.tec.br/wp-content/uploads/2025/03/image-2-1024x585.png 1024w, https://mcu.tec.br/wp-content/uploads/2025/03/image-2-300x171.png 300w, https://mcu.tec.br/wp-content/uploads/2025/03/image-2-768x439.png 768w, https://mcu.tec.br/wp-content/uploads/2025/03/image-2-1536x878.png 1536w, https://mcu.tec.br/wp-content/uploads/2025/03/image-2.png 1792w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading"><strong>Introdução aos Sistemas de Controle</strong></h2>



<p class="wp-block-paragraph">Os sistemas de controle são fundamentais em diversas áreas da engenharia, permitindo a automação de processos mecânicos, elétricos e químicos. De maneira geral, esses sistemas podem ser classificados em <strong>controle aberto</strong> e <strong>controle fechado</strong>, cada um com características e aplicações distintas.</p>



<h3 class="wp-block-heading"><strong>Sistemas de Controle Aberto</strong></h3>



<p class="wp-block-paragraph">Um sistema de controle aberto é aquele no qual a saída não influencia diretamente a ação de controle. Ou seja, a entrada é aplicada ao sistema e a saída é gerada sem qualquer tipo de realimentação. Esse tipo de controle é simples, mas apresenta limitações significativas, pois não se ajusta automaticamente às variações externas ou internas do sistema.</p>



<h4 class="wp-block-heading"><strong>Exemplo de Sistema de Controle Aberto</strong></h4>



<ul class="wp-block-list">
<li><strong>Torradeira elétrica</strong>: Uma torradeira aplica calor ao pão por um tempo pré-determinado sem medir se ele realmente atingiu o nível de tostagem desejado.</li>
</ul>



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



<ul class="wp-block-list">
<li>Simplicidade na implementação;</li>



<li>Baixo custo.</li>
</ul>



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



<ul class="wp-block-list">
<li>Sensibilidade a perturbações externas;</li>



<li>Incapacidade de correção automática de erros.</li>
</ul>



<h3 class="wp-block-heading"><strong>Sistemas de Controle Fechado</strong></h3>



<p class="wp-block-paragraph">Diferente dos sistemas abertos, um sistema de controle fechado utiliza realimentação (feedback) para ajustar automaticamente a saída conforme a necessidade. Um sensor mede a variável de saída e compara com o valor desejado (setpoint), ajustando o sinal de controle para minimizar o erro.</p>



<h4 class="wp-block-heading"><strong>Exemplo de Sistema de Controle Fechado</strong></h4>



<ul class="wp-block-list">
<li><strong>Controle de temperatura de um forno</strong>: Um sensor mede a temperatura interna do forno e ajusta a potência do aquecedor para manter a temperatura desejada.</li>
</ul>



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



<ul class="wp-block-list">
<li>Maior precisão no controle da variável de interesse;</li>



<li>Capacidade de compensação de perturbações externas;</li>



<li>Melhor estabilidade do sistema.</li>
</ul>



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



<ul class="wp-block-list">
<li>Maior complexidade e custo;</li>



<li>Necessidade de calibração e ajuste dos parâmetros.</li>
</ul>



<h2 class="wp-block-heading"><strong>Fundamentos do Controle PID</strong></h2>



<p class="wp-block-paragraph">O controlador PID é um tipo de controlador de realimentação que utiliza três componentes matemáticos principais para ajustar a resposta do sistema: <strong>Proporcional (P), Integral (I) e Derivativo (D)</strong>. A equação geral do PID pode ser expressa como: u(t)=Kpe(t)+Ki∫e(t)dt+Kdde(t)dtu(t) = K_p e(t) + K_i \int e(t) dt + K_d \frac{d e(t)}{dt}</p>



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



<ul class="wp-block-list">
<li>u(t)u(t) é o sinal de controle;</li>



<li>e(t)e(t) é o erro, definido como a diferença entre o valor desejado e o valor atual;</li>



<li>KpK_p é o ganho proporcional;</li>



<li>KiK_i é o ganho integral;</li>



<li>KdK_d é o ganho derivativo.</li>
</ul>



<p class="wp-block-paragraph">Cada um desses termos tem um papel fundamental no comportamento do sistema:</p>



<ul class="wp-block-list">
<li><strong>Proporcional (P):</strong> Controla a resposta imediata do sistema ao erro, ajustando a intensidade do sinal de controle proporcionalmente ao erro.</li>



<li><strong>Integral (I):</strong> Acumula os erros passados para eliminar erros de estado estacionário.</li>



<li><strong>Derivativo (D):</strong> Prever tendências futuras de erro e atuar para minimizar oscilações.</li>
</ul>



<h2 class="wp-block-heading"><strong>Implementação do Algoritmo PID em C</strong></h2>



<p class="wp-block-paragraph">Para demonstrar o funcionamento do controlador PID, implementamos um algoritmo em C, documentado e estruturado para ser usado em sistemas embarcados e aplicações de controle industrial.</p>



<p class="wp-block-paragraph">A implementação abaixo utiliza uma estrutura de dados para armazenar os parâmetros do controlador PID e inclui uma função para calcular a saída do controlador com base no erro de entrada.</p>



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



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

// Definição da estrutura do controlador PID
typedef struct {
    double Kp;  // Ganho Proporcional
    double Ki;  // Ganho Integral
    double Kd;  // Ganho Derivativo
    double prevError; // Erro anterior
    double integral;  // Acumulador do termo integral
    double dt;  // Tempo de amostragem
} PIDController;

// Função para inicializar o controlador PID
void PID_Init(PIDController *pid, double Kp, double Ki, double Kd, double dt) {
    pid-&gt;Kp = Kp;
    pid-&gt;Ki = Ki;
    pid-&gt;Kd = Kd;
    pid-&gt;prevError = 0.0;
    pid-&gt;integral = 0.0;
    pid-&gt;dt = dt;
}

// Função para calcular a saída do controlador PID
double PID_Compute(PIDController *pid, double setpoint, double measuredValue) {
    double error = setpoint - measuredValue;  // Calcula o erro
    pid-&gt;integral += error * pid-&gt;dt;  // Calcula o termo integral
    double derivative = (error - pid-&gt;prevError) / pid-&gt;dt;  // Calcula o termo derivativo

    // Calcula a saída do PID
    double output = (pid-&gt;Kp * error) + (pid-&gt;Ki * pid-&gt;integral) + (pid-&gt;Kd * derivative);

    // Atualiza o erro anterior para a próxima iteração
    pid-&gt;prevError = error;

    return output;
}

// Exemplo de uso do controlador PID
int main() {
    PIDController pid;
    PID_Init(&amp;pid, 1.2, 0.01, 0.5, 0.1);  // Inicializa o PID com valores arbitrários

    double setpoint = 100.0;  // Valor desejado
    double measuredValue = 90.0;  // Valor real medido

    for (int i = 0; i < 10; i++) {  // Simulação de 10 iterações
        double controlSignal = PID_Compute(&amp;pid, setpoint, measuredValue);
        measuredValue += controlSignal * 0.1;  // Simula um sistema reagindo ao controle

        printf(&quot;Iteração %d - Controle: %.2f - Medida Atual: %.2f\n&quot;, i + 1, controlSignal, measuredValue);
    }

    return 0;
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&lt;</span><span style="color: #8FBCBB">stdio.h</span><span style="color: #ECEFF4">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Definição da estrutura do controlador PID</span></span>
<span class="line"><span style="color: #81A1C1">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> Kp</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Ganho Proporcional</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> Ki</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Ganho Integral</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> Kd</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Ganho Derivativo</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> prevError</span><span style="color: #81A1C1">;</span><span style="color: #616E88"> // Erro anterior</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> integral</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Acumulador do termo integral</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> dt</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Tempo de amostragem</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> PIDController</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Função para inicializar o controlador PID</span></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">PID_Init</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">PIDController </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pid</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Kp</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Ki</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Kd</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dt</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> Kp</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">Ki</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> Ki</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">Kd</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> Kd</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">prevError</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">dt</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> dt</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">// Função para calcular a saída do controlador PID</span></span>
<span class="line"><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">PID_Compute</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">PIDController </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pid</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">setpoint</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">measuredValue</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> error </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> setpoint </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> measuredValue</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Calcula o erro</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">integral</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> error </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">dt</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Calcula o termo integral</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> derivative </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">error </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">prevError</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">dt</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Calcula o termo derivativo</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Calcula a saída do PID</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> output </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">Kp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> error</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">Ki</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">integral</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">Kd</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> derivative</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Atualiza o erro anterior para a próxima iteração</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pid</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">prevError</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> error</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"> output</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">// Exemplo de uso do controlador PID</span></span>
<span class="line"><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">main</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    PIDController pid</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">PID_Init</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF">pid</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.01</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.5</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.1</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Inicializa o PID com valores arbitrários</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> setpoint </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100.0</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Valor desejado</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> measuredValue </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">90.0</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Valor real medido</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> i </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"> i </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> i</span><span style="color: #81A1C1">++</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #616E88">  // Simulação de 10 iterações</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">double</span><span style="color: #D8DEE9FF"> controlSignal </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">PID_Compute</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF">pid</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> setpoint</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> measuredValue</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        measuredValue </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> controlSignal </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.1</span><span style="color: #81A1C1">;</span><span style="color: #616E88">  // Simula um sistema reagindo ao controle</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">printf</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Iteração %d - Controle: %.2f - Medida Atual: %.2f</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> i </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> controlSignal</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> measuredValue</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



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



<h3 class="wp-block-heading"><strong>Explicação do Código</strong></h3>



<p class="wp-block-paragraph">O código acima segue uma estrutura modular e bem documentada:</p>



<ol class="wp-block-list">
<li><strong>Estrutura <code>PIDController</code></strong>:
<ul class="wp-block-list">
<li>Armazena os parâmetros do controlador (<code>Kp</code>, <code>Ki</code>, <code>Kd</code>).</li>



<li>Mantém o erro anterior e o termo integral acumulado.</li>



<li>Inclui o tempo de amostragem (<code>dt</code>), necessário para cálculos diferenciais.</li>
</ul>
</li>



<li><strong>Função <code>PID_Init</code></strong>:
<ul class="wp-block-list">
<li>Inicializa os valores do controlador, garantindo que os estados internos sejam zerados.</li>
</ul>
</li>



<li><strong>Função <code>PID_Compute</code></strong>:
<ul class="wp-block-list">
<li>Calcula o erro entre o valor desejado (<code>setpoint</code>) e o valor real (<code>measuredValue</code>).</li>



<li>Atualiza o termo integral e computa a derivada do erro.</li>



<li>Gera a saída do controlador PID.</li>
</ul>
</li>



<li><strong>Função <code>main</code></strong>:
<ul class="wp-block-list">
<li>Cria um controlador PID e o inicializa com ganhos arbitrários.</li>



<li>Simula um sistema onde a saída do PID afeta diretamente a variável controlada.</li>



<li>Exibe os valores de controle ao longo das iterações.</li>
</ul>
</li>
</ol><p>The post <a href="https://mcu.tec.br/algoritimos/sistema-pid-e-diferencas-entre-sistemas-de-controle-aberto-e-fechado/">Sistema PID e Diferenças entre Sistemas de Controle Aberto e Fechado</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">120</post-id>	</item>
		<item>
		<title>O Barramento RS485: Teoria e Funcionamento</title>
		<link>https://mcu.tec.br/protoclos/o-barramento-rs485-teoria-e-funcionamento/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=o-barramento-rs485-teoria-e-funcionamento</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Thu, 02 Jan 2025 00:19:54 +0000</pubDate>
				<category><![CDATA[protocolos]]></category>
		<category><![CDATA[automação industrial]]></category>
		<category><![CDATA[automação predial]]></category>
		<category><![CDATA[automação residencial]]></category>
		<category><![CDATA[automação SCADA]]></category>
		<category><![CDATA[barramento RS485]]></category>
		<category><![CDATA[cabo trançado]]></category>
		<category><![CDATA[comunicação de longo alcance]]></category>
		<category><![CDATA[comunicação diferencial]]></category>
		<category><![CDATA[comunicação robusta]]></category>
		<category><![CDATA[controle de direção.]]></category>
		<category><![CDATA[dispositivos RS485]]></category>
		<category><![CDATA[full-duplex]]></category>
		<category><![CDATA[half-duplex]]></category>
		<category><![CDATA[imunidade a ruídos]]></category>
		<category><![CDATA[multidrop]]></category>
		<category><![CDATA[padrão RS485]]></category>
		<category><![CDATA[protocolos Modbus]]></category>
		<category><![CDATA[redes industriais]]></category>
		<category><![CDATA[RS485]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[terminação do barramento]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=41</guid>

					<description><![CDATA[<p>Entenda o funcionamento e aplicações do barramento RS485 na comunicação industrial e sistemas embarcados.</p>
<p>The post <a href="https://mcu.tec.br/protoclos/o-barramento-rs485-teoria-e-funcionamento/">O Barramento RS485: Teoria e Funcionamento</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">O <strong>RS485</strong> é um padrão amplamente utilizado na comunicação de dados em sistemas embarcados e industriais devido à sua robustez, confiabilidade e capacidade de operar em ambientes ruidosos. Este artigo busca esclarecer os fundamentos teóricos e o funcionamento prático do RS485, abordando suas características técnicas, vantagens e aplicações.</p>



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



<h3 class="wp-block-heading">Introdução ao RS485</h3>



<p class="wp-block-paragraph">O padrão RS485 foi desenvolvido para atender à necessidade de comunicação confiável em ambientes industriais, onde ruídos eletromagnéticos e longas distâncias são comuns. Baseado em sinalização diferencial, o RS485 oferece maior imunidade a interferências externas, permitindo comunicação eficiente mesmo em condições adversas.</p>



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



<h3 class="wp-block-heading">Características Técnicas do RS485</h3>



<ol class="wp-block-list">
<li><strong>Sinalização Diferencial</strong>:
<ul class="wp-block-list">
<li>No RS485, os dados são transmitidos por meio de dois fios, geralmente identificados como <strong>A</strong> e <strong>B</strong>.</li>



<li>Um sinal diferencial é criado invertendo a polaridade do sinal nos fios, o que ajuda a cancelar os ruídos comuns que afetam ambos os fios igualmente.</li>
</ul>
</li>



<li><strong>Topologia de Comunicação</strong>:
<ul class="wp-block-list">
<li>Suporta topologia <strong>multidrop</strong>, ou seja, vários dispositivos podem ser conectados ao mesmo barramento, formando uma rede.</li>



<li>Um barramento RS485 pode conter até <strong>32 transceptores</strong> em sua configuração básica, mas usando transceptores de alta impedância, esse número pode aumentar.</li>
</ul>
</li>



<li><strong>Distâncias e Velocidades</strong>:
<ul class="wp-block-list">
<li>O RS485 opera em longas distâncias, podendo atingir até <strong>1200 metros</strong> em velocidades de até <strong>100 kbps</strong>.</li>



<li>Velocidades maiores são possíveis, mas a distância máxima é reduzida devido às limitações de atenuação e tempo de propagação do sinal.</li>
</ul>
</li>



<li><strong>Modo de Operação</strong>:
<ul class="wp-block-list">
<li>Pode funcionar em modo <strong>half-duplex</strong> ou <strong>full-duplex</strong>, dependendo do número de fios usados:
<ul class="wp-block-list">
<li><strong>Half-duplex</strong>: Usa dois fios (A e B) e exige controle do sentido de transmissão.</li>



<li><strong>Full-duplex</strong>: Requer quatro fios (um par para transmissão e outro para recepção).</li>
</ul>
</li>
</ul>
</li>



<li><strong>Terminação do Barramento</strong>:
<ul class="wp-block-list">
<li>Em sistemas RS485, resistores de terminação são adicionados nas extremidades do barramento para minimizar reflexões do sinal e garantir a integridade dos dados.</li>
</ul>
</li>
</ol>



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



<h3 class="wp-block-heading">Funcionamento do RS485</h3>



<p class="wp-block-paragraph">O RS485 opera com base em transceptores, que convertem sinais lógicos em sinais diferenciais e vice-versa. O funcionamento pode ser dividido em:</p>



<ol class="wp-block-list">
<li><strong>Transmissão de Dados</strong>:
<ul class="wp-block-list">
<li>Quando um dispositivo deseja transmitir, ele ativa o driver do barramento e envia um sinal diferencial pelos fios A e B.</li>



<li>A lógica <strong>1</strong> é representada por A > B, enquanto a lógica <strong>0</strong> é representada por A &lt; B.</li>
</ul>
</li>



<li><strong>Recepção de Dados</strong>:
<ul class="wp-block-list">
<li>O receptor detecta a diferença de tensão entre os fios e a converte em um nível lógico correspondente.</li>
</ul>
</li>



<li><strong>Controle de Direção</strong>:
<ul class="wp-block-list">
<li>No modo half-duplex, o controle de direção é crítico para evitar conflitos no barramento. Um pino de controle no microcontrolador (geralmente chamado DE ou Driver Enable) é usado para alternar entre transmissão e recepção.</li>
</ul>
</li>
</ol>



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



<h3 class="wp-block-heading">Vantagens do RS485</h3>



<ul class="wp-block-list">
<li><strong>Imunidade a Ruídos</strong>: A sinalização diferencial reduz a suscetibilidade a interferências eletromagnéticas.</li>



<li><strong>Comunicação de Longo Alcance</strong>: Permite transmissão em grandes distâncias sem perda significativa de sinal.</li>



<li><strong>Multidrop</strong>: Suporte para múltiplos dispositivos conectados ao mesmo barramento.</li>



<li><strong>Flexibilidade</strong>: Pode operar em diferentes configurações de topologia e modos de comunicação.</li>
</ul>



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



<h3 class="wp-block-heading">Aplicações do RS485</h3>



<p class="wp-block-paragraph">O RS485 é amplamente utilizado em aplicações industriais e comerciais, como:</p>



<ul class="wp-block-list">
<li><strong>Automação Industrial</strong>: Redes de sensores e controladores, como em sistemas SCADA e PLCs.</li>



<li><strong>Automação Predial</strong>: Controle de HVAC (aquecimento, ventilação e ar-condicionado) e sistemas de segurança.</li>



<li><strong>Dispositivos Médicos</strong>: Comunicação entre equipamentos médicos em redes locais.</li>



<li><strong>Sistemas de Energia</strong>: Monitoramento e controle de inversores, medidores inteligentes e UPS.</li>
</ul>



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



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



<p class="wp-block-paragraph">Para implementar um sistema RS485, é essencial considerar:</p>



<ol class="wp-block-list">
<li><strong>Resistores de Terminação</strong>:
<ul class="wp-block-list">
<li>O valor típico é de <strong>120 Ω</strong>, ajustado para o cabo utilizado.</li>
</ul>
</li>



<li><strong>Cabos Adequados</strong>:
<ul class="wp-block-list">
<li>Use cabos trançados e blindados para garantir a melhor qualidade de transmissão.</li>
</ul>
</li>



<li><strong>Protocolo de Comunicação</strong>:
<ul class="wp-block-list">
<li>O RS485 define o meio físico, mas o protocolo de comunicação deve ser implementado, como Modbus RTU ou DMX512.</li>
</ul>
</li>
</ol>



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



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



<p class="wp-block-paragraph">O RS485 é um barramento confiável e versátil, ideal para aplicações que exigem comunicação robusta em ambientes desafiadores. Sua ampla adoção no mercado reflete sua eficiência e adaptabilidade. Para projetos com sistemas embarcados ou industriais, o RS485 continua sendo uma escolha sólida e eficaz.</p><p>The post <a href="https://mcu.tec.br/protoclos/o-barramento-rs485-teoria-e-funcionamento/">O Barramento RS485: Teoria e Funcionamento</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">41</post-id>	</item>
		<item>
		<title>Introdução ao ESP-Modbus com ESP-IDF</title>
		<link>https://mcu.tec.br/protoclos/introducao-ao-esp-modbus-com-esp-idf/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introducao-ao-esp-modbus-com-esp-idf</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sat, 28 Dec 2024 04:57:34 +0000</pubDate>
				<category><![CDATA[Modbus]]></category>
		<category><![CDATA[protocolos]]></category>
		<category><![CDATA[API Modbus]]></category>
		<category><![CDATA[atuadores Modbus]]></category>
		<category><![CDATA[automação industrial]]></category>
		<category><![CDATA[automação residencial]]></category>
		<category><![CDATA[coils]]></category>
		<category><![CDATA[comunicação mestre-escravo]]></category>
		<category><![CDATA[comunicação serial]]></category>
		<category><![CDATA[comunicação TCP/IP]]></category>
		<category><![CDATA[configuração ESP32]]></category>
		<category><![CDATA[configuração Modbus]]></category>
		<category><![CDATA[controle de atuadores]]></category>
		<category><![CDATA[controle remoto]]></category>
		<category><![CDATA[diagnóstico Modbus]]></category>
		<category><![CDATA[dicionário de dados Modbus]]></category>
		<category><![CDATA[dispositivos industriais.]]></category>
		<category><![CDATA[escravo Modbus]]></category>
		<category><![CDATA[esp-idf]]></category>
		<category><![CDATA[ESP-Modbus]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[exemplos Modbus]]></category>
		<category><![CDATA[FreeModbus]]></category>
		<category><![CDATA[holding registers]]></category>
		<category><![CDATA[input registers]]></category>
		<category><![CDATA[integração industrial]]></category>
		<category><![CDATA[mestre Modbus]]></category>
		<category><![CDATA[Modbus ASCII]]></category>
		<category><![CDATA[Modbus RTU]]></category>
		<category><![CDATA[Modbus TCP/IP]]></category>
		<category><![CDATA[monitoramento de sensores]]></category>
		<category><![CDATA[protocolos de comunicação]]></category>
		<category><![CDATA[rede Modbus]]></category>
		<category><![CDATA[redes industriais]]></category>
		<category><![CDATA[registro Modbus]]></category>
		<category><![CDATA[registros de entrada]]></category>
		<category><![CDATA[RS-485]]></category>
		<category><![CDATA[SCADA]]></category>
		<category><![CDATA[sensores Modbus]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=31</guid>

					<description><![CDATA[<p>O Modbus é um protocolo de comunicação amplamente utilizado na indústria para conectar dispositivos eletrônicos, como sensores e atuadores. Com o suporte nativo no ESP32 por meio da biblioteca ESP-Modbus, integrá-lo a projetos embarcados torna-se uma tarefa eficiente e confiável. Este artigo explora como utilizar o ESP-Modbus na plataforma ESP-IDF, explicando conceitos-chave e orientando sobre [&#8230;]</p>
<p>The post <a href="https://mcu.tec.br/protoclos/introducao-ao-esp-modbus-com-esp-idf/">Introdução ao ESP-Modbus com ESP-IDF</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">O Modbus é um protocolo de comunicação amplamente utilizado na indústria para conectar dispositivos eletrônicos, como sensores e atuadores. Com o suporte nativo no ESP32 por meio da biblioteca ESP-Modbus, integrá-lo a projetos embarcados torna-se uma tarefa eficiente e confiável.</p>



<p class="wp-block-paragraph">Este artigo explora como utilizar o ESP-Modbus na plataforma ESP-IDF, explicando conceitos-chave e orientando sobre a configuração de comunicação com dispositivos Modbus em suas variantes mais comuns, como <strong>Modbus RTU</strong>, <strong>Modbus ASCII</strong> e <strong>Modbus TCP/IP</strong>.</p>



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



<h2 class="wp-block-heading">Visão Geral do Modbus</h2>



<p class="wp-block-paragraph">O protocolo Modbus define regras de comunicação para troca de mensagens entre dispositivos mestre (master) e escravos (slaves) em uma rede. Ele é amplamente adotado em aplicações industriais devido à sua simplicidade e eficiência.</p>



<h3 class="wp-block-heading">Tipos de Modbus:</h3>



<ol class="wp-block-list">
<li><strong>Modbus RTU (Remote Terminal Unit):</strong>
<ul class="wp-block-list">
<li>Comunicação serial com dados representados em formato binário compacto.</li>



<li>Utiliza verificação de erros com checksum (CRC).</li>



<li>Requer intervalos de silêncio para enquadrar mensagens, sendo o <strong>RS-485</strong> a interface mais utilizada.</li>
</ul>
</li>



<li><strong>Modbus ASCII:</strong>
<ul class="wp-block-list">
<li>Dados em formato legível por humanos (ASCII).</li>



<li>Inclui checagem de erros com verificação longitudinal (LRC).</li>



<li>Mensagens são delimitadas por um caractere <code>:</code> no início e CR/LF no final.</li>
</ul>
</li>



<li><strong>Modbus TCP/IP:</strong>
<ul class="wp-block-list">
<li>Adaptação para redes Ethernet utilizando o protocolo TCP/IP.</li>



<li>Transmissão via porta padrão 502, sem necessidade de checksum adicional devido à proteção fornecida pelas camadas inferiores do TCP/IP.</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph">Os dados no Modbus são organizados em registros, que podem ser de quatro tipos principais:</p>



<ul class="wp-block-list">
<li><strong>Coils (Saídas discretas):</strong> Valores binários para controle de atuadores.</li>



<li><strong>Discrete Inputs (Entradas discretas):</strong> Leituras binárias de sensores.</li>



<li><strong>Holding Registers:</strong> Valores de 16 bits para leitura e escrita.</li>



<li><strong>Input Registers:</strong> Valores de 16 bits apenas para leitura.</li>
</ul>



<p class="wp-block-paragraph">A biblioteca ESP-Modbus do ESP32 é baseada na FreeModbus, oferecendo suporte para as implementações <strong>RTU</strong>, <strong>ASCII</strong> e <strong>TCP/IP</strong>, tanto para dispositivos mestre quanto escravo.</p>



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



<h2 class="wp-block-heading">Modelo de Mensagem e Mapeamento de Dados</h2>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://docs.espressif.com/projects/esp-idf/en/v4.4.3/esp32/_images/modbus-segment.png" alt="Modbus segment diagram"/><figcaption class="wp-element-caption">Modbus segment diagram</figcaption></figure>
</div>


<p class="wp-block-paragraph">O Modbus é um protocolo baseado em registros que define um modelo de comunicação estruturado, independente do meio físico utilizado para a transmissão de dados. Este modelo organiza as mensagens como transações entre dispositivos mestre e escravo, onde o mestre controla toda a comunicação.</p>



<h3 class="wp-block-heading">Comunicação Mestre-Escravo</h3>



<p class="wp-block-paragraph">Em uma rede Modbus:</p>



<ul class="wp-block-list">
<li>O <strong>mestre</strong> envia comandos para os dispositivos <strong>escravos</strong>.</li>



<li>Os <strong>escravos</strong> respondem aos comandos ou permanecem inativos se não forem endereçados.</li>



<li>Não há comunicação direta entre escravos.</li>
</ul>



<p class="wp-block-paragraph">No caso do <strong>Modbus TCP/IP</strong>, múltiplos mestres podem coexistir na mesma rede, aproveitando a natureza da comunicação IP.</p>



<h3 class="wp-block-heading">Tipos de Registros no Modbus<figure><img decoding="async" class="aligncenter" src="https://docs.espressif.com/projects/esp-idf/en/v4.4.3/esp32/_images/modbus-data-mapping.png" alt="Modbus data mapping"></figure></h3>



<p class="wp-block-paragraph">Os dispositivos mapeiam seus dados em quatro tipos de registros que representam características físicas, como leituras de sensores ou estados de atuadores. Abaixo, detalhamos esses tipos:</p>



<ol class="wp-block-list">
<li><strong>Coils (Saídas Discretas):</strong>
<ul class="wp-block-list">
<li>Bits de saída que podem ser controlados pelo mestre.</li>



<li>Geralmente usados para ligar/desligar dispositivos como relés.</li>
</ul>
</li>



<li><strong>Discrete Inputs (Entradas Discretas):</strong>
<ul class="wp-block-list">
<li>Bits de entrada somente leitura.</li>



<li>Utilizados para monitorar estados, como o fechamento de um contato.</li>
</ul>
</li>



<li><strong>Holding Registers:</strong>
<ul class="wp-block-list">
<li>Registros de 16 bits que permitem leitura e escrita.</li>



<li>Comumente usados para armazenar valores configuráveis, como setpoints de temperatura.</li>
</ul>
</li>



<li><strong>Input Registers:</strong>
<ul class="wp-block-list">
<li>Registros de 16 bits somente leitura.</li>



<li>Geralmente associados a sensores analógicos que enviam valores convertidos.</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading">Mapeamento de Dados no ESP-Modbus</h3>



<p class="wp-block-paragraph">No ESP-Modbus, cada dispositivo na rede é identificado por um <strong>endereço escravo único</strong>, configurado em seu manual. O mestre deve conhecer o mapa de registros do dispositivo para acessar os dados corretamente. Esse mapa define:</p>



<ul class="wp-block-list">
<li>O tipo de registro (Coil, Holding, etc.).</li>



<li>O endereço inicial.</li>



<li>A quantidade de registros disponíveis.</li>
</ul>



<p class="wp-block-paragraph">Este mapeamento é essencial para configurar o Modbus no ESP32 e estabelecer uma comunicação eficiente entre dispositivos.</p>



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



<h2 class="wp-block-heading">Inicialização da Porta Modbus</h2>



<p class="wp-block-paragraph">Para iniciar a comunicação Modbus em um ESP32 utilizando o ESP-Modbus, é necessário configurar corretamente a porta de comunicação. O ESP-Modbus suporta tanto comunicação <strong>serial</strong> (via RTU ou ASCII) quanto <strong>TCP/IP</strong>. A inicialização correta da porta é o primeiro passo para utilizar as APIs disponíveis.</p>



<h3 class="wp-block-heading">Configuração de Portas no ESP-Modbus</h3>



<p class="wp-block-paragraph">O ESP-Modbus fornece as seguintes funções para inicializar controladores Modbus, tanto para dispositivos mestre quanto escravo, dependendo do tipo de comunicação:</p>



<ul class="wp-block-list">
<li><p><strong>Serial (RTU/ASCII):</strong></p>
<ul class="wp-block-list">
<li><code>mbc_slave_init()</code>: Inicializa um escravo Modbus em comunicação serial.</li>



<li><code>mbc_master_init()</code>: Inicializa um mestre Modbus em comunicação serial.</li>
</ul>
</li>



<li><p><strong>TCP/IP:</strong></p>
<ul class="wp-block-list">
<li><code>mbc_slave_init_tcp()</code>: Inicializa um escravo Modbus em comunicação TCP/IP.</li>



<li><code>mbc_master_init_tcp()</code>: Inicializa um mestre Modbus em comunicação TCP/IP.</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph">A escolha da função depende do tipo de dispositivo (mestre ou escravo) e do meio de transmissão (serial ou TCP/IP).</p>



<h3 class="wp-block-heading">Exemplo de Inicialização</h3>



<p class="wp-block-paragraph">Para inicializar uma porta serial no modo escravo, o seguinte código pode ser usado:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="void* slave_handler = NULL;
// Estrutura de interface 
esp_err_t err = mbc_slave_init(MB_PORT_SERIAL_SLAVE, &amp;slave_handler); 
if (slave_handler == NULL || err != ESP_OK) {
  ESP_LOGE(TAG, &quot;Falha na inicialização do controlador Modbus.&quot;); 
}" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">slave_handler</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #616E88">// Estrutura de interface </span></span>
<span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_slave_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MB_PORT_SERIAL_SLAVE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">slave_handler</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">slave_handler</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</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">!=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Falha na inicialização do controlador Modbus.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">No caso de comunicação TCP/IP, a inicialização segue um padrão similar, mas com a função mbc_slave_init_tcp:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="void* slave_handler = NULL;
esp_err_t err = mbc_slave_init_tcp(&amp;slave_handler);

if (slave_handler == NULL || err != ESP_OK) {
    ESP_LOGE(TAG, &quot;Falha na inicialização do controlador Modbus TCP.&quot;);
}" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">slave_handler</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_slave_init_tcp</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">slave_handler</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">slave_handler</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</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">!=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Falha na inicialização do controlador Modbus TCP.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



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



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



<p class="wp-block-paragraph">Essas funções configuram a estrutura base para a comunicação Modbus e devem ser chamadas antes de qualquer outra operação relacionada ao protocolo.</p>



<h2 class="wp-block-heading">API Modbus Mestre &#8211; Visão Geral</h2>



<p class="wp-block-paragraph">A API do Modbus para dispositivos mestre no ESP32 oferece uma estrutura completa para configurar, acessar e gerenciar a comunicação com dispositivos escravos. Essa API segue uma sequência lógica de passos para configurar a comunicação e realizar transações.</p>



<h3 class="wp-block-heading">Etapas Principais da Comunicação Mestre</h3>



<ol class="wp-block-list">
<li><strong>Inicialização da Porta Modbus:</strong>
<ul class="wp-block-list">
<li>Configura a interface de comunicação (serial ou TCP/IP) e o controlador mestre.</li>
</ul>
</li>



<li><strong>Configuração do Acesso a Dados:</strong>
<ul class="wp-block-list">
<li>Define os parâmetros que o mestre acessará nos dispositivos escravos.</li>



<li>Utiliza um mapeamento chamado &#8220;Dicionário de Dados&#8221;, que associa identificadores únicos (CID) a registros Modbus.</li>
</ul>
</li>



<li><strong>Opções de Comunicação:</strong>
<ul class="wp-block-list">
<li>Configura parâmetros específicos, como baud rate (para serial) ou endereços IP (para TCP/IP).</li>
</ul>
</li>



<li><strong>Início da Comunicação:</strong>
<ul class="wp-block-list">
<li>Ativa o controlador Modbus, permitindo o envio e recebimento de dados entre mestre e escravos.</li>
</ul>
</li>



<li><strong>Finalização:</strong>
<ul class="wp-block-list">
<li>Libera recursos do controlador Modbus ao finalizar a comunicação.</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading">Dicionário de Dados e CID</h3>



<p class="wp-block-paragraph">O ESP-Modbus introduz um nível de abstração acima do protocolo padrão, denominado &#8220;Dicionário de Dados&#8221;. Cada parâmetro acessível pelo mestre é identificado por:</p>



<ul class="wp-block-list">
<li><strong>CID (Identificador de Característica):</strong> Um número único que identifica um parâmetro no dispositivo escravo.</li>



<li><strong>Nome e Unidades:</strong> Uma descrição textual do parâmetro e sua unidade física (como °C para temperatura).</li>



<li><strong>Tipo de Registro e Endereço:</strong> Define o tipo de registro Modbus (Holding, Input, etc.) e seu endereço inicial no dispositivo escravo.</li>
</ul>



<p class="wp-block-paragraph">Exemplo de definição de parâmetros no Dicionário de Dados:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="mb_parameter_descriptor_t device_parameters[] = {
    { CID_SER_NUM1, &quot;Serial_number_1&quot;, &quot;--&quot;, MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0, 2, 0, PARAM_TYPE_U32, 4 },
    { CID_TEMP_DATA_1, &quot;Temperature_1&quot;, &quot;C&quot;, MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0, 2, 0, PARAM_TYPE_FLOAT, 4 }
};
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">mb_parameter_descriptor_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">device_parameters</span><span style="color: #D8DEE9FF">[] </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: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CID_SER_NUM1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Serial_number_1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">--</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_DEVICE_ADDR1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_INPUT</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: #B48EAD">2</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">PARAM_TYPE_U32</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4</span><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 style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CID_TEMP_DATA_1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Temperature_1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">C</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_DEVICE_ADDR1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_HOLDING</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: #B48EAD">2</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">PARAM_TYPE_FLOAT</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



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



<ul class="wp-block-list">
<li>O parâmetro <code>CID_SER_NUM1</code> refere-se ao número de série do dispositivo.</li>



<li>O parâmetro <code>CID_TEMP_DATA_1</code> mapeia um registro de temperatura em graus Celsius.</li>
</ul>



<h3 class="wp-block-heading">Configuração do Mestre</h3>



<p class="wp-block-paragraph">Após definir o Dicionário de Dados, ele deve ser associado ao controlador Modbus utilizando a função <code>mbc_master_set_descriptor()</code>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="ESP_ERROR_CHECK(mbc_master_set_descriptor(&amp;device_parameters[0], num_device_parameters));
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_master_set_descriptor</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">device_parameters</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">]</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">num_device_parameters</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Isso permite que o mestre acesse os parâmetros do escravo conforme o mapeamento definido.</p>



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



<h2 class="wp-block-heading">Configuração de Acesso a Dados no Mestre</h2>



<p class="wp-block-paragraph">Para que um dispositivo mestre possa acessar parâmetros de dispositivos escravos, é necessário configurar o acesso aos dados. Isso é realizado definindo os detalhes de cada parâmetro que será lido ou escrito, utilizando o <strong>Dicionário de Dados</strong> já apresentado.</p>



<h3 class="wp-block-heading">Estrutura do Dicionário de Dados</h3>



<p class="wp-block-paragraph">Cada entrada no Dicionário de Dados representa uma característica física ou lógica disponível no dispositivo escravo, como temperatura, pressão ou um número de série. A configuração inclui:</p>



<ul class="wp-block-list">
<li><strong>CID (Identificador de Característica):</strong> Um identificador único que referencia o parâmetro.</li>



<li><strong>Endereço do Registro:</strong> Define onde os dados estão localizados no mapa de registros do escravo.</li>



<li><strong>Tipo de Registro:</strong> Especifica se é um registro de entrada, holding, etc.</li>



<li><strong>Tamanho:</strong> Determina quantos registros Modbus são utilizados para armazenar o valor.</li>
</ul>



<h3 class="wp-block-heading">Exemplo Prático de Configuração</h3>



<p class="wp-block-paragraph">Abaixo está um exemplo de definição de parâmetros para dois dispositivos escravos conectados a um mestre:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="mb_parameter_descriptor_t device_parameters[] = {
    { CID_TEMP_DATA_1, &quot;Temperature_1&quot;, &quot;C&quot;, MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0, 2, 0, PARAM_TYPE_FLOAT, 4 },
    { CID_HUMIDITY_1, &quot;Humidity_1&quot;, &quot;%&quot;, MB_DEVICE_ADDR1, MB_PARAM_INPUT, 2, 1, 0, PARAM_TYPE_U16, 2 },
    { CID_TEMP_DATA_2, &quot;Temperature_2&quot;, &quot;C&quot;, MB_DEVICE_ADDR2, MB_PARAM_HOLDING, 0, 2, 0, PARAM_TYPE_FLOAT, 4 },
    { CID_HUMIDITY_2, &quot;Humidity_2&quot;, &quot;%&quot;, MB_DEVICE_ADDR2, MB_PARAM_INPUT, 2, 1, 0, PARAM_TYPE_U16, 2 }
};
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">mb_parameter_descriptor_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">device_parameters</span><span style="color: #D8DEE9FF">[] </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: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CID_TEMP_DATA_1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Temperature_1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">C</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_DEVICE_ADDR1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_HOLDING</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: #B48EAD">2</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">PARAM_TYPE_FLOAT</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4</span><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 style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CID_HUMIDITY_1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Humidity_1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">%</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_DEVICE_ADDR1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_INPUT</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">PARAM_TYPE_U16</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><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 style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CID_TEMP_DATA_2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Temperature_2</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">C</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_DEVICE_ADDR2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_HOLDING</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: #B48EAD">2</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">PARAM_TYPE_FLOAT</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4</span><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 style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CID_HUMIDITY_2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Humidity_2</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">%</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_DEVICE_ADDR2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_INPUT</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">PARAM_TYPE_U16</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



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



<ul class="wp-block-list">
<li><strong>CID_TEMP_DATA_1:</strong> Mapeia a temperatura do dispositivo 1 (endereço <code>MB_DEVICE_ADDR1</code>) em registros de holding.</li>



<li><strong>CID_HUMIDITY_1:</strong> Mapeia a umidade do dispositivo 1 como registro de entrada.</li>



<li><strong>CID_TEMP_DATA_2 e CID_HUMIDITY_2:</strong> Seguem a mesma lógica para o segundo dispositivo.</li>
</ul>



<p class="wp-block-paragraph">O número de parâmetros no Dicionário de Dados pode ser calculado automaticamente:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="uint16_t num_device_parameters = (sizeof(device_parameters) / sizeof(device_parameters[0]));
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">num_device_parameters</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">device_parameters</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">device_parameters</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">]))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Configuração no Controlador Mestre</h3>



<p class="wp-block-paragraph">Após definir o Dicionário de Dados, ele deve ser registrado no controlador Modbus para permitir o acesso aos dispositivos escravos:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="ESP_ERROR_CHECK(mbc_master_set_descriptor(&amp;device_parameters[0], num_device_parameters));
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_master_set_descriptor</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">device_parameters</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">]</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">num_device_parameters</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Com essa configuração, o mestre está preparado para acessar os parâmetros definidos nos escravos, conforme as especificações do Dicionário de Dados.</p>



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



<h2 class="wp-block-heading">Opções de Comunicação do Mestre</h2>



<p class="wp-block-paragraph">Depois de configurar os parâmetros de acesso no Dicionário de Dados, é necessário definir as opções de comunicação do mestre para garantir uma troca de dados eficiente e confiável com os dispositivos escravos. Essas opções incluem parâmetros de comunicação específicos para cada tipo de interface: serial ou TCP/IP.</p>



<h3 class="wp-block-heading">Configuração de Comunicação Serial</h3>



<p class="wp-block-paragraph">Ao utilizar a comunicação serial (Modbus RTU ou ASCII), os seguintes parâmetros devem ser definidos:</p>



<ul class="wp-block-list">
<li><strong>Porta Serial:</strong> Identifica qual porta UART será utilizada.</li>



<li><strong>Modo de Comunicação:</strong> Define se será RTU ou ASCII.</li>



<li><strong>Taxa de Baud:</strong> Determina a velocidade da transmissão em bits por segundo.</li>



<li><strong>Paridade:</strong> Especifica o tipo de verificação de paridade (nenhuma, ímpar ou par).</li>
</ul>



<p class="wp-block-paragraph">Exemplo de configuração para uma porta serial:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="mb_communication_info_t comm_info = {
    .port = MB_PORT_NUM,        // Número da porta serial
    .mode = MB_MODE_RTU,        // Modo de comunicação Modbus (RTU ou ASCII)
    .baudrate = 9600,           // Taxa de transmissão em bits por segundo
    .parity = MB_PARITY_NONE    // Tipo de paridade (nenhuma neste caso)
};

// Configura o mestre Modbus com os parâmetros de comunicação
ESP_ERROR_CHECK(mbc_master_setup((void*)&amp;comm_info));
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">mb_communication_info_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF"> </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">port</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PORT_NUM</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// Número da porta serial</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">mode</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_MODE_RTU</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// Modo de comunicação Modbus (RTU ou ASCII)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">baudrate</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">9600</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">           </span><span style="color: #616E88">// Taxa de transmissão em bits por segundo</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">parity</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARITY_NONE</span><span style="color: #D8DEE9FF">    </span><span style="color: #616E88">// Tipo de paridade (nenhuma neste caso)</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Configura o mestre Modbus com os parâmetros de comunicação</span></span>
<span class="line"><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_master_setup</span><span style="color: #D8DEE9FF">((</span><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Configuração de Comunicação TCP/IP</h3>



<p class="wp-block-paragraph">Para comunicação via TCP/IP, além dos parâmetros gerais, é necessário configurar os endereços IP dos dispositivos escravos. Esses endereços são utilizados para identificar cada dispositivo na rede.</p>



<p class="wp-block-paragraph">Exemplo de configuração para uma rede TCP/IP:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="char* slave_ip_address_table[MB_SLAVE_COUNT] = {
    &quot;192.168.1.2&quot;, // Endereço IP do escravo 1
    &quot;192.168.1.3&quot;, // Endereço IP do escravo 2
    NULL           // Término da tabela
};

mb_communication_info_t comm_info = {
    .ip_port = MB_TCP_PORT,                    // Porta Modbus TCP (padrão 502)
    .ip_addr_type = MB_IPV4,                   // Tipo de endereço IP (IPv4)
    .ip_mode = MB_MODE_TCP,                    // Modo de comunicação TCP
    .ip_addr = (void*)slave_ip_address_table,  // Tabela de endereços IP dos escravos
    .ip_netif_ptr = esp_netif_ptr              // Ponteiro para a interface de rede
};

// Configura o mestre Modbus com os parâmetros de comunicação
ESP_ERROR_CHECK(mbc_master_setup((void*)&amp;comm_info));
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">char</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">slave_ip_address_table</span><span style="color: #D8DEE9FF">[</span><span style="color: #D8DEE9">MB_SLAVE_COUNT</span><span style="color: #D8DEE9FF">] </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: #ECEFF4">&quot;</span><span style="color: #A3BE8C">192.168.1.2</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Endereço IP do escravo 1</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">192.168.1.3</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Endereço IP do escravo 2</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">NULL</span><span style="color: #D8DEE9FF">           </span><span style="color: #616E88">// Término da tabela</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">mb_communication_info_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF"> </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">ip_port</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_TCP_PORT</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">                    </span><span style="color: #616E88">// Porta Modbus TCP (padrão 502)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">ip_addr_type</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_IPV4</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">                   </span><span style="color: #616E88">// Tipo de endereço IP (IPv4)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">ip_mode</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_MODE_TCP</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">                    </span><span style="color: #616E88">// Modo de comunicação TCP</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">ip_addr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">slave_ip_address_table</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">// Tabela de endereços IP dos escravos</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">ip_netif_ptr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">esp_netif_ptr</span><span style="color: #D8DEE9FF">              </span><span style="color: #616E88">// Ponteiro para a interface de rede</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Configura o mestre Modbus com os parâmetros de comunicação</span></span>
<span class="line"><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_master_setup</span><span style="color: #D8DEE9FF">((</span><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Considerações Importantes</h3>



<ol class="wp-block-list">
<li>Para comunicação <strong>RS-485</strong>, é necessário configurar o modo UART e os pinos apropriados usando as APIs UART do ESP-IDF.</li>



<li>No caso de redes TCP/IP, a descoberta automática de dispositivos pode ser configurada utilizando o serviço mDNS.</li>
</ol>



<p class="wp-block-paragraph">Com as opções de comunicação configuradas, o mestre está pronto para iniciar a troca de dados com os escravos.</p>



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



<h2 class="wp-block-heading">Comunicação do Mestre</h2>



<p class="wp-block-paragraph">Após configurar o mestre Modbus e suas opções de comunicação, o próximo passo é iniciar a comunicação com os dispositivos escravos. O ESP-Modbus oferece APIs para iniciar, enviar requisições e processar as respostas recebidas.</p>



<h3 class="wp-block-heading">Inicialização da Comunicação</h3>



<p class="wp-block-paragraph">A comunicação do mestre Modbus é iniciada com a chamada da função <code>mbc_master_start()</code>, que ativa a pilha Modbus e permite a troca de dados.</p>



<p class="wp-block-paragraph">Exemplo de inicialização:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="esp_err_t err = mbc_master_start();
if (err != ESP_OK) {
    ESP_LOGE(TAG, &quot;Falha ao iniciar o controlador Modbus, erro = %x.&quot;, err);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_master_start</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">if</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">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Falha ao iniciar o controlador Modbus, erro = %x.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</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>



<h3 class="wp-block-heading">Envio de Requisições</h3>



<p class="wp-block-paragraph">O mestre envia requisições aos escravos utilizando a função <code>mbc_master_send_request()</code>. Essa função é bloqueante, ou seja, ela aguarda uma resposta do escravo antes de continuar.</p>



<p class="wp-block-paragraph">Exemplo básico de envio de requisição:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="mb_param_request_t request = {
    .slave_addr = 1,          // Endereço do dispositivo escravo
    .command = MB_FUNC_READ,  // Comando Modbus (ex.: leitura de registros)
    .reg_start = 0,           // Endereço inicial do registro
    .reg_size = 2             // Número de registros a serem lidos
};

uint8_t response_data[4]; // Buffer para armazenar a resposta
esp_err_t err = mbc_master_send_request(&amp;request, response_data);
if (err == ESP_OK) {
    ESP_LOGI(TAG, &quot;Requisição bem-sucedida. Dados recebidos.&quot;);
} else {
    ESP_LOGE(TAG, &quot;Erro na requisição Modbus, código de erro: %x.&quot;, err);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">mb_param_request_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">request</span><span style="color: #D8DEE9FF"> </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">slave_addr</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: #ECEFF4">,</span><span style="color: #D8DEE9FF">          </span><span style="color: #616E88">// Endereço do dispositivo escravo</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">command</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_FUNC_READ</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">// Comando Modbus (ex.: leitura de registros)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">reg_start</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 style="color: #D8DEE9FF">           </span><span style="color: #616E88">// Endereço inicial do registro</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">reg_size</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: #D8DEE9FF">             </span><span style="color: #616E88">// Número de registros a serem lidos</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">response_data</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">4</span><span style="color: #D8DEE9FF">]</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Buffer para armazenar a resposta</span></span>
<span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_master_send_request</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">request</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">response_data</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">if</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">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Requisição bem-sucedida. Dados recebidos.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro na requisição Modbus, código de erro: %x.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</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>



<h3 class="wp-block-heading">Leitura de Dados</h3>



<p class="wp-block-paragraph">O mestre pode acessar os valores de parâmetros definidos no Dicionário de Dados utilizando <code>mbc_master_get_parameter()</code>. Essa função permite recuperar os dados mapeados por um CID específico.</p>



<p class="wp-block-paragraph">Exemplo de leitura de parâmetro:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="const mb_parameter_descriptor_t* param_descriptor = NULL;
uint8_t data_buffer[4]; // Buffer para armazenar os dados
uint8_t data_type;

esp_err_t err = mbc_master_get_cid_info(CID_TEMP_DATA_1, &amp;param_descriptor);
if (err == ESP_OK) {
    err = mbc_master_get_parameter(param_descriptor-&gt;cid, (char*)param_descriptor-&gt;param_key, data_buffer, &amp;data_type);
    if (err == ESP_OK) {
        ESP_LOGI(TAG, &quot;Parâmetro: %s, Valor: 0x%08x&quot;, param_descriptor-&gt;param_key, *(uint32_t*)data_buffer);
    } else {
        ESP_LOGE(TAG, &quot;Erro ao ler o parâmetro, código de erro: %x.&quot;, err);
    }
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mb_parameter_descriptor_t</span><span style="color: #D8DEE9FF">* param_descriptor </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">data_buffer</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">4</span><span style="color: #D8DEE9FF">]</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Buffer para armazenar os dados</span></span>
<span class="line"><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">data_type</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_master_get_cid_info</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">CID_TEMP_DATA_1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> ¶</span><span style="color: #D8DEE9">m_descriptor</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">if</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">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><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: #88C0D0">mbc_master_get_parameter</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">param_descriptor</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">cid</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">char</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">param_descriptor</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">param_key</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">data_buffer</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">data_type</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: #D8DEE9">err</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Parâmetro: %s, Valor: 0x%08x</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">param_descriptor</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">param_key</span><span style="color: #ECEFF4">,</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: #81A1C1">*</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">data_buffer</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 style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro ao ler o parâmetro, código de erro: %x.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</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">Escrita de Dados</h3>



<p class="wp-block-paragraph">O mestre também pode alterar valores nos registros de um escravo utilizando <code>mbc_master_set_parameter()</code>.</p>



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



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="uint8_t new_value[4] = {0x12, 0x34, 0x56, 0x78};
esp_err_t err = mbc_master_set_parameter(CID_TEMP_DATA_1, &quot;Temperature_1&quot;, new_value, NULL);
if (err == ESP_OK) {
    ESP_LOGI(TAG, &quot;Parâmetro atualizado com sucesso.&quot;);
} else {
    ESP_LOGE(TAG, &quot;Erro ao atualizar parâmetro, código de erro: %x.&quot;, err);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">new_value</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">4</span><span style="color: #D8DEE9FF">] </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #B48EAD">0x12</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x34</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x56</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x78</span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_master_set_parameter</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">CID_TEMP_DATA_1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Temperature_1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">new_value</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">if</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">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Parâmetro atualizado com sucesso.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro ao atualizar parâmetro, código de erro: %x.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</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>



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



<h2 class="wp-block-heading">Encerramento do Mestre Modbus</h2>



<p class="wp-block-paragraph">Ao finalizar a utilização do mestre Modbus, é essencial encerrar corretamente a pilha de comunicação para liberar os recursos do sistema. O ESP-Modbus oferece APIs específicas para garantir que todo o contexto do controlador seja destruído de forma segura.</p>



<h3 class="wp-block-heading">Parada da Pilha Modbus</h3>



<p class="wp-block-paragraph">A função <code>mbc_master_stop()</code> deve ser chamada para interromper a pilha de comunicação. Isso encerra todas as operações ativas e desativa o controlador.</p>



<p class="wp-block-paragraph">Exemplo de parada da pilha:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="esp_err_t err = mbc_master_stop();
if (err == ESP_OK) {
    ESP_LOGI(TAG, &quot;Pilha Modbus parada com sucesso.&quot;);
} else {
    ESP_LOGE(TAG, &quot;Erro ao parar a pilha Modbus, código de erro: %x.&quot;, err);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_master_stop</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">if</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">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Pilha Modbus parada com sucesso.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro ao parar a pilha Modbus, código de erro: %x.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</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>



<h3 class="wp-block-heading">Destruição do Controlador</h3>



<p class="wp-block-paragraph">Após a parada da pilha, o controlador Modbus deve ser destruído utilizando a função <code>mbc_master_destroy()</code>. Isso libera a memória e outros recursos alocados durante a inicialização.</p>



<p class="wp-block-paragraph">Exemplo de destruição do controlador:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="esp_err_t err = mbc_master_destroy();
if (err == ESP_OK) {
    ESP_LOGI(TAG, &quot;Controlador Modbus destruído com sucesso.&quot;);
} else {
    ESP_LOGE(TAG, &quot;Erro ao destruir o controlador Modbus, código de erro: %x.&quot;, err);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_master_destroy</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">if</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">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Controlador Modbus destruído com sucesso.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro ao destruir o controlador Modbus, código de erro: %x.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</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>



<h3 class="wp-block-heading">Boas Práticas</h3>



<ul class="wp-block-list">
<li><strong>Verificação de Erros:</strong> Sempre verifique os códigos de retorno das funções para identificar possíveis falhas e tratar erros de forma adequada.</li>



<li><strong>Liberação de Recursos:</strong> Certifique-se de que a função <code>mbc_master_destroy()</code> seja chamada antes de finalizar a aplicação para evitar vazamentos de memória.</li>



<li><strong>Sincronização:</strong> Garanta que todas as operações Modbus tenham sido concluídas antes de encerrar a pilha.</li>
</ul>



<p class="wp-block-paragraph">Com esses passos, o ciclo de vida do controlador mestre Modbus é finalizado de forma segura e eficiente.</p>



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



<h2 class="wp-block-heading">API Modbus Escravo &#8211; Visão Geral</h2>



<p class="wp-block-paragraph">A API Modbus para dispositivos escravos no ESP32 permite configurar e gerenciar a comunicação com mestres Modbus. Assim como a API para mestres, a API para escravos segue uma sequência lógica de configuração e operação.</p>



<h3 class="wp-block-heading">Etapas Principais da Comunicação Escravo</h3>



<ol class="wp-block-list">
<li><strong>Inicialização da Porta Modbus:</strong>
<ul class="wp-block-list">
<li>Configura a interface de comunicação (serial ou TCP/IP) e o controlador escravo.</li>
</ul>
</li>



<li><strong>Configuração de Acesso a Dados:</strong>
<ul class="wp-block-list">
<li>Define os registros que estarão disponíveis para acesso pelo mestre, como holding registers ou input registers.</li>
</ul>
</li>



<li><strong>Opções de Comunicação:</strong>
<ul class="wp-block-list">
<li>Configura parâmetros específicos, como taxa de transmissão e endereços de comunicação.</li>
</ul>
</li>



<li><strong>Início da Comunicação:</strong>
<ul class="wp-block-list">
<li>Ativa a pilha Modbus, permitindo a troca de dados entre o escravo e o mestre.</li>
</ul>
</li>



<li><strong>Finalização:</strong>
<ul class="wp-block-list">
<li>Libera os recursos do controlador ao finalizar a comunicação.</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading">Estrutura de Dados no Escravo</h3>



<p class="wp-block-paragraph">Assim como no mestre, o escravo utiliza estruturas de dados para organizar os registros Modbus acessíveis pelo mestre. A configuração de cada área de registro inclui:</p>



<ul class="wp-block-list">
<li><strong>Tipo de Registro:</strong> Define se é um holding register, input register, coil, ou discrete input.</li>



<li><strong>Endereço Inicial:</strong> Especifica a posição inicial do registro na memória do dispositivo.</li>



<li><strong>Tamanho:</strong> Determina o número de registros disponíveis para acesso.</li>
</ul>



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



<h2 class="wp-block-heading">Configuração de Acesso a Dados no Escravo</h2>



<p class="wp-block-paragraph">A configuração de acesso a dados no escravo Modbus é uma etapa essencial para disponibilizar registros aos mestres. No ESP-Modbus, isso é feito definindo áreas de memória específicas que armazenarão os dados acessíveis. Essas áreas são mapeadas para tipos de registros Modbus, como <strong>Holding Registers</strong> e <strong>Input Registers</strong>.</p>



<h3 class="wp-block-heading">Definindo Áreas de Registro</h3>



<p class="wp-block-paragraph">Cada tipo de registro Modbus no escravo é configurado utilizando a estrutura <code>mb_register_area_descriptor_t</code>. Essa estrutura especifica:</p>



<ul class="wp-block-list">
<li><strong>Offset Inicial:</strong> A posição relativa do registro dentro do tipo configurado.</li>



<li><strong>Tipo de Registro:</strong> Indica se a área é de Holding Registers, Input Registers, Coils ou Discrete Inputs.</li>



<li><strong>Endereço de Memória:</strong> Um ponteiro para a área de memória onde os dados serão armazenados.</li>



<li><strong>Tamanho da Área:</strong> Define o número de registros disponíveis para leitura/escrita.</li>
</ul>



<p class="wp-block-paragraph">Exemplo de configuração de áreas de registro:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#define MB_REG_INPUT_START_AREA0    (0)
#define MB_REG_HOLDING_START_AREA0  (0)
#define MB_REG_HOLD_CNT             (100) // Número de registros de holding
#define MB_REG_INPUT_CNT            (100) // Número de registros de input

mb_register_area_descriptor_t reg_area; // Estrutura de descrição da área de registros

// Área de registros de holding
uint16_t holding_reg_area[MB_REG_HOLD_CNT] = {0};
reg_area.type = MB_PARAM_HOLDING;
reg_area.start_offset = MB_REG_HOLDING_START_AREA0;
reg_area.address = (void*)&amp;holding_reg_area[0];
reg_area.size = sizeof(holding_reg_area);
ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));

// Área de registros de input
uint16_t input_reg_area[MB_REG_INPUT_CNT] = {0};
reg_area.type = MB_PARAM_INPUT;
reg_area.start_offset = MB_REG_INPUT_START_AREA0;
reg_area.address = (void*)&amp;input_reg_area[0];
reg_area.size = sizeof(input_reg_area);
ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MB_REG_INPUT_START_AREA0</span><span style="color: #D8DEE9FF">    (</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MB_REG_HOLDING_START_AREA0</span><span style="color: #D8DEE9FF">  (</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MB_REG_HOLD_CNT</span><span style="color: #D8DEE9FF">             (</span><span style="color: #B48EAD">100</span><span style="color: #D8DEE9FF">) </span><span style="color: #616E88">// Número de registros de holding</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MB_REG_INPUT_CNT</span><span style="color: #D8DEE9FF">            (</span><span style="color: #B48EAD">100</span><span style="color: #D8DEE9FF">) </span><span style="color: #616E88">// Número de registros de input</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">mb_register_area_descriptor_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">reg_area</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Estrutura de descrição da área de registros</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Área de registros de holding</span></span>
<span class="line"><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">holding_reg_area</span><span style="color: #D8DEE9FF">[</span><span style="color: #D8DEE9">MB_REG_HOLD_CNT</span><span style="color: #D8DEE9FF">] </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: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">reg_area</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">type</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_HOLDING</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">reg_area</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">start_offset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_REG_HOLDING_START_AREA0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">reg_area</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">address</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">holding_reg_area</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">]</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">reg_area</span><span style="color: #ECEFF4">.</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: #88C0D0">sizeof</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">holding_reg_area</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_slave_set_descriptor</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">reg_area</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Área de registros de input</span></span>
<span class="line"><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">input_reg_area</span><span style="color: #D8DEE9FF">[</span><span style="color: #D8DEE9">MB_REG_INPUT_CNT</span><span style="color: #D8DEE9FF">] </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: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">reg_area</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">type</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_INPUT</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">reg_area</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">start_offset</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_REG_INPUT_START_AREA0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">reg_area</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">address</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">input_reg_area</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">]</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">reg_area</span><span style="color: #ECEFF4">.</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: #88C0D0">sizeof</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">input_reg_area</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_slave_set_descriptor</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">reg_area</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Proteção e Acesso aos Registros</h3>



<p class="wp-block-paragraph">Para evitar inconsistências durante a escrita/leitura dos registros, é importante proteger as áreas de memória com seções críticas. Exemplo:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="portENTER_CRITICAL(&amp;param_lock);
holding_reg_area[2] += 10; // Atualizando um registro
portEXIT_CRITICAL(&amp;param_lock);
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">portENTER_CRITICAL</span><span style="color: #D8DEE9FF">(¶</span><span style="color: #D8DEE9">m_lock</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">holding_reg_area</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">] </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Atualizando um registro</span></span>
<span class="line"><span style="color: #88C0D0">portEXIT_CRITICAL</span><span style="color: #D8DEE9FF">(¶</span><span style="color: #D8DEE9">m_lock</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Requisitos para a Configuração</h3>



<ul class="wp-block-list">
<li>Pelo menos uma área de cada tipo de registro necessário deve ser configurada.</li>



<li>Caso um mestre tente acessar uma área não configurada, será gerada uma exceção Modbus.</li>
</ul>



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



<h2 class="wp-block-heading">Opções de Comunicação do Escravo</h2>



<p class="wp-block-paragraph">Após configurar as áreas de registro, é necessário definir as opções de comunicação para o escravo Modbus. Esses parâmetros garantem que o dispositivo esteja corretamente configurado para se comunicar com o mestre, seja em modo serial (RTU/ASCII) ou TCP/IP.</p>



<h3 class="wp-block-heading">Configuração de Comunicação Serial</h3>



<p class="wp-block-paragraph">Na comunicação serial, os parâmetros principais são:</p>



<ul class="wp-block-list">
<li><strong>Porta UART:</strong> Define qual porta física será utilizada.</li>



<li><strong>Modo de Comunicação:</strong> Indica se será RTU ou ASCII.</li>



<li><strong>Endereço do Escravo:</strong> Identifica unicamente o dispositivo na rede.</li>



<li><strong>Taxa de Baud:</strong> Determina a velocidade de transmissão.</li>



<li><strong>Paridade:</strong> Configura o tipo de paridade (nenhuma, ímpar ou par).</li>
</ul>



<p class="wp-block-paragraph">Exemplo de configuração serial:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#define MB_SLAVE_DEV_SPEED 9600
#define MB_SLAVE_ADDR 1
#define MB_SLAVE_PORT_NUM 2

mb_communication_info_t comm_info = {
    .mode = MB_MODE_RTU,                    // Modo RTU
    .slave_addr = MB_SLAVE_ADDR,            // Endereço do escravo
    .port = MB_SLAVE_PORT_NUM,              // Porta UART
    .baudrate = MB_SLAVE_DEV_SPEED,         // Taxa de baud
    .parity = MB_PARITY_NONE                // Sem paridade
};

// Configura o escravo Modbus com os parâmetros definidos
ESP_ERROR_CHECK(mbc_slave_setup((void*)&amp;comm_info));
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_SLAVE_DEV_SPEED</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">9600</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">MB_SLAVE_ADDR</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">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">MB_SLAVE_PORT_NUM</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">mb_communication_info_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF"> </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">mode</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_MODE_RTU</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">                    </span><span style="color: #616E88">// Modo RTU</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">slave_addr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_SLAVE_ADDR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">            </span><span style="color: #616E88">// Endereço do escravo</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">port</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_SLAVE_PORT_NUM</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">              </span><span style="color: #616E88">// Porta UART</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">baudrate</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_SLAVE_DEV_SPEED</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">         </span><span style="color: #616E88">// Taxa de baud</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">parity</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARITY_NONE</span><span style="color: #D8DEE9FF">                </span><span style="color: #616E88">// Sem paridade</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Configura o escravo Modbus com os parâmetros definidos</span></span>
<span class="line"><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_slave_setup</span><span style="color: #D8DEE9FF">((</span><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Configuração de Comunicação TCP/IP</h3>



<p class="wp-block-paragraph">Na comunicação via TCP/IP, o escravo precisa estar associado a uma interface de rede válida e configurado para escutar em uma porta específica. A porta padrão para Modbus TCP é a <strong>502</strong>.</p>



<p class="wp-block-paragraph">Exemplo de configuração TCP/IP:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="mb_communication_info_t comm_info = {
    .ip_port = MB_TCP_PORT,                    // Porta Modbus TCP (padrão 502)
    .ip_addr_type = MB_IPV4,                   // IPv4
    .ip_mode = MB_MODE_TCP,                    // Modo TCP
    .ip_addr = NULL,                           // Aceita conexões de qualquer cliente
    .ip_netif_ptr = esp_netif_ptr              // Ponteiro para a interface de rede
};

// Configura o escravo Modbus para comunicação TCP/IP
ESP_ERROR_CHECK(mbc_slave_setup((void*)&amp;comm_info));
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">mb_communication_info_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF"> </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">ip_port</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_TCP_PORT</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">                    </span><span style="color: #616E88">// Porta Modbus TCP (padrão 502)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">ip_addr_type</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_IPV4</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">                   </span><span style="color: #616E88">// IPv4</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">ip_mode</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_MODE_TCP</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">                    </span><span style="color: #616E88">// Modo TCP</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">ip_addr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">                           </span><span style="color: #616E88">// Aceita conexões de qualquer cliente</span></span>
<span class="line"><span style="color: #D8DEE9FF">    .</span><span style="color: #D8DEE9">ip_netif_ptr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">esp_netif_ptr</span><span style="color: #D8DEE9FF">              </span><span style="color: #616E88">// Ponteiro para a interface de rede</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Configura o escravo Modbus para comunicação TCP/IP</span></span>
<span class="line"><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_slave_setup</span><span style="color: #D8DEE9FF">((</span><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Considerações para Comunicação Estável</h3>



<ol class="wp-block-list">
<li><strong>RS-485:</strong> Caso a interface serial utilize RS-485, configure os pinos UART e o modo half-duplex utilizando as APIs UART do ESP-IDF.</li>



<li><strong>Descoberta Automática:</strong> Para TCP/IP, é possível usar o serviço mDNS para facilitar a descoberta de dispositivos na rede.</li>



<li><strong>Respostas em Tempo Real:</strong> Certifique-se de que os registros necessários estejam configurados para evitar erros de timeout no mestre.</li>
</ol>



<p class="wp-block-paragraph">Com os parâmetros de comunicação configurados, o escravo está pronto para se comunicar com o mestre.</p>



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



<h2 class="wp-block-heading">Comunicação do Escravo</h2>



<p class="wp-block-paragraph">Com as áreas de registro e as opções de comunicação configuradas, o escravo Modbus está pronto para iniciar a troca de dados com o mestre. O ESP-Modbus oferece APIs para gerenciar eventos e processar acessos aos registros configurados.</p>



<h3 class="wp-block-heading">Início da Comunicação</h3>



<p class="wp-block-paragraph">A comunicação do escravo é iniciada com a função <code>mbc_slave_start()</code>. Isso ativa a pilha Modbus, permitindo que o dispositivo receba e responda às requisições do mestre.</p>



<p class="wp-block-paragraph">Exemplo de inicialização:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="esp_err_t err = mbc_slave_start();
if (err == ESP_OK) {
    ESP_LOGI(TAG, &quot;Escravo Modbus iniciado com sucesso.&quot;);
} else {
    ESP_LOGE(TAG, &quot;Erro ao iniciar o escravo Modbus, código: %x.&quot;, err);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_slave_start</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">if</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">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Escravo Modbus iniciado com sucesso.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro ao iniciar o escravo Modbus, código: %x.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</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>



<h3 class="wp-block-heading">Monitoramento de Eventos</h3>



<p class="wp-block-paragraph">O escravo pode monitorar eventos relacionados ao acesso aos registros utilizando a função <code>mbc_slave_check_event()</code>. Essa função é bloqueante e retorna o tipo de evento ocorrido, como leitura ou escrita em um registro.</p>



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



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#define MB_READ_MASK (MB_EVENT_INPUT_REG_RD | MB_EVENT_HOLDING_REG_RD)
#define MB_WRITE_MASK (MB_EVENT_HOLDING_REG_WR)
#define MB_READ_WRITE_MASK (MB_READ_MASK | MB_WRITE_MASK)

mb_event_group_t event = mbc_slave_check_event(MB_READ_WRITE_MASK);

if (event &amp; MB_EVENT_HOLDING_REG_WR) {
    ESP_LOGI(TAG, &quot;Escrita em Holding Register detectada.&quot;);
} else if (event &amp; MB_EVENT_INPUT_REG_RD) {
    ESP_LOGI(TAG, &quot;Leitura em Input Register detectada.&quot;);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MB_READ_MASK</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">MB_EVENT_INPUT_REG_RD</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_EVENT_HOLDING_REG_RD</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MB_WRITE_MASK</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">MB_EVENT_HOLDING_REG_WR</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MB_READ_WRITE_MASK</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">MB_READ_MASK</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_WRITE_MASK</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">mb_event_group_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">event</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mbc_slave_check_event</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MB_READ_WRITE_MASK</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">event</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_EVENT_HOLDING_REG_WR</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Escrita em Holding Register detectada.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><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">event</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_EVENT_INPUT_REG_RD</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Leitura em Input Register detectada.</span><span style="color: #ECEFF4">&quot;</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>



<h3 class="wp-block-heading">Acesso a Parâmetros</h3>



<p class="wp-block-paragraph">A função <code>mbc_slave_get_param_info()</code> permite obter detalhes sobre o registro acessado pelo mestre, como tipo de registro, endereço e tamanho.</p>



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



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="mb_param_info_t reg_info;
esp_err_t err = mbc_slave_get_param_info(&amp;reg_info, MB_PAR_INFO_GET_TOUT);
if (err == ESP_OK) {
    ESP_LOGI(TAG, &quot;Registro acessado: Tipo=%u, Endereço=%u, Tamanho=%u&quot;,
             reg_info.type, reg_info.mb_offset, reg_info.size);
} else {
    ESP_LOGE(TAG, &quot;Erro ao obter informações do parâmetro, código: %x.&quot;, err);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">mb_param_info_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">reg_info</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_slave_get_param_info</span><span style="color: #D8DEE9FF">(®</span><span style="color: #D8DEE9">_info</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PAR_INFO_GET_TOUT</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">if</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">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Registro acessado: Tipo=%u, Endereço=%u, Tamanho=%u</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">reg_info</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">type</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">reg_info</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">mb_offset</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">reg_info</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">size</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro ao obter informações do parâmetro, código: %x.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</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>



<h3 class="wp-block-heading">Respostas em Tempo Real</h3>



<p class="wp-block-paragraph">O escravo responde automaticamente às requisições do mestre com base nos registros configurados. Certifique-se de que as áreas de registro estejam atualizadas com os valores corretos para evitar comportamentos inesperados.</p>



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



<h2 class="wp-block-heading">Encerramento do Escravo Modbus</h2>



<p class="wp-block-paragraph">Ao finalizar a operação do escravo Modbus, é fundamental encerrar corretamente a pilha de comunicação e liberar os recursos alocados. Isso garante a estabilidade do sistema e evita vazamentos de memória.</p>



<h3 class="wp-block-heading">Parada da Pilha Modbus</h3>



<p class="wp-block-paragraph">A função <code>mbc_slave_stop()</code> é usada para interromper a pilha Modbus. Essa chamada encerra todas as operações ativas do escravo.</p>



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



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="esp_err_t err = mbc_slave_stop();
if (err == ESP_OK) {
    ESP_LOGI(TAG, &quot;Pilha Modbus do escravo parada com sucesso.&quot;);
} else {
    ESP_LOGE(TAG, &quot;Erro ao parar a pilha Modbus, código: %x.&quot;, err);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_slave_stop</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">if</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">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Pilha Modbus do escravo parada com sucesso.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro ao parar a pilha Modbus, código: %x.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</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>



<h3 class="wp-block-heading">Destruição do Controlador</h3>



<p class="wp-block-paragraph">Após parar a pilha, a função <code>mbc_slave_destroy()</code> deve ser chamada para destruir o controlador Modbus e liberar todos os recursos alocados durante a inicialização.</p>



<p class="wp-block-paragraph">Exemplo de destruição:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="esp_err_t err = mbc_slave_destroy();
if (err == ESP_OK) {
    ESP_LOGI(TAG, &quot;Controlador do escravo Modbus destruído com sucesso.&quot;);
} else {
    ESP_LOGE(TAG, &quot;Erro ao destruir o controlador Modbus, código: %x.&quot;, err);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">esp_err_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: #88C0D0">mbc_slave_destroy</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">if</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">ESP_OK</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Controlador do escravo Modbus destruído com sucesso.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro ao destruir o controlador Modbus, código: %x.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</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>



<h3 class="wp-block-heading">Boas Práticas</h3>



<ol class="wp-block-list">
<li><strong>Verificação de Operações Ativas:</strong> Antes de encerrar a pilha, certifique-se de que todas as operações de leitura/escrita tenham sido concluídas.</li>



<li><strong>Liberação de Recursos:</strong> Sempre chame <code>mbc_slave_destroy()</code> para evitar vazamentos de memória ou instabilidades.</li>



<li><strong>Sincronização de Tarefas:</strong> Caso múltiplas tarefas acessem os registros Modbus, garanta que todas tenham finalizado antes de destruir o controlador.</li>
</ol>



<p class="wp-block-paragraph">Com esses passos, o ciclo de vida do escravo Modbus é encerrado de forma segura e eficiente.</p>



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



<h2 class="wp-block-heading">Possíveis Problemas de Comunicação e Soluções</h2>



<p class="wp-block-paragraph">Durante a implementação do protocolo Modbus, podem ocorrer problemas de comunicação entre o mestre e os escravos. A identificação e a solução desses problemas são essenciais para garantir o funcionamento correto do sistema.</p>



<h3 class="wp-block-heading">Principais Erros e Soluções</h3>



<ol class="wp-block-list">
<li><strong>Requisição Inválida (ESP_ERR_NOT_SUPPORTED &#8211; Código: 0x106)</strong>
<ul class="wp-block-list">
<li><strong>Causa:</strong> O mestre enviou uma requisição para um registro ou comando não suportado pelo escravo.</li>



<li><strong>Solução:</strong> Verifique o mapa de registros do escravo e ajuste a requisição do mestre para corresponder às capacidades do dispositivo.</li>
</ul>
</li>



<li><strong>Timeout na Resposta do Escravo (ESP_ERR_TIMEOUT &#8211; Código: 0x107)</strong>
<ul class="wp-block-list">
<li><strong>Causa:</strong> O escravo não respondeu dentro do tempo esperado.</li>



<li><strong>Solução:</strong> Certifique-se de que:
<ul class="wp-block-list">
<li>O escravo está conectado corretamente.</li>



<li>A taxa de baud e os parâmetros de comunicação (como paridade) são compatíveis entre mestre e escravo.</li>



<li>O endereço do escravo na requisição está correto.</li>
</ul>
</li>
</ul>
</li>



<li><strong>Resposta Inválida (ESP_ERR_INVALID_RESPONSE &#8211; Código: 0x108)</strong>
<ul class="wp-block-list">
<li><strong>Causa:</strong> O mestre recebeu uma resposta corrompida ou com erro de validação (checksum inválido).</li>



<li><strong>Solução:</strong> Verifique a integridade do cabo de comunicação (no caso de RTU/ASCII) ou a estabilidade da conexão de rede (no caso de TCP/IP). Além disso, confirme que os parâmetros Modbus no escravo estão configurados corretamente.</li>
</ul>
</li>



<li><strong>Estado Inválido (ESP_ERR_INVALID_STATE &#8211; Código: 0x103)</strong>
<ul class="wp-block-list">
<li><strong>Causa:</strong> Erro crítico no controlador Modbus, como sequência de comandos incorreta ou controlador ocupado.</li>



<li><strong>Solução:</strong> Reinicie o controlador Modbus no mestre ou no escravo. Verifique se múltiplas tarefas estão acessando o controlador simultaneamente e sincronize-as.</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading">Dicas para Diagnóstico</h3>



<ul class="wp-block-list">
<li><strong>Logs Detalhados:</strong> Ative logs no ESP-IDF para capturar mensagens de erro detalhadas, como falhas de inicialização ou problemas durante a execução.</li>



<li><strong>Testes Isolados:</strong> Teste cada dispositivo escravo individualmente antes de integrar vários dispositivos na rede.</li>



<li><strong>Osciloscópio ou Analisador de Rede:</strong> Use ferramentas de diagnóstico para verificar os sinais na linha de comunicação serial ou monitorar pacotes TCP/IP.</li>
</ul>



<h3 class="wp-block-heading">Exemplos de Mensagens de Erro</h3>



<p class="wp-block-paragraph">Um exemplo de mensagem de erro capturada nos logs do mestre:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="E (1692332) MB_CONTROLLER_MASTER: mbc_master_get_parameter(111): SERIAL master get parameter failure error=(0x107) (ESP_ERR_TIMEOUT).
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">E</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1692332</span><span style="color: #D8DEE9FF">) MB_CONTROLLER_MASTER</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mbc_master_get_parameter</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">111</span><span style="color: #D8DEE9FF">): </span><span style="color: #D8DEE9">SERIAL</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">master</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">parameter</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">failure</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">error</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">0x107</span><span style="color: #D8DEE9FF">) (</span><span style="color: #D8DEE9">ESP_ERR_TIMEOUT</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">.</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Neste caso, o erro indica que o escravo não respondeu no tempo esperado. A solução seria revisar as conexões físicas e os parâmetros de comunicação.</p>



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



<h2 class="wp-block-heading">Exemplos de Aplicação</h2>



<p class="wp-block-paragraph">O ESP-Modbus fornece suporte completo para implementar soluções Modbus em dispositivos ESP32, permitindo a integração com uma ampla variedade de dispositivos industriais. Abaixo estão exemplos práticos de aplicações para mestre e escravo, baseados nas APIs discutidas.</p>



<h3 class="wp-block-heading">Exemplo 1: Mestre Modbus Serial para Monitoramento de Sensores</h3>



<p class="wp-block-paragraph">Um mestre Modbus pode ser utilizado para monitorar parâmetros de sensores conectados via RS-485. O exemplo abaixo ilustra como configurar o mestre para ler a temperatura e umidade de dois dispositivos escravos.</p>



<h4 class="wp-block-heading">Configuração do Mestre:</h4>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#include &quot;mbcontroller.h&quot;

// Configuração do dicionário de dados
mb_parameter_descriptor_t device_parameters[] = {
    { CID_TEMP, &quot;Temperature&quot;, &quot;C&quot;, MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0, 2, 0, PARAM_TYPE_FLOAT, 4 },
    { CID_HUMID, &quot;Humidity&quot;, &quot;%&quot;, MB_DEVICE_ADDR1, MB_PARAM_INPUT, 2, 1, 0, PARAM_TYPE_U16, 2 }
};

void app_main() {
    void* master_handler = NULL;
    ESP_ERROR_CHECK(mbc_master_init(MB_PORT_SERIAL_MASTER, &amp;master_handler));

    mb_communication_info_t comm_info = {
        .port = MB_PORT_NUM,
        .mode = MB_MODE_RTU,
        .baudrate = 9600,
        .parity = MB_PARITY_NONE
    };
    ESP_ERROR_CHECK(mbc_master_setup((void*)&amp;comm_info));

    ESP_ERROR_CHECK(mbc_master_set_descriptor(device_parameters, sizeof(device_parameters) / sizeof(device_parameters[0])));
    ESP_ERROR_CHECK(mbc_master_start());

    uint8_t temp_data[4];
    ESP_ERROR_CHECK(mbc_master_get_parameter(CID_TEMP, &quot;Temperature&quot;, temp_data, NULL));
    ESP_LOGI(TAG, &quot;Temperatura lida: %f&quot;, *(float*)temp_data);

    ESP_ERROR_CHECK(mbc_master_destroy());
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">mbcontroller.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Configuração do dicionário de dados</span></span>
<span class="line"><span style="color: #D8DEE9">mb_parameter_descriptor_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">device_parameters</span><span style="color: #D8DEE9FF">[] </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: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CID_TEMP</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Temperature</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">C</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_DEVICE_ADDR1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_HOLDING</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: #B48EAD">2</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">PARAM_TYPE_FLOAT</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4</span><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 style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CID_HUMID</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Humidity</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">%</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_DEVICE_ADDR1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_INPUT</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">PARAM_TYPE_U16</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</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">app_main</span><span style="color: #D8DEE9FF">() </span><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">master_handler</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_master_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MB_PORT_SERIAL_MASTER</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">master_handler</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">mb_communication_info_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF"> </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">port</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PORT_NUM</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        .</span><span style="color: #D8DEE9">mode</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_MODE_RTU</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        .</span><span style="color: #D8DEE9">baudrate</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">9600</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        .</span><span style="color: #D8DEE9">parity</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARITY_NONE</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_master_setup</span><span style="color: #D8DEE9FF">((</span><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_master_set_descriptor</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">device_parameters</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">device_parameters</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">device_parameters</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">])))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_master_start</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">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">temp_data</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">4</span><span style="color: #D8DEE9FF">]</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_master_get_parameter</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">CID_TEMP</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Temperature</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">temp_data</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_LOGI</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">TAG</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Temperatura lida: %f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</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: #81A1C1">*</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">temp_data</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_master_destroy</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>



<h3 class="wp-block-heading">Exemplo 2: Escravo Modbus TCP para Controle de Atuadores</h3>



<p class="wp-block-paragraph">Um escravo Modbus pode ser utilizado para controlar dispositivos como relés ou motores conectados via Ethernet. O exemplo abaixo configura o escravo para gerenciar dois relés.</p>



<h4 class="wp-block-heading">Configuração do Escravo:</h4>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="#include &quot;mbcontroller.h&quot;

#define RELAY_1_GPIO 25
#define RELAY_2_GPIO 26

void app_main() {
    uint16_t relay_registers[2] = {0}; // Registradores para os relés

    mb_register_area_descriptor_t reg_area = {
        .type = MB_PARAM_COIL,
        .start_offset = 0,
        .address = relay_registers,
        .size = sizeof(relay_registers)
    };
    ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));

    mb_communication_info_t comm_info = {
        .ip_port = MB_TCP_PORT,
        .ip_addr_type = MB_IPV4,
        .ip_mode = MB_MODE_TCP,
        .ip_addr = NULL,
        .ip_netif_ptr = esp_netif_ptr
    };
    ESP_ERROR_CHECK(mbc_slave_setup((void*)&amp;comm_info));
    ESP_ERROR_CHECK(mbc_slave_start());

    while (true) {
        if (relay_registers[0]) {
            gpio_set_level(RELAY_1_GPIO, 1);
        }
        if (relay_registers[1]) {
            gpio_set_level(RELAY_2_GPIO, 1);
        }
        vTaskDelay(pdMS_TO_TICKS(100));
    }

    ESP_ERROR_CHECK(mbc_slave_destroy());
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">mbcontroller.h</span><span style="color: #ECEFF4">&quot;</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">RELAY_1_GPIO</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">25</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">RELAY_2_GPIO</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">26</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">app_main</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">relay_registers</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">] </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: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Registradores para os relés</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">mb_register_area_descriptor_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">reg_area</span><span style="color: #D8DEE9FF"> </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">type</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_PARAM_COIL</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        .</span><span style="color: #D8DEE9">start_offset</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">address</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">relay_registers</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        .</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: #88C0D0">sizeof</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">relay_registers</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_slave_set_descriptor</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">reg_area</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">mb_communication_info_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF"> </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">ip_port</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_TCP_PORT</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        .</span><span style="color: #D8DEE9">ip_addr_type</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_IPV4</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        .</span><span style="color: #D8DEE9">ip_mode</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MB_MODE_TCP</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        .</span><span style="color: #D8DEE9">ip_addr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        .</span><span style="color: #D8DEE9">ip_netif_ptr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">esp_netif_ptr</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_slave_setup</span><span style="color: #D8DEE9FF">((</span><span style="color: #81A1C1">void*</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">comm_info</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_slave_start</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">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</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">relay_registers</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">gpio_set_level</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">RELAY_1_GPIO</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">;</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">relay_registers</span><span style="color: #D8DEE9FF">[</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">]) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">gpio_set_level</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">RELAY_2_GPIO</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">;</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">vTaskDelay</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">pdMS_TO_TICKS</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">100</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">ESP_ERROR_CHECK</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">mbc_slave_destroy</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>



<h3 class="wp-block-heading">Integração com Outras Tecnologias</h3>



<ul class="wp-block-list">
<li><strong>MQTT:</strong> Combine Modbus com MQTT para enviar dados lidos pelo mestre para um servidor em nuvem.</li>



<li><strong>Automação Industrial:</strong> Use o ESP-Modbus para integrar dispositivos como CLPs e inversores de frequência a um sistema de supervisão (SCADA).</li>
</ul>



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



<h2 class="wp-block-heading">Conclusão e Próximos Passos</h2>



<p class="wp-block-paragraph">O suporte ao Modbus no ESP32, através da biblioteca ESP-Modbus, oferece uma solução robusta e flexível para aplicações de automação e integração industrial. Seja na leitura de sensores via Modbus RTU ou no controle remoto de dispositivos com Modbus TCP/IP, o ESP-Modbus simplifica a implementação e gerenciamento dessas comunicações.</p>



<h3 class="wp-block-heading">Resumo dos Passos</h3>



<ol class="wp-block-list">
<li><strong>Configuração Inicial:</strong> Defina os parâmetros de comunicação e o mapeamento de dados.</li>



<li><strong>Troca de Dados:</strong> Utilize as APIs para enviar, receber e processar dados entre mestres e escravos.</li>



<li><strong>Diagnóstico e Resolução de Problemas:</strong> Monitore logs e corrija eventuais falhas de comunicação.</li>



<li><strong>Encerramento:</strong> Libere recursos corretamente ao finalizar a aplicação.</li>
</ol>



<h3 class="wp-block-heading">Próximos Passos</h3>



<ul class="wp-block-list">
<li><strong>Integração com Outras Protocolos:</strong> Experimente combinar o Modbus com protocolos como MQTT ou WebSocket para criar sistemas híbridos e conectados.</li>



<li><strong>Escalabilidade:</strong> Explore o uso de redes maiores com múltiplos dispositivos mestre e escravo.</li>



<li><strong>Customização:</strong> Adapte os exemplos fornecidos às suas necessidades específicas, otimizando o desempenho e a confiabilidade.</li>
</ul>



<h3 class="wp-block-heading">Recursos Adicionais</h3>



<p class="wp-block-paragraph">Para mais informações sobre o ESP-Modbus e o ESP-IDF, acesse:</p>



<ul class="wp-block-list">
<li><a href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/index.html">Documentação oficial do ESP-IDF</a></li>



<li><a href="https://modbus.org/specs.php">Especificações do protocolo Modbus</a></li>
</ul>



<p class="wp-block-paragraph">Com os exemplos e explicações fornecidos neste artigo, você terá uma base sólida para desenvolver aplicações Modbus em dispositivos ESP32.</p>



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



<p class="wp-block-paragraph"></p><p>The post <a href="https://mcu.tec.br/protoclos/introducao-ao-esp-modbus-com-esp-idf/">Introdução ao ESP-Modbus com ESP-IDF</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">31</post-id>	</item>
	</channel>
</rss>
