Multiplexador I2C – Controle até 64 Sensores com ESP32 - Blog Usinainfo
por	Matheus Gebert Straub	25/10/2021	1784	Visualizações
O Multiplexador T29548A é um módulo simples e muito utilizado por quem deseja resolver um dos problemas mais conhecidos de quem trabalha com dispositivos I2C, que o conflito de endereços em um mesmo projeto.
Controle até 64 Sensores através do ESP32
Para quem não consegue entender ao que exatamente estou me referindo, todo dispositivo de comunicação I2C possui um endereço próprio de funcionamento, o que permite que diversos equipamentos com endereços diferentes trabalhem através de apenas dois pinos.
O problema na utilização de dispositivos I2C é que a sua maioria, possui endereçamento fixo, ou seja, não é possível alterá-lo e assim não temos como utilizá-los simultaneamente em um projeto, mas o Multiplexador vem como uma solução para este problema.
Multiplexador I2C T29548A
O protocolo de comunicação I2C é amplamente conhecido pela sua característica especial de possibilitar a comunicação de diversos dispositivos através de um único barramento de dois pinos, mas todos devem ter endereços exclusivos.
Devido à condição citada anteriormente, se tentarmos utilizar dois ou mais displays, por exemplo, que possuam o mesmo endereço e não tenham como ser alterados, infelizmente não será possível tal utilização devido ao conflito de dados.
Como solução para este caso, temos o Multiplexador I2C, um dispositivo que permite a comunicação de até oito dispositivos I2C com o mesmo endereço e permite o mesmo sistema de troca de dados através de uma linguagem bidirecional.
Abaixo podemos observar o detalhamento dos pinos que compõem o Multiplexador I2C T29548A e conseguiremos entender um pouco mais o seu sistema de funcionamento, veja:
Pinout Multiplexador T29548A
Como podemos ver no esquema de pinos acima, é possível conectarmos as oito unidades de forma isolada, os pinos com inicial SD serão nossos pinos SDA e os pinos com inicial SC, os pinos SCL para conexão dos periféricos.
Através dos pinos de alimentação conseguimos alimentar nosso módulo com tensões que vão de 1,65V a 5,5V, fator muito importante, uma vez que possibilita a sua utilização tanto com Arduino, quanto com ESP32 e ESP8266.
Endereçamento I2C do Multiplexador
Como sabemos, o Multiplexador se comunica com o microcontrolador através de um sistema de comunicação I2C e para isto, precisa de um endereço para se comunicar. Diferente da maioria dos dispositivos I2C, o multiplexador possibilita a configuração do endereço, permitindo até oito endereços diferentes.
Posso usar oito endereços do Multiplexador I2C simultaneamente?
Sim, esta é uma característica que é realmente impressionante neste componente, por ter a possibilidade de oito configurações de endereço e também tornar possível a conexão de até oito periféricos, em um único microcontrolador, conseguimos conectar um total de 64 dispositivos I2C utilizando apenas dois pinos.
Com um endereço configurável, podemos selecionar um valor de 0x70 a 0x77 através do ajuste de nível lógico dos pinos A0, A1 e A2, conforme mostrado na tabela abaixo:
Tabela de Endereçamento I2C do Multiplexador
Lembrando que os níveis lógicos citados estão relacionados diretamente aos pinos de alimentação, por exemplo, o nível lógico LOW é obtido conectando o pino junto ao GND e o nível lógico HIGH é obtido conectando o pino junto ao VCC da alimentação.
Exemplo: Se você conectar os pinos A0, A1 e A2 do Multiplexador no GND, você obterá um endereço de 0x70, porém se ligar estes mesmos pinos no VCC, você terá um endereço de 0x77.
Produtos Utilizados no Teste do Multiplexador I2C
Para o projeto, iremos ler vários sensores BMP280 de mesmo endereço através de um Multiplexador I2C, neste exemplo será apenas quatro sensores, porém é possível conectar até oito.
Segue lista dos itens que iremos utilizar em nosso projeto:
1 NodeMCU ESP32S Iot com WiFi e Bluetooth – 38 Pinos
1 Multiplexador T29548A I2C 1 a 8 Canais
4 Sensor de Pressão e Temperatura BMP280
1 Protoboard 830 pontos para montagem de projetos
Jumper Premium para Protoboard Macho-Macho 20 cm
Scanner I2C com BMP 280 e ESP32
Quando trabalhamos com equipamentos de comunicação I2C, sabemos que uma informação crucial para o seu desenvolvimento é o seu endereço, salvo quando não conseguimos configurar o mesmo através de combinações como vimos acima.
O BMP280 é um destes casos nos quais precisamos descobrir o endereço e para isto fizemos uso de um scanner junto ao próprio microcontrolador base, veja o esquema de ligação utilizado e logo abaixo o código:
Esquema de Ligação Scanner I2C com ESP32
Como podemos ver, o esquema de ligação não possui segredos, basta que alimentemos o Módulo e o conectamos aos seus respectivos pinos de comunicação I2C do ESP32.
O código utilizado neste exemplo é o mesmo utilizado para os demais microcontroladores, uma vez que mesmo que possuam diferentes pinos de conexão, a linguagem de comunicação é universal entre estes, veja o código completo:
// Scanner I2C para BMP280 e ESP32 #include <Wire.h> void setup() { Wire.begin(); Serial.begin(115200); Serial.println("Scanner I2C"); } void loop() { byte erro, endereco; int dispositivos; Serial.println("Procurando Dispositivo I2C ..."); dispositivos = 0; for (endereco = 1; endereco < 127; endereco++ ) { Wire.beginTransmission(endereco); erro = Wire.endTransmission(); if (erro == 0) { Serial.print("Dispositivo I2C encontrado. Endereco 0x"); if (endereco < 16) Serial.print("0"); Serial.print(endereco, HEX); Serial.println(" !"); dispositivos++; } else if (erro == 4) { Serial.print("Erro desconhecido no Endereco 0x"); if (endereco < 16) Serial.print("0"); } } if (dispositivos == 0) Serial.println("Nenhum dispositivo I2C encontrado\n"); else Serial.println("Scanneamento Concluido\n"); while(Serial); }
// Scanner I2C para BMP280 e ESP32
Não vamos entrar nos critérios de compilação do código junto ao ESP32, porém para obter os valores junto ao monitor serial, após abri-lo, basta pressionar o botão EN do ESP32 para obter uma resposta semelhante a esta:
Exemplo de execução de leitura de endereço I2C
Outra diferença que vale ressaltar é o a velocidade de comunicação, quando utilizamos o Arduino, por exemplo, estamos habituados a trabalhar com um Baud Rate de 9600, porém com o ESP32 recomendo a utilização de 115200.
Esquema de Ligação do Multiplexador I2C com BMP280
O esquema de ligação do projeto é extremamente simples, porém para conseguirmos compreender um pouco melhor iremos dividi-lo em algumas partes devido aos detalhes que envolvem o mesmo.
Primeiramente, vamos realizar a ligação do Multiplexador I2C com ESP32 e configurar o endereço de comunicação através dos pinos A0, A1 e A2. Para facilitar, vamos utilizar o endereço 0x70 ligando todos os pinos em nível lógico baixo, veja:
Esquema de conexão do Multiplexador I2C com ESP32
Como podemos ver, o Multiplexador I2C está com seus pinos de configuração de endereço todos no barramento GND, ou seja, estão todos em LOW, o que significa que está configurado no endereço que mencionamos anteriormente.
Além disto, conseguimos observar o sistema de ligação I2C entre o Multiplexador e o ESP32, porém vale lembrar que além do ESP32 também é possível desenvolver este mesmo projeto com Arduino e ESP8266, para isto é necessário atentar-se apenas aos pinos utilizados, veja:
Tabela de Pinos I2C do ESP32, ESP8266 e Arduino Uno
Com as conexões acima mencionadas, nos basta apenas realizar a conexão dos sensores para leitura de dados antes de passarmos para a programação do nosso projeto, veja abaixo como ficará o projeto completo, totalmente montado:
Esquema de Ligação do Projeto com ESP32 e Sensor BMP280
Com o esquema de ligação totalmente completo e o endereço do sensor já anotado, chegou a hora de programarmos o nosso sistema para fazer a leitura dos nossos dispositivos I2C.
A alimentação do ESP32 é suficiente para o Multiplexador I2C?
A alimentação é suficiente para o esquema de ligação apresentado acima, porém quanto maior for a quantia de sensores atribuídos, maior será a corrente consumida e consequentemente, será necessário incluir ao projeto uma fonte de alimentação externa para suprir esta necessidade.
Caso a intenção seja utilizar os oito Multiplexadores com os oito sensores, é fundamental que se inclua uma fonte de 5V 1A, aproximadamente e uma dica, seria a utilização de uma Fonte Ajustável para Protoboard.
Código Fonte do Multiplexador com BMP280 e ESP32
O código de funcionamento é extremamente simples e de fácil compreensão, precisamos apenas considerar a seleção do barramento I2C correto antes de enviarmos os comandos para a leitura dos dados.
Para o presente projeto utilizaremos as seguintes bibliotecas:
Biblioteca Adafruit Sensor: DOWNLOAD AQUI.
Biblioteca Adafruit BMP280: DOWNLOAD AQUI.
Também é possível instalar as bibliotecas usando o Arduino Library Manager, para isto, siga os passos descritos a seguir em seu Arduino IDE:
Sketch à Incluir Biblioteca à Gerenciar Bibliotecas
Após, uma janela irá se abrir e pasta pesquisar pelas seguintes bibliotecas:
Após carregadas as bibliotecas, já podemos passar à compilação do código final do nosso projeto conforme segue abaixo:
// Projeto Leitura de Dados com Multiplexador I2C // Endereço BMP280: 0x76 // Inclui bibliotecas para o projeto #include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_BMP280.h> // Nomeia os sensores utilizados Adafruit_BMP280 sensor1; Adafruit_BMP280 sensor2; Adafruit_BMP280 sensor3; Adafruit_BMP280 sensor4; // Inicializa o Multiplexador com o endereço configurado void TCA9548A(uint8_t id) { Wire.beginTransmission(0x70); // A0= LOW; A1= LOW; A2= LOW Wire.write(1 << id); Wire.endTransmission(); } void setup() { Serial.begin(115200); Wire.begin(); // Verifica se o sensor 4 foi identificado TCA9548A(4); if (!sensor1.begin(0x76)) { Serial.println("Erro ao Identificar Sensor 4"); while (1); } Serial.println(); // Verifica se o sensor 5 foi identificado TCA9548A(5); if (!sensor2.begin(0x76)) { Serial.println("Erro ao Identificar Sensor 5"); while (1); } Serial.println(); // Verifica se o sensor 6 foi identificado TCA9548A(6); if (!sensor3.begin(0x76)) { Serial.println("Erro ao Identificar Sensor 6"); while (1); } Serial.println(); // Verifica se o sensor 7 foi identificado TCA9548A(7); if (!sensor4.begin(0x76)) { Serial.println("Erro ao Identificar Sensor 7"); while (1); } Serial.println(); } void loop() { // Imprime os dados do sensor SC4 SD4 TCA9548A (4); Serial.println("ID do Sensor: 4"); Serial.print("Temperatura: "); Serial.print(sensor1.readTemperature()); Serial.println(" ºC"); Serial.print("Pressão: "); Serial.print(sensor1.readPressure() / 100.0F); Serial.println(" hPa"); Serial.print("Altitude: ~"); // Valor aproximado Serial.print(sensor1.readAltitude(1013.25)); Serial.println(" m"); Serial.println(); // Imprime os dados do sensor SC5 SD5 TCA9548A (5); Serial.println("ID do Sensor: 5"); Serial.print("Temperatura: "); Serial.print(sensor2.readTemperature()); Serial.println(" ºC"); Serial.print("Pressão: "); Serial.print(sensor2.readPressure() / 100.0F); Serial.println(" hPa"); Serial.print("Altitude: ~"); // Valor aproximado Serial.print(sensor2.readAltitude(1013.25)); Serial.println(" m"); Serial.println(); // Imprime os dados do sensor SC6 SD6 TCA9548A (6); Serial.println("ID do Sensor: 6"); Serial.print("Temperatura: "); Serial.print(sensor3.readTemperature()); Serial.println(" ºC"); Serial.print("Pressão: "); Serial.print(sensor3.readPressure() / 100.0F); Serial.println(" hPa"); Serial.print("Altitude: ~"); // Valor aproximado Serial.print(sensor3.readAltitude(1013.25)); Serial.println(" m"); Serial.println(); // Imprime os dados do sensor SC7 SD7 TCA9548A (7); Serial.println("ID do Sensor: 7"); Serial.print("Temperatura: "); Serial.print(sensor4.readTemperature()); Serial.println(" ºC"); Serial.print("Pressão: "); Serial.print(sensor4.readPressure() / 100.0F); Serial.println(" hPa"); Serial.print("Altitude: ~"); // Valor aproximado Serial.print(sensor4.readAltitude(1013.25)); Serial.println(" m"); Serial.println("----------------------------------------------------"); delay(5000); }
// Projeto Leitura de Dados com Multiplexador I2C
// Endereço BMP280: 0x76
// Inclui bibliotecas para o projeto
// Nomeia os sensores utilizados
Adafruit_BMP280 sensor1;
Adafruit_BMP280 sensor2;
Adafruit_BMP280 sensor3;
Adafruit_BMP280 sensor4;
// Inicializa o Multiplexador com o endereço configurado
void TCA9548A(uint8_t id) {
Wire.beginTransmission(0x70); // A0= LOW; A1= LOW; A2= LOW
Wire.write(1 << id);
// Verifica se o sensor 4 foi identificado
if (!sensor1.begin(0x76)) {
Serial.println("Erro ao Identificar Sensor 4");
// Verifica se o sensor 5 foi identificado
if (!sensor2.begin(0x76)) {
Serial.println("Erro ao Identificar Sensor 5");
// Verifica se o sensor 6 foi identificado
if (!sensor3.begin(0x76)) {
Serial.println("Erro ao Identificar Sensor 6");
// Verifica se o sensor 7 foi identificado
if (!sensor4.begin(0x76)) {
Serial.println("Erro ao Identificar Sensor 7");
// Imprime os dados do sensor SC4 SD4
TCA9548A (4);
Serial.println("ID do Sensor: 4");
Serial.print(sensor1.readTemperature());
Serial.print("Pressão: ");
Serial.print(sensor1.readPressure() / 100.0F);
Serial.print("Altitude: ~"); // Valor aproximado
Serial.print(sensor1.readAltitude(1013.25));
// Imprime os dados do sensor SC5 SD5
TCA9548A (5);
Serial.println("ID do Sensor: 5");
Serial.print(sensor2.readTemperature());
Serial.print(sensor2.readPressure() / 100.0F);
Serial.print(sensor2.readAltitude(1013.25));
// Imprime os dados do sensor SC6 SD6
TCA9548A (6);
Serial.println("ID do Sensor: 6");
Serial.print(sensor3.readTemperature());
Serial.print(sensor3.readPressure() / 100.0F);
Serial.print(sensor3.readAltitude(1013.25));
// Imprime os dados do sensor SC7 SD7
TCA9548A (7);
Serial.println("ID do Sensor: 7");
Serial.print(sensor4.readTemperature());
Serial.print(sensor4.readPressure() / 100.0F);
Serial.print(sensor4.readAltitude(1013.25));
Para verificar se o dispositivo I2C conectado no barramento foi identificado e tabém para nomear o respectivo sensor atribuído ao mesmo, utilizamos o seguinte comando:
TCA9548A(4); // O valor entre parênteses associa o sensor aos pinos SC4 SD4 if (!sensor1.begin(0x76)) { // Verifica se o sensor conectado representa o endereço Serial.println("Erro ao Identificar Sensor 4"); // Caso contrário imprime o Erro while (1); } Serial.println(); // Cria uma linha em branco
TCA9548A(4); // O valor entre parênteses associa o sensor aos pinos SC4 SD4
if (!sensor1.begin(0x76)) { // Verifica se o sensor conectado representa o endereço
Serial.println("Erro ao Identificar Sensor 4"); // Caso contrário imprime o Erro
Serial.println(); // Cria uma linha em branco
Vale lembrar que o valor entre os parênteses é o mesmo impresso junto a módulo, indo de 0 até 7, o que faz com que mesmo que tenha oito terminais, sua contagem máxima seja 7.
TCA9548A (4); // Chama o sensor relacionado ao pino 4 Serial.println("ID do Sensor: 4"); // Imprime o texto Serial.print("Temperatura: "); // Imprime o texto Serial.print(sensor1.readTemperature()); // Lê e imprime a temperatura do sensor 1 Serial.println(" ºC"); // Imprime o texto Serial.print("Pressão: "); // Imprime o texto Serial.print(sensor1.readPressure() / 100.0F); // Lê e imprime a pressão do sensor 1 Serial.println(" hPa"); // Imprime o texto Serial.print("Altitude: ~"); // // Imprime o texto com sinal de aproximado Serial.print(sensor1.readAltitude(1013.25)); // Lê e imprime a altitude em relação ao valor de 1031.25 Serial.println(" m"); // Imprime o texto Serial.println(); // Cria uma linha em branco
TCA9548A (4); // Chama o sensor relacionado ao pino 4
Serial.println("ID do Sensor: 4"); // Imprime o texto
Serial.print(sensor1.readTemperature()); // Lê e imprime a temperatura do sensor 1
Serial.println(" ºC"); // Imprime o texto
Serial.print("Pressão: "); // Imprime o texto
Serial.print(sensor1.readPressure() / 100.0F); // Lê e imprime a pressão do sensor 1
Serial.println(" hPa"); // Imprime o texto
Serial.print("Altitude: ~"); // // Imprime o texto com sinal de aproximado
Serial.print(sensor1.readAltitude(1013.25)); // Lê e imprime a altitude em relação ao valor de 1031.25
Serial.println(" m"); // Imprime o texto
Quando utilizamos o recurso acima, devemos lembrar-nos de trocar o valor do TCA9548A (4); em cada caso de acordo com a porta individual que desejamos utilizar, lembrando que utilizamos de 4 a 7 neste projeto, porém os valores anterior também podem ser adicionados de acordo com a instalação utilizada.
Resultado das Leituras independentes
Acima, podemos observar os resultados lidos através do monitor serial e a resposta que obtemos através da programação desenvolvida para o referido projeto.
O Multiplexador é um componente muito útil, tanto em sua versão Digital quanto Analógica / I2C, porém pudemos ver neste exemplo, a capacidade deste pequeno módulo que associado adequadamente possibilita conectar uma quantia extremamente grande de sensores através de apenas dois fios.
Alcançando a marca de 64 sensores I2C, o conjunto de 08 Multiplexadores possibilita intercalar o funcionamento de todos seus dispositivos associados de uma maneira tão rápida que nem percebemos a individualidade dos comandos.
Se você curtiu este conteúdo, gostou da sugestão ou até já desenvolveu este projeto ou semelhante, não se esqueça de comentar e deixar sua opinião, sugestão e colabore para a melhora do nosso conteúdo.