
Passo 1 de 9
Conferir o módulo e montar o barramento
Prepare uma ligação I2C segura entre um Uno R3 e um módulo MCP9808 compatível com 5 V, identificando corretamente alimentação, GND, SDA, SCL e os pull-ups já existentes.
Trilha de aprendizado · Nível 11 · Tutorial 7
Ao concluir, o aluno será capaz de ler a temperatura ambiente de um módulo MCP9808 próprio por I2C, conferindo conexões, endereço, formato do registrador e resultados das transações.
Conferir o módulo e montar o barramento
Prepare uma ligação I2C segura entre um Uno R3 e um módulo MCP9808 compatível com 5 V, identificando corretamente alimentação, GND, SDA, SCL e os pull-ups já existentes. 4 min
Definir o endereço do MCP9808
Determine o endereço I2C de sete bits do MCP9808 a partir dos pinos A2, A1 e A0 e use 0x18 na configuração desta prática. 2 min
Entender a sequência de uma transação I2C
Reconheça os eventos de uma transação I2C e diferencie confirmações esperadas de ausência de confirmação. 3 min
Preparar a Wire com limite de espera
Configure a Wire do Uno R3 para 100 kHz e habilite um timeout interno de 25 ms antes de iniciar a leitura do MCP9808. 3 min
Selecionar e solicitar o registrador de temperatura
Use as chamadas da Wire para selecionar o MCP9808, apontar o registrador 0x05 e solicitar seus dois bytes em uma única transação de leitura. 3 min
Validar a transação antes de usar os bytes
Valide a escrita, o timeout e a presença dos dois bytes antes de permitir qualquer interpretação do registrador. 3 min
Converter o registrador em graus Celsius
Transforme os dois bytes já validados do registrador 0x05 em uma temperatura em graus Celsius, isolando alertas, sinal e campo numérico. 3 min
Executar a leitura no equipamento próprio
Execute o sketch completo no Uno R3, observe uma leitura válida e teste a rejeição segura de um endereço I2C sem resposta. 3 min
Aplicação final: aceitar ou rejeitar a leitura
Revise os critérios que permitem aceitar uma leitura do MCP9808 e aplique-os a casos de sucesso e falha. 2 min

Passo 1 de 9
Prepare uma ligação I2C segura entre um Uno R3 e um módulo MCP9808 compatível com 5 V, identificando corretamente alimentação, GND, SDA, SCL e os pull-ups já existentes.
Você fará a prática no seu computador e com seus próprios equipamentos: um Arduino Uno R3, um módulo MCP9808 e cabos. Antes de montar, consulte a documentação do seu módulo e confirme que ele é explicitamente compatível com alimentação e sinais de 5 V.
Módulos podem ter a mesma função, mas pinos em posições, nomes e circuitos auxiliares diferentes. Por isso, siga a função indicada no módulo e na documentação — não uma posição presumida na placa.

Use a documentação para localizar cada terminal funcional no seu módulo.
No Uno R3, o barramento desta prática usa os pinos analógicos compartilhados:
O GND comum é indispensável: ele fornece a referência de tensão para os sinais SDA e SCL. Faça a montagem com o circuito desligado.
Use esta tabela como roteiro funcional. Ela não substitui a identificação da pinagem específica do seu módulo.
| Função no MCP9808 | Conectar no Uno R3 | Conferência |
|---|---|---|
| Alimentação | 5 V, se a documentação permitir | Terminal de alimentação correto |
| GND | GND | Referência comum |
| SDA | A4 | Linha de dados |
| SCL | A5 | Linha de clock |
Atenção
Desligue a alimentação antes de inserir, remover ou trocar cabos. Meça resistência somente com o circuito desenergizado. Não adicione ligações pela posição visual de um pino: confirme seu nome na serigrafia e na documentação.
SDA e SCL são linhas de dreno aberto. Em vez de alguém forçar nível alto, cada participante do barramento faz apenas uma destas ações:
Quando todos a liberam, o resistor de pull-up leva a linha ao nível alto. Assim, vários dispositivos podem compartilhar a mesma linha sem um dispositivo dirigir alto enquanto outro dirige baixo.

O nível alto vem do pull-up; os participantes somente puxam para baixo ou liberam a linha.
Dica
Muitos módulos já incluem pull-ups. Antes de acrescentar resistores, confira na documentação:
Não acrescente pull-ups automaticamente: resistores em paralelo reduzem a resistência equivalente e podem aumentar a corrente quando a linha está em nível baixo.
Você encontrou na documentação do módulo dois resistores de pull-up já conectados de SDA e SCL para a alimentação compatível. Qual é a melhor decisão antes de instalar outros pull-ups externos?
Escreva pelo menos 40 caracteres (0/40).

Passo 2 de 9
Determine o endereço I2C de sete bits do MCP9808 a partir dos pinos A2, A1 e A0 e use 0x18 na configuração desta prática.
No barramento I2C, o Uno é o controlador: ele inicia a comunicação e escolhe com qual dispositivo quer falar. Essa escolha usa um endereço de 7 bits.
O MCP9808 usa uma base fixa, 0x18. Os pinos de endereço do próprio sensor — A2, A1 e A0 — acrescentam um valor de 0 a 7 a essa base. Assim, vários MCP9808 podem compartilhar SDA e SCL quando recebem configurações diferentes.
Atenção: A0, A1 e A2 aqui são pinos de endereço do MCP9808. Eles não são as entradas analógicas A0, A1 e A2 do Uno.

Na configuração desta prática, os três pinos de endereço do MCP9808 estão em nível baixo.
Cada pino A contribui com um bit para o final do endereço. A base 0x18 corresponde ao padrão com A2, A1 e A0 baixos:
0x18 + valor binário A2A1A0
Por exemplo, A2=0, A1=1 e A0=1 formam 011₂, que vale 3. Logo, o endereço é 0x18 + 3 = 0x1B. Consulte a documentação do seu módulo para saber como seus pinos ou resistores definem esses níveis.
Endereços possíveis para o MCP9808
| A2 A1 A0 | Valor | Endereço de 7 bits |
|---|---|---|
| 000 | 0 | 0x18 |
| 001 | 1 | 0x19 |
| 010 | 2 | 0x1A |
| 011 | 3 | 0x1B |
| 100 | 4 | 0x1C |
| 101 | 5 | 0x1D |
| 110 | 6 | 0x1E |
| 111 | 7 | 0x1F |
Para a montagem deste tutorial, A2, A1 e A0 estão em nível baixo. Complete o valor hexadecimal de sete bits que será passado à Wire.
Wire usará o endereço {{blank}} para selecionar o MCP9808 desta prática.
Não converta 0x18 para um “endereço de leitura” ou “endereço de escrita” ao chamar a Wire. O bit que diferencia leitura e escrita faz parte da transmissão no barramento, mas não deve ser acrescentado manualmente ao argumento da biblioteca.
Portanto, quando chegar o momento de iniciar uma comunicação, o valor será 0x18 — não 0x30 nem 0x31.
Dica
O endereço de 7 bits é 0x18. Se você o deslocasse uma posição para formar o byte transmitido, obteria 0x30 para escrita ou 0x31 para leitura. A Wire recebe somente 0x18 e cuida dessa parte do protocolo.

Passo 3 de 9
Reconheça os eventos de uma transação I2C e diferencie confirmações esperadas de ausência de confirmação.
Uma transação I2C é delimitada por condições especiais nas duas linhas do barramento:
Entre esses limites, os bits de dados normalmente mudam enquanto SCL está baixo. O receptor observa o valor de SDA enquanto SCL está alto. Essa regra permite distinguir dados das condições que abrem e encerram uma conversa no barramento.

As transições de SDA com SCL alto delimitam START e STOP; os dados ficam estáveis na parte alta dos pulsos de SCL.
Cada trecho transmitido tem oito bits e mais um nono pulso de clock destinado à confirmação.
Após os oito bits, quem recebeu o byte pode puxar SDA para baixo no nono pulso: isso é ACK. Se SDA permanece em alto, há um NACK.
O sentido importa: quem transmite os oito bits não é necessariamente quem confirma. Por exemplo, ao controlador enviar endereço e dados, o sensor confirma. Ao sensor enviar um byte de leitura, o controlador confirma ou encerra com NACK.

ACK e NACK são estados do nono pulso. O receptor é quem produz essa resposta.
Dica
O I2C também prevê que um dispositivo mantenha SCL em nível baixo por mais tempo antes de liberar o próximo pulso. Esse comportamento é chamado de prolongamento do clock.
Ele é uma possibilidade do protocolo; não conclua apenas por isso que o MCP9808 o usará nesta prática. Uma linha mantida baixa também pode indicar outro problema físico no barramento.
Uma leitura de registrador costuma ter duas fases contínuas. Depois de selecionar um registrador para escrita, o controlador gera um START repetido: uma nova condição START sem STOP intermediário. Assim, a comunicação muda para a fase de leitura sem liberar o barramento entre as fases.
Em uma leitura de dois bytes, o controlador confirma o primeiro byte recebido com ACK. No segundo e último byte, ele responde com NACK e então gera STOP. Esse NACK final informa ao dispositivo que não deve enviar outro byte.

O NACK do controlador depois do último byte é parte normal do encerramento de uma leitura.
Atenção
Nem todo NACK tem o mesmo significado:
Portanto, interprete o NACK observando quem o enviou e em que ponto da transação ele ocorreu.
Organize a sequência de uma leitura de dois bytes com START repetido.
Qual NACK faz parte de uma leitura I2C normal de dois bytes?

Passo 4 de 9
Configure a Wire do Uno R3 para 100 kHz e habilite um timeout interno de 25 ms antes de iniciar a leitura do MCP9808.
Nesta prática, use a biblioteca Wire fornecida pelo pacote Arduino AVR Boards: não é necessária uma biblioteca específica para o MCP9808. O Uno será configurado para I2C a 100 kHz.
Antes de escrever a leitura do sensor, confirme no seu ambiente local que a versão instalada do pacote Arduino AVR Boards documenta estas funções:
Wire.setWireTimeout(...)Wire.getWireTimeoutFlag()Wire.clearWireTimeoutFlag()Consulte a referência da versão instalada na IDE ou os arquivos locais do pacote. Se essa API não estiver disponível, atualize o pacote antes de continuar. Não remova a proteção de timeout como substituto.

A Wire configura o barramento; a proteção de timeout limita esperas internas da biblioteca.
Coloque esta configuração no início de setup(), antes das transações que serão criadas nos próximos passos.
Configuração da Wire para esta prática
#include <Wire.h>
void setup() {
Wire.begin();
Wire.setClock(100000L);
Wire.setWireTimeout(25000, true);
}
void loop() {
}Dica
100000L representa 100.000 Hz, isto é, 100 kHz. Em Wire.setWireTimeout(25000, true), o primeiro argumento está em microssegundos: 25.000 µs equivalem a 25 ms.
O segundo argumento true permite que a Wire reinicialize o periférico TWI se detectar o timeout. Isso pode recuperar o periférico, mas não garante liberar uma linha SDA ou SCL que permaneça fisicamente presa em nível baixo.
O timeout da Wire atua nas esperas internas das chamadas da própria biblioteca. Ele é diferente de medir um tempo fora da chamada.
Se uma chamada bloqueante estiver esperando uma condição no barramento, o código após essa chamada ainda não começou a executar. Por isso, um teste com millis() colocado apenas antes e depois dela não consegue interrompê-la.
A flag de timeout também é persistente: depois de registrada, continua ativa até você limpá-la explicitamente. Nos próximos passos, ela será limpa no começo de cada tentativa e consultada ao longo da transação.
Atenção
Não interprete a reinicialização do TWI como conserto automático da montagem. Com alimentação desligada, confira conexões e pull-ups se o barramento continuar sem responder.
Complete apenas as chamadas de configuração. Considere que Wire.h já foi incluída e que o código é destinado ao Uno R3 com uma versão AVR que oferece a API de timeout.
Preencha os valores usados nesta prática.
void setup() {
Wire.begin();
Wire.setClock();
Wire.setWireTimeout(, true);
}
Passo 5 de 9
Use as chamadas da Wire para selecionar o MCP9808, apontar o registrador 0x05 e solicitar seus dois bytes em uma única transação de leitura.
Há dois endereços diferentes nesta leitura:
Portanto, não use 0x05 em Wire.beginTransmission(): essa chamada espera o endereço do dispositivo, isto é, 0x18.

O endereço 0x18 seleciona o sensor; 0x05 seleciona seu registrador de temperatura.
A leitura é feita em duas fases contínuas.
1. Apontar o registrador. Wire.beginTransmission(0x18) prepara uma transmissão ao sensor. Wire.write(0x05) coloca no buffer o registrador desejado.
2. Manter o barramento. Wire.endTransmission(false) transmite essa fase, mas o argumento false evita o STOP. Assim, a próxima chamada pode continuar com um START repetido.
O valor retornado por endTransmission() será validado no próximo step. Por enquanto, concentre-se na sequência e no papel de cada chamada.
Fase 1: selecionar o registrador de temperatura
const uint8_t MCP9808 = 0x18;
const uint8_t REG_TEMPERATURA = 0x05;
Wire.beginTransmission(MCP9808);
Wire.write(REG_TEMPERATURA);
uint8_t status = Wire.endTransmission(false);Dica
Use false, e não true, nesta chamada. O true padrão enviaria STOP após 0x05, quebrando a sequência que queremos manter até a fase de leitura.
Depois da fase de escrita sem STOP, solicite dois bytes ao mesmo sensor:
uint8_t recebidos = Wire.requestFrom(MCP9808, (uint8_t)2);A biblioteca inicia a fase de leitura e emite STOP quando ela termina. Durante o recebimento, ela também cuida do protocolo: confirma o primeiro byte com ACK, envia NACK após o segundo e último byte e encerra a transação.
Não controle SDA ou SCL manualmente para produzir esses eventos.
Organize as fases da leitura do registrador 0x05. Pense na ordem que mantém a transação contínua entre o envio do registrador e a solicitação de dados.
Coloque as etapas na ordem correta.
Complete a sequência que aponta o registrador de temperatura e solicita seus dois bytes. As lacunas representam valores e argumentos essenciais, não nomes de variáveis arbitrários.
Preencha a sequência de leitura do registrador de temperatura.
Wire.beginTransmission();
Wire.write();
Wire.endTransmission();
Wire.requestFrom((uint8_t)0x18, (uint8_t));
Passo 6 de 9
Valide a escrita, o timeout e a presença dos dois bytes antes de permitir qualquer interpretação do registrador.
Uma leitura só pode chegar à etapa de interpretação quando todas as verificações de transporte forem aprovadas. Comece cada tentativa limpando a flag persistente de timeout. Depois, confira essa flag após cada operação da Wire que possa aguardar o barramento.
A fase que seleciona o registrador termina em Wire.endTransmission(false). Se ela falhar, encerre a tentativa imediatamente: não solicite os dois bytes e não produza uma temperatura.
Mesmo que o retorno da escrita seja sucesso, um timeout registrado torna a tentativa inválida.

A conversão só pode ser chamada depois dos quatro portões verdes: escrita válida, sem timeout, dois bytes retornados e dois bytes disponíveis.
No núcleo Arduino AVR adotado, o retorno de Wire.endTransmission(false) informa o resultado da fase de escrita. O valor 0 é o único sucesso. Os demais valores devem ser tratados como falha e comunicados como tal, sem inventar um valor de temperatura.
Consulte a documentação da versão local do pacote Arduino AVR Boards para confirmar os códigos disponíveis.
Códigos usuais retornados por Wire.endTransmission(false) no Arduino AVR.
| Retorno | Significado | Ação nesta tentativa |
|---|---|---|
| 0 | Escrita concluída | Prosseguir para a leitura |
| 1 | Buffer de transmissão excedido | Rejeitar |
| 2 | NACK no endereço | Rejeitar |
| 3 | NACK no dado enviado | Rejeitar |
| 4 | Outro erro | Rejeitar |
| 5 | Timeout | Rejeitar |
Esta função valida o transporte e só entrega dois bytes quando a tentativa está completa. Ela ainda não converte esses bytes em graus Celsius.
bool lerBytesTemperatura(uint8_t &msb, uint8_t &lsb) {
Wire.clearWireTimeoutFlag();
Wire.beginTransmission(0x18);
Wire.write(0x05);
uint8_t status = Wire.endTransmission(false);
if (Wire.getWireTimeoutFlag()) {
Serial.println("Falha: timeout na escrita");
return false;
}
if (status != 0) {
Serial.print("Falha na escrita, codigo: ");
Serial.println(status);
return false;
}
uint8_t recebidos = Wire.requestFrom(0x18, 2);
if (Wire.getWireTimeoutFlag()) {
Serial.println("Falha: timeout na leitura");
return false;
}
if (recebidos != 2 || Wire.available() != 2) {
Serial.println("Falha: recebimento incompleto");
return false;
}
int primeiro = Wire.read();
int segundo = Wire.read();
if (primeiro < 0 || segundo < 0) {
Serial.println("Falha: byte ausente");
return false;
}
msb = (uint8_t)primeiro;
lsb = (uint8_t)segundo;
return true;
}Dica
Wire.requestFrom() informa quantos bytes foram efetivamente recebidos. Antes de cada Wire.read(), confirme também a disponibilidade com Wire.available().
Wire.read() retorna um int: quando não há dado, ele pode retornar valor negativo. Fazer uma conversão direta para uint8_t poderia transformar essa ausência em um byte aparentemente válido. Por isso, leia primeiro em int, teste o resultado e só então converta.
Se a função retornar false, mostre a falha e não chame a conversão. Zero será uma temperatura válida mais adiante; não deve ser usado como substituto de erro.
Complete os critérios numéricos que aceitam a escrita e exigem o recebimento completo antes de ler os bytes.
uint8_t status = Wire.endTransmission(false);
if (status != || Wire.getWireTimeoutFlag()) {
return false;
}
uint8_t recebidos = Wire.requestFrom(0x18, 2);
if (Wire.getWireTimeoutFlag() ||
recebidos != || Wire.available() != ) {
return false;
}
Passo 7 de 9
Transforme os dois bytes já validados do registrador 0x05 em uma temperatura em graus Celsius, isolando alertas, sinal e campo numérico.
A conversão só começa depois de a tentativa ter sido validada: escrita concluída, sem timeout e dois bytes disponíveis. O registrador de temperatura é o 0x05.
O MCP9808 envia primeiro o byte mais significativo (MSB) e depois o menos significativo (LSB). Portanto, se a leitura fornecer msb e lsb, a palavra de 16 bits é formada como MSB:LSB, e não na ordem inversa.
Os bits 15 a 13 trazem indicadores de alerta. Eles fazem parte da palavra recebida, mas não fazem parte do valor numérico da temperatura.

Os alertas ocupam os bits 15 a 13; o bit 12 informa o sinal; os bits 11 a 0 formam o campo numérico.
Monte a palavra com uint16_t. A conversão explícita antes do deslocamento faz o deslocamento ocorrer em um tipo sem sinal de 16 bits, em vez de depender do comportamento de int com sinal no AVR.
Depois, use máscaras separadas: 0x0FFF conserva apenas o campo numérico, e 0x1000 testa o bit de sinal. A divisão por 16.0 preserva a fração: cada unidade do campo vale 1/16 °C.
Trecho para usar somente após validar os dois bytes recebidos.
uint16_t raw = (static_cast<uint16_t>(msb) << 8) | lsb;
uint16_t campo = raw & 0x0FFF;
float temperaturaC = campo / 16.0;
if (raw & 0x1000) {
temperaturaC -= 256.0;
}Dica
A fórmula é aplicada ao campo mascarado, não à palavra inteira:
temperatura = campo / 16.0temperatura = campo / 16.0 - 256.0Os bits de alerta não alteram o cálculo. Eles ficam fora porque a máscara 0x0FFF remove os bits 15 a 12 antes da divisão.
Confira alguns valores completos. Em todos os casos, o campo numérico é dividido por 16. Os alertas ativos no último caso não entram no resultado.
| Palavra recebida | Campo 0x0FFF | Cálculo | Temperatura |
|---|---|---|---|
| 0x0198 | 0x0198 | 408 / 16 | 25,5 °C |
| 0x1FF8 | 0x0FF8 | 4088 / 16 − 256 | −0,5 °C |
| 0x0000 | 0x0000 | 0 / 16 | 0,0 °C |
| 0xE190 | 0x0190 | 400 / 16 | 25,0 °C |
Exemplo
Em 0xE190, os três bits de alerta estão ativos (111 nos bits 15 a 13). Ainda assim, o valor é 25,0 °C: a máscara mantém somente 0x0190. Zero também é uma temperatura válida quando a transação foi completa; não é, por si só, sinal de falha.
Complete as lacunas para montar a palavra e converter uma leitura negativa. Os alertas devem permanecer fora do valor calculado.
Preencha os elementos da conversão do registrador MCP9808.
uint16_t raw = ( << 8) | lsb;
uint16_t campo = raw & ;
float temperaturaC = campo / ;
if (raw & ) {
temperaturaC -= ;
}
Passo 8 de 9
Execute o sketch completo no Uno R3, observe uma leitura válida e teste a rejeição segura de um endereço I2C sem resposta.
Com a montagem já conferida e o MCP9808 configurado em 0x18, a execução terá dois estados:
Nas próximas telas, copie os dois blocos para um único sketch, na ordem apresentada. Compile, grave no Uno e abra o Monitor Serial em 9600 baud. A primeira tentativa acontece cerca de um segundo após a placa iniciar; as próximas ocorrem a cada segundo.
A temperatura ambiente não tem um valor predeterminado e pode oscilar um pouco. Não aqueça nem resfrie o sensor para este teste.

O programa só mostra uma temperatura depois de concluir e validar toda a transação.
Bloco 1 de 2 — coloque este trecho no início do sketch. Ele reúne a leitura validada e a conversão já estudadas.
#include <Wire.h>
constexpr uint8_t SENSOR_ADDR = 0x18;
constexpr uint8_t TEMP_REG = 0x05;
constexpr unsigned long INTERVALO_MS = 1000;
enum ReadStatus {
READ_OK,
WRITE_ERROR,
TIMEOUT_ERROR,
INCOMPLETE_DATA
};
ReadStatus readTemperature(float &celsius) {
Wire.clearWireTimeoutFlag();
Wire.beginTransmission(SENSOR_ADDR);
Wire.write(TEMP_REG);
uint8_t writeStatus = Wire.endTransmission(false);
if (Wire.getWireTimeoutFlag()) {
return TIMEOUT_ERROR;
}
if (writeStatus != 0) {
return WRITE_ERROR;
}
uint8_t received = Wire.requestFrom(SENSOR_ADDR, (uint8_t)2);
if (Wire.getWireTimeoutFlag()) {
return TIMEOUT_ERROR;
}
if (received != 2 || Wire.available() != 2) {
return INCOMPLETE_DATA;
}
int msb = Wire.read();
int lsb = Wire.read();
if (msb < 0 || lsb < 0) {
return INCOMPLETE_DATA;
}
uint16_t raw = ((uint16_t)msb << 8) | (uint8_t)lsb;
celsius = (raw & 0x0FFF) / 16.0;
if (raw & 0x1000) {
celsius -= 256.0;
}
return READ_OK;
}Bloco 2 de 2 — acrescente este trecho abaixo do bloco anterior. Juntos, os dois blocos formam o sketch completo para compilar e gravar.
unsigned long lastAttempt = 0;
void printResult(ReadStatus status, float celsius) {
if (status == READ_OK) {
Serial.print("Temperatura: ");
Serial.print(celsius, 4);
Serial.println(" C");
} else if (status == WRITE_ERROR) {
Serial.println("Falha I2C: escrita ou endereco sem resposta");
} else if (status == TIMEOUT_ERROR) {
Serial.println("Falha I2C: timeout");
} else {
Serial.println("Falha I2C: recebimento incompleto");
}
}
void setup() {
Serial.begin(9600);
Wire.begin();
Wire.setClock(100000L);
Wire.setWireTimeout(25000, true);
}
void loop() {
unsigned long now = millis();
if (now - lastAttempt >= INTERVALO_MS) {
lastAttempt = now;
float celsius = 0.0;
ReadStatus status = readTemperature(celsius);
printResult(status, celsius);
}
}Temperatura: 23.5000 C Temperatura: 23.5000 C Falha I2C: escrita ou endereco sem resposta Falha I2C: escrita ou endereco sem resposta Temperatura: 23.5000 C
Com `SENSOR_ADDR = 0x18`, as linhas de temperatura são exemplos: o valor real varia com o ambiente. Após trocar apenas a constante para `0x19` e gravar novamente, espere as linhas de falha. Depois de restaurar `0x18`, uma nova linha de temperatura deve voltar a aparecer.
Dica
Ao usar 0x18, registre um valor aproximado visto no Monitor Serial. O número pode mudar levemente entre uma tentativa e outra.
Embora celsius comece como 0.0, ele só é impresso quando status == READ_OK. Assim, uma falha não se torna falsamente 0.0000 C e não reutiliza uma temperatura anterior como se fosse uma nova leitura.
Agora teste uma ausência de resposta sem alterar a fiação:
SENSOR_ADDR = 0x18 por SENSOR_ADDR = 0x19.0x18 no barramento.Falha I2C: escrita ou endereco sem resposta. Não deve aparecer uma temperatura nessa tentativa.0x18, grave o sketch e confirme que a temperatura volta a aparecer.A alteração seleciona um endereço diferente e produz um teste seguro de NACK de endereço.
Atenção
Não altere conexões com o circuito energizado. Faça este teste exclusivamente pela mudança do endereço no código. Não provoque curto-circuito nem tente prender SDA ou SCL em nível baixo.
Complete a constante usada temporariamente para testar o NACK de endereço.
constexpr uint8_t SENSOR_ADDR = ;Relate o que você observou: informe um valor aproximado obtido com 0x18, a mensagem ou estado visto com 0x19 e o que aconteceu depois de restaurar 0x18.
Escreva pelo menos 50 caracteres (0/50).

Passo 9 de 9
Revise os critérios que permitem aceitar uma leitura do MCP9808 e aplique-os a casos de sucesso e falha.
Antes de converter, siga sempre esta ordem: montagem compatível → endereço do sensor → registrador 0x05 → transação → validação → conversão.
Uma tentativa só pode virar temperatura quando a escrita do registrador teve sucesso, não houve timeout e chegaram exatamente dois bytes disponíveis. Um valor de 0,00 °C pode ser válido: zero não é sinal automático de falha.
| Etapa | Evidência para prosseguir | Se falhar |
|---|---|---|
| Selecionar | Endereço do MCP9808 configurado | Não iniciar leitura como válida |
| Apontar registrador | endTransmission() retorna 0 | Classificar como falha de escrita/NACK |
| Solicitar bytes | Sem flag de timeout | Classificar como timeout |
| Receber | 2 bytes retornados e disponíveis | Classificar como recebimento incompleto |
| Converter | Dois bytes brutos válidos | Calcular temperatura em °C |

A barreira só libera bytes completos, obtidos sem falha de escrita nem timeout.
Associe cada evidência ao resultado correto. Considere um MCP9808 configurado no endereço 0x18 e a seleção do registrador 0x05.
| Caso | endTransmission() | Timeout? | Bytes recebidos | Bytes brutos |
|---|---|---|---|---|
| A | 0 | não | 2 | 0x00, 0x00 |
| B | 2 | não | 0 | — |
| C | 0 | sim | 0 | — |
| D | 0 | não | 1 | 0x01 |
Faça a associação entre o caso e sua conclusão.
Associe cada caso à classificação correta.
Toque em um item e depois no par correspondente.
Considere esta tentativa: o sensor está configurado em 0x18; endTransmission(false) retorna 0; a flag de timeout está limpa; requestFrom() retorna 2 e há 2 bytes disponíveis: 0x01 e 0x90.
Ela pode ser aceita? Se puder, calcule a temperatura e explique brevemente por que os bits de alerta não alteram o valor.
Escreva pelo menos 80 caracteres (0/80).
| Critério | Deve ser verdadeiro |
|---|---|
| Montagem | Módulo compatível, alimentação, GND e pull-ups conferidos |
| Endereço | O endereço usado corresponde a A2, A1 e A0 |
| Escrita | A seleção de 0x05 terminou com retorno 0 |
| Espera | Não há flag de timeout |
| Recebimento | Exatamente 2 bytes retornados e disponíveis |
| Conversão | Bytes montados e interpretados conforme o formato do MCP9808 |
| Se ocorrer | Faça |
|---|---|
| NACK | Informe a falha; não gere temperatura |
| Timeout | Informe timeout; não use bytes |
| Menos de 2 bytes | Informe recebimento incompleto |
| Todos os critérios atendidos | Converta e apresente a temperatura, inclusive se for 0,00 °C |
Resumo
Parabéns! Você concluiu: Leitura de temperatura por I2C com o MCP9808
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks