Trilha de aprendizado · Nível 11 · Tutorial 9

Diagnóstico de aquisição e falhas de comunicação

Ao concluir, o aluno será capaz de investigar leituras incoerentes e falhas de comunicação, preservar a distinção entre dados válidos e inválidos e recuperar a aquisição sem esperas ou tentativas ilimitadas.

  • Nível: Intermediário
  • Duração: 22 min
  • 10 passos
Diagnóstico de aquisição e falhas de comunicação

O que você vai percorrer

  1. Localizar a camada antes de corrigir Classifique sintomas pelo percurso da medição e escolha observações que diferenciem hipóteses antes de alterar a montagem ou o firmware. 2 min
  2. Registrar evidências sem perturbar a aquisição Registre evidências de aquisição de forma comparável, explícita e limitada para não perturbar a comunicação que está sendo investigada. 2 min
  3. Distinguir problema elétrico de problema de amostragem Escolha medições seguras para diferenciar saturação, referência incorreta e efeitos de amostragem. 2 min
  4. Interpretar os indícios de UART, I2C e SPI Relacione indícios de UART, I2C e SPI às verificações que realmente diferenciam suas causas. 3 min
  5. Conferir os bytes antes de aceitar o valor Compare bytes brutos, palavra montada e valor convertido para localizar erros de interpretação com vetores conhecidos. 3 min
  6. Separar valor, validade e idade Represente valor, validade e idade como informações independentes para não confundir zero, ausência e histórico. 3 min
  7. Limitar esperas e novas tentativas Defina tentativas com prazo, intervalo e encerramento explícito, sem esperas ou novas tentativas ilimitadas. 3 min
  8. Confirmar a recuperação antes de retomar Recupere a aquisição de modo controlado e retome a operação somente após uma nova leitura validada. 2 min
  9. Planejar testes de falha sem danificar a montagem Planeje uma falha de comunicação controlada, segura e reversível para verificar detecção, limite de tentativas e recuperação. 2 min
  10. Concluir e documentar um diagnóstico completo Aplique um roteiro completo de diagnóstico a registros de operação, falha e recuperação controlada. 2 min

O que você vai aprender

  • Classificar um sintoma por camada e escolher uma observação que diferencie causas possíveis.
  • Comparar bytes brutos e valores convertidos para localizar erros de interpretação.
  • Identificar amostras ausentes ou antigas sem substituí-las silenciosamente por zero.
  • Definir tentativas limitadas e um comportamento explícito diante de ausência de resposta.
  • Documentar a hipótese, a evidência e o resultado de um teste seguro de recuperação.

Antes de começar

  • Leitura de tensão com o ADC do Arduino Uno
  • Taxa de amostragem e prevenção de aliasing
  • Mensagens UART com delimitação e timeout
  • Leitura de temperatura por I2C com o MCP9808
  • Aquisição por SPI com o MCP3008
  • Observação segura de sinais com o osciloscópio

Passo 1 de 10

Localizar a camada antes de corrigir

Classifique sintomas pelo percurso da medição e escolha observações que diferenciem hipóteses antes de alterar a montagem ou o firmware.

Mapa da medição

Investigue por camadas

Uma leitura estranha não aponta automaticamente para uma causa. Antes de mudar código, cabos ou parâmetros, localize em qual camada do percurso o problema pode ter surgido.

Use este mapa: alimentação e referência → sinal físico → configuração da interface → transação → interpretação do dado → valor apresentado.

Cada camada deixa indícios diferentes. O objetivo inicial não é adivinhar: é escolher a próxima observação que elimine possibilidades.

O caminho até o valor

Diagrama do percurso de uma medição: sensor e referência, sinal, interface, transação, bytes e valor exibido.

A investigação segue o mesmo caminho que os dados percorrem. Observe um ponto por vez.

Da observação à hipótese

Sintoma não é diagnóstico

Separe três coisas:

  • Sintoma: o que foi observado. Ex.: “a tela mostra 0”, “não chegaram bytes” ou “a temperatura é implausível”.
  • Hipótese: uma explicação possível. Ex.: entrada em 0 V, endereço I2C incorreto, bytes invertidos.
  • Evidência: uma observação que pode apoiar ou enfraquecer uma hipótese. Ex.: medir a entrada, conferir a contagem de bytes ou comparar os bytes com um caso conhecido.

Um sintoma pode ter várias hipóteses. Portanto, evite mudar várias configurações ao mesmo tempo: se o resultado mudar, você não saberá qual alteração foi relevante.

Exemplo

Exemplo: extremo não prova defeito

Caso: um ADC apresenta repetidamente o código máximo.

Isso pode indicar, entre outras possibilidades:

  • tensão de entrada acima da faixa de conversão;
  • referência assumida ou conexão de referência inadequada;
  • problema na cadeia analógica antes do ADC;
  • interpretação errada de bytes, se o código veio de um ADC externo.

O código máximo é o sintoma. Uma observação útil é comparar a tensão realmente presente na entrada com a referência aplicável. Ela ajuda a separar uma condição elétrica de uma possível falha na interpretação.

Escolha uma observação discriminante

Três separações úteis

Uma escolha inicial prática:

  • Não há resposta, caracteres truncados ou quantidade inesperada de bytes: investigue configuração e transação antes de converter qualquer dado.
  • Há resposta completa, mas o valor físico é incoerente: compare sinal ou referência e bytes brutos; o problema pode estar na cadeia elétrica ou na interpretação.
  • Há bytes completos e coerentes, mas a conversão mostrada diverge do resultado esperado: concentre-se na montagem da palavra, sinal, máscara ou escala.

“Transferir algo” não confirma, por si só, que o dado representa uma medição correta.

Dica

Uma mudança por vez

Ao escolher a próxima ação, prefira uma observação que produza resultados diferentes para hipóteses diferentes.

Por exemplo, diante de uma leitura I2C incoerente, alterar simultaneamente endereço, clock e fórmula de conversão mistura camadas. Em vez disso, primeiro verifique se a transação fornece a quantidade de bytes esperada; depois compare os bytes recebidos com o formato documentado; só então avalie a conversão.

Assim, cada passo reduz a incerteza sem criar novos efeitos difíceis de explicar.

Prática: localize o primeiro ponto

Qual camada vem primeiro?

Associe cada sintoma à camada que deve ser investigada primeiro. Considere que esta é apenas a primeira direção da investigação, não uma conclusão definitiva.

Faça as associações.

Toque em um item e depois no par correspondente.

Passo 2 de 10

Registrar evidências sem perturbar a aquisição

Registre evidências de aquisição de forma comparável, explícita e limitada para não perturbar a comunicação que está sendo investigada.

Registrar fatos, não suposições

O registro mínimo

Uma investigação útil registra o bastante para comparar tentativas, sem transformar o diagnóstico em uma nova fonte de falhas. Para cada operação, anote: interface e dispositivo/canal, instante, estado da transação, quantidade de bytes recebidos, bytes brutos e, somente se a resposta estiver completa e aceita, o valor convertido.

O estado explica o que ocorreu; os campos numéricos mostram a evidência. Exemplo: I2C MCP9808 t=1250 ms estado=PARCIAL n=1 bruto=0x01 valor=indisponível.

Não invente informação ausente. Se nenhum byte chegou, bytes brutos e valor convertido são indisponíveis. Se chegaram menos bytes que o esperado, registre apenas os bytes efetivamente recebidos e não converta a resposta.

Diagrama de um registro de diagnóstico com campos separados; o valor convertido só aparece quando a resposta está completa.

Registre evidências observadas e marque explicitamente o que não foi recebido.

Comparar e publicar com limite

Dois registros, duas situações

Compare uma referência conhecida como correta com a tentativa sob investigação. A comparação mostra em que ponto os registros deixam de ser equivalentes, sem concluir ainda qual correção será necessária.

Exemplo de campos que permitem distinguir ausência, resposta parcial e uma resposta completa que ainda exige conferência.
CampoOperação conhecida corretaTentativa com falha
Interface / alvoI2C / 0x18I2C / 0x18
Instante1250 ms2250 ms
EstadoCOMPLETAPARCIAL
Bytes recebidos2 de 21 de 2
Bytes brutos0x01 0x900x01
Valor convertido25,0 °Cindisponível

Publicar sem inundar a UART

Exemplo de publicação limitada: a aquisição pode continuar em seu ritmo; o monitor recebe apenas um resumo periódico ou um evento novo.

cpp
const unsigned long INTERVALO_LOG_MS = 1000;
unsigned long ultimoLogMs = 0;
unsigned int falhasDesdeUltimoLog = 0;

void publicarResumo(bool houveFalha, unsigned long agora) {
  if (houveFalha) {
    falhasDesdeUltimoLog++;
  }

  if (agora - ultimoLogMs >= INTERVALO_LOG_MS) {
    Serial.print("falhas no intervalo: ");
    Serial.println(falhasDesdeUltimoLog);
    falhasDesdeUltimoLog = 0;
    ultimoLogMs = agora;
  }
}

Dica

Diagnóstico com impacto controlado

A frequência de aquisição não precisa ser a frequência de publicação. Registre cada falha no estado interno, mas publique um resumo em intervalos definidos, com uma contagem de ocorrências. Mensagens curtas e limitadas reduzem o risco de encher buffers, atrasar o programa ou alterar o próprio sintoma investigado.

Verificar a evidência e o limite

Prática: limitar o registro

Complete a condição que limita a publicação do resumo. A aquisição e a contagem de falhas podem continuar fora desse bloco.

cpp
if (agora - ultimoLogMs >= ) {
  Serial.print("falhas no intervalo: ");
  Serial.println(falhasDesdeUltimoLog);
  falhasDesdeUltimoLog = 0;
  ultimoLogMs = agora;
}

Evidência suficiente

Qual conjunto de campos separa corretamente uma resposta ausente de uma resposta parcial e de uma resposta completa que gerou um valor?

Passo 3 de 10

Distinguir problema elétrico de problema de amostragem

Escolha medições seguras para diferenciar saturação, referência incorreta e efeitos de amostragem.

Código extremo: compare antes de concluir

Comece pela cadeia de medição

Um código ADC repetidamente em 0 ou no máximo não condena o conversor sozinho. Localize primeiro o ponto em que a evidência deixa de ser coerente:

  1. Meça a tensão de entrada em relação ao terra da montagem.
  2. Confira a referência realmente usada pelo ADC.
  3. Compare esses valores com o código bruto.

Entrada próxima de 0 V pode justificar código baixo; entrada próxima ou acima da referência pode justificar saturação alta. Se a tensão estiver dentro da faixa esperada, mas o código permanecer extremo, ainda há hipóteses sobre conexão, canal, referência ou aquisição a investigar.

Pontos de comparação

Diagrama da tensão de entrada, da referência do ADC e do código bruto como três pontos de observação da mesma medição.

Compare grandezas da mesma cadeia antes de atribuir a causa ao ADC.

Dica

Princípio de diagnóstico

Evite mudar referência, canal, taxa e fiação ao mesmo tempo. Uma observação por vez reduz as hipóteses concorrentes e preserva o significado do resultado.

Teste estável e leitura da evidência

Use uma entrada estável para separar hipóteses

Uma tensão contínua conhecida e compatível com a entrada é um teste de separação útil. Ela não precisa ser “perfeita”: basta conhecer seu nível por uma medição segura e mantê-lo estável durante a comparação.

Se essa tensão produz um código coerente, a cadeia de aquisição ganha evidência favorável; investigue então o sinal variável, sua faixa ou sua amostragem. Se ainda produz resultado incoerente, concentre a investigação na entrada, referência, canal ou configuração de aquisição.

Exemplo

Exemplo: teste com nível conhecido

Caso: o ADC de 10 bits usa referência medida de 4,90 V. Uma entrada contínua medida em 2,45 V deveria resultar aproximadamente em metade da escala: código 512. O registro mostra 511 repetidamente.

Essa evidência favorece o funcionamento da cadeia nessa condição. Ela não prova que um sinal variável será adquirido sem aliasing ou que a taxa de amostragem é adequada.

Evidência e próximo passo

| Evidência observada | Hipótese mais compatível | Próxima observação |
|---|---|---|
| Entrada próxima de 0 V e código 0 | Nível baixo real ou ligação ao terra | Confirmar tensão no pino e terra comum |
| Entrada próxima de Vref e código máximo | Saturação na faixa | Verificar se o sinal excede a faixa |
| 2,45 V com Vref de 4,90 V e código 511 | Cadeia coerente nesse teste | Investigar o sinal variável |
| Tensão estável, mas código oscila muito | Aquisição, referência ou ruído | Medir referência e observar o sinal |

A tabela orienta a próxima observação; ela não substitui a medição no circuito.
Evidência observadaHipótese mais compatívelPróxima observação
Entrada próxima de 0 V e código 0Nível baixo real ou ligação ao terraConfirmar tensão no pino e terra comum
Entrada próxima de Vref e código máximoSaturação na faixaVerificar se o sinal excede a faixa
2,45 V com Vref de 4,90 V e código 511Cadeia coerente nesse testeInvestigar o sinal variável
Tensão estável, mas código oscila muitoAquisição, referência ou ruídoMedir referência e observar o sinal

Nível contínuo não mostra tudo

Escolha o instrumento pela hipótese

O multímetro é apropriado para comparar níveis contínuos, como entrada e referência. Porém, seu valor médio não revela necessariamente pulsos, bordas, ruído rápido nem a integridade de uma comunicação digital.

Quando a hipótese depende de variação no tempo, o osciloscópio — se disponível — permite observar nível, variação e bordas. Compare a taxa de amostragem registrada com o comportamento esperado do sinal; uma variação aparente pode ser aliasing, mas exige evidência adicional.

Atenção

Segurança nas medições

Faça medições somente em montagens de baixa tensão. Ao usar um osciloscópio aterrado, conecte a garra de terra apenas a um terra compatível da montagem. Nunca remova o aterramento de proteção do instrumento para “resolver” uma conexão.

Sem instrumentos, analise os casos e registros fornecidos no tutorial: a conclusão deve indicar o que a evidência permite — e o que ela ainda não permite afirmar.

Prática: não extrapole o valor médio

Escolha a próxima evidência

Uma leitura de multímetro mostra 2,50 V estáveis na entrada de um ADC. Os códigos digitais registrados alternam de modo aparentemente irregular. A aplicação amostra um sinal que pode variar rapidamente.

Qual é o próximo teste mais informativo?

Escreva pelo menos 80 caracteres (0/80).

Passo 4 de 10

Interpretar os indícios de UART, I2C e SPI

Relacione indícios de UART, I2C e SPI às verificações que realmente diferenciam suas causas.

Leia o indício no contexto da interface

O retorno depende da interface

Um indício de comunicação só ganha significado dentro da interface e da fase em que apareceu. Antes de mudar configuração ou fiação, registre o sintoma e escolha uma observação que separe hipóteses.

  • UART: caracteres incoerentes sugerem configuração incompatível, como taxa ou enquadramento. Isso é diferente de mensagem incompleta ou de nenhum byte recebido.
  • I2C: ACK e NACK pertencem a fases específicas da transação; ainda é preciso confirmar quantos bytes chegaram.
  • SPI: transferir bytes mostra que o controlador gerou clocks e leu níveis em MISO. Não existe ACK padronizado que confirme a presença do periférico.

Indícios não têm o mesmo significado

Comparação visual entre caracteres incoerentes em UART, uma leitura I2C normal de dois bytes e uma transferência SPI com bytes zero sem confirmação de periférico.

O mesmo resultado aparente exige verificações diferentes em UART, I2C e SPI.

Cheque fase e quantidade no I2C

Sintoma, hipótese e verificação

Use o sintoma para escolher a próxima verificação, não para fechar o diagnóstico cedo demais.

Cada linha sugere uma observação que reduz a incerteza.
Interface e sintomaHipóteses iniciaisPróxima verificação
UART: caracteres sem sentidoTaxa ou enquadramento incompatíveisComparar a configuração nos dois extremos
UART: mensagem truncadaPerda, delimitador ausente ou prazo encerradoConferir bytes recebidos e terminador esperado
I2C: NACK inesperadoEndereço, fase, alimentação ou conexãoLocalizar a fase do NACK antes de concluir a causa
I2C: menos bytes que o esperadoResposta parcialRejeitar a leitura antes de montar ou converter
SPI: resultado constanteCS, modo, clock, ordem dos bits ou entrada legítimaConferir CS e parâmetros; comparar sinais quando disponível

Dica

I2C: fase e quantidade são independentes

Em uma leitura I2C normal de 2 bytes, o controlador confirma o primeiro byte com ACK porque ainda deseja outro byte. Após receber o segundo, emite NACK para encerrar a leitura. Esse NACK final previsto pelo protocolo não é falha.

Um NACK inesperado precisa ser localizado: ocorreu ao selecionar o endereço, ao enviar o registrador ou em outra fase? A fase orienta a conferência de endereço, alimentação e conexão.

Há outro caso: endereço reconhecido, mas apenas 1 dos 2 bytes esperados chega; o controlador pode emitir NACK após esse único byte para encerrar antecipadamente. O NACK pode ser um encerramento válido, mas a contagem de 1 de 2 torna a resposta inválida. Não monte nem converta dados parciais.

Verifique suas conclusões

Exemplo

Prática: indício e verificação

Associe cada indício à próxima verificação mais útil. Considere as associações como direção de investigação, não como confirmação definitiva da causa.

Relacione os indícios

Associe cada indício à próxima verificação mais útil. Considere as associações como direção de investigação, não como confirmação definitiva da causa.

Escreva pelo menos 80 caracteres (0/80).

Não confunda encerramento com resposta válida

Uma rotina I2C solicitou 2 bytes. O endereço foi reconhecido, mas somente o primeiro byte chegou. Para encerrar a tentativa, o controlador emitiu NACK após esse byte. Qual conclusão é correta?

Passo 5 de 10

Conferir os bytes antes de aceitar o valor

Compare bytes brutos, palavra montada e valor convertido para localizar erros de interpretação com vetores conhecidos.

Encontre a primeira divergência

Siga a cadeia de interpretação

Uma resposta já validada na transação ainda precisa passar por três conferências antes de ser aceita como medida:

  1. bytes brutos recebidos;
  2. palavra digital montada a partir deles;
  3. valor convertido para a unidade física.

Use uma resposta conhecida e compare cada etapa lado a lado. A primeira divergência orienta a investigação:

  • bytes diferentes do vetor esperado: investigue antes da interpretação;
  • bytes corretos, mas palavra errada: revise ordem dos bytes, máscara ou sinal;
  • palavra correta, mas valor errado: revise escala, referência assumida ou cálculo numérico.

Uma resposta completa e um número plausível não provam, isoladamente, que a interpretação está certa. Aqui, considere que a quantidade de bytes já foi validada: o foco é não atribuir ao transporte um erro que está na conversão.

Do byte ao valor físico

Diagrama mostra os bytes 0x01 e 0x90 formando a palavra 0x0190 e 25,0 °C; na ordem invertida, formam 0x9001 e levam a uma interpretação negativa incorreta para o vetor.

Compare bytes, palavra e valor: a primeira etapa diferente localiza a categoria do erro.

Teste com respostas conhecidas

Exemplo

Dois vetores de referência

No registrador de temperatura do MCP9808, use vetores conhecidos para testar a interpretação sem depender de uma nova medição física.

Vetor positivo: bytes 0x01 0x90 formam 0x0190. Os 12 bits de temperatura são 0x190 = 400. Com escala de 1/16 °C, o resultado é 25,0 °C.

Vetor negativo: bytes 0x1F 0x60 formam 0x1F60. Os 12 bits de temperatura são 0xF60 = 3936, ou 246,0 °C antes do ajuste. Como o bit 0x1000 está ativo, subtraia 256,0 °C: o resultado é −10,0 °C.

O bit de sinal não pede para negar diretamente os 12 bits. No formato do sensor, a conversão é: valor de 12 bits dividido por 16 e, se o bit 0x1000 estiver ativo, menos 256 °C.

Compare as etapas

A inversão dos bytes muda a palavra antes de qualquer cálculo de escala. Ela não é um problema de transporte se os bytes brutos coincidem com o registro recebido.

Os vetores conhecidos verificam ordem dos bytes, sinal e escala.
Bytes brutosPalavra montadaCálculoResultado esperado
0x01 0x900x0190400 / 1625,0 °C
0x1F 0x600x1F603936 / 16 − 256−10,0 °C
0x01 0x90 invertidos0x90011 / 16 − 256−255,9375 °C

Conversão no formato do MCP9808

A montagem da palavra e a conversão para temperatura são etapas distintas. Os sufixos .0f impedem divisão inteira e preservam a parte fracionária.

cpp
float interpretarTemperatura(uint8_t msb, uint8_t lsb) {
  uint16_t word = ((uint16_t)msb << 8) | lsb;
  float temperaturaC = (word & 0x0FFF) / 16.0f;

  if (word & 0x1000) {
    temperaturaC -= 256.0f;
  }

  return temperaturaC;
}

Pratique a conferência

Complete a interpretação

Complete a conversão. Ela deve retornar 25,0 para 0x01 0x90 e −10,0 para 0x1F 0x60. Os bytes já foram recebidos completos; avalie apenas a interpretação.

cpp
float interpretarTemperatura(uint8_t msb, uint8_t lsb) {
  uint16_t word = ((uint16_t)msb << 8) | lsb;
  float temperaturaC = (word & ) / ;

  if (word & 0x1000) {
    temperaturaC -= ;
  }
  return temperaturaC;
}

Localize a primeira divergência

O registro mostra bytes brutos 0x01 0x90, iguais ao vetor de 25,0 °C. Porém, o firmware registra palavra 0x9001 antes de calcular a temperatura. Qual é a causa mais diretamente indicada?

Passo 6 de 10

Separar valor, validade e idade

Represente valor, validade e idade como informações independentes para não confundir zero, ausência e histórico.

Modele o contexto da amostra

Três informações, três papéis

Uma leitura não é apenas um número. Para apresentá-la com segurança, mantenha três informações separadas:

  • valor: resultado numérico da última leitura aceita;
  • amostraValida: informa se já existe uma amostra aceita;
  • instanteAceito: marca de tempo da última atualização aceita.

Assim, 0 continua sendo uma medição possível. Ele não precisa significar “não recebi nada”.

Valor não informa validade nem idade

Diagrama com campos separados para valor, validade e instante, comparando amostra ausente, antiga e atual.

O mesmo valor numérico pode aparecer em estados diferentes; a validade e a idade dão o contexto.

Leia a linha do tempo corretamente

Tentativa atual não é amostra aceita

Use o limite de idade adequado à aplicação. Por exemplo, uma amostra pode ser considerada atual por até 2 segundos. A idade é calculada a partir da última leitura aceita, não do início da tentativa atual.

A tentativa em andamento ou recém-falha tem seu próprio estado. Ela não apaga, não valida novamente e não rejuvenesce a amostra anterior. Portanto, uma falha às 11 900 ms não torna atual uma amostra aceita às 9 000 ms.

Classifique cada situação

Considere agora = 12000 ms e um limite de idade de 2000 ms.

O valor só é exibido como leitura atual quando existe e está dentro do limite de idade.
SituaçãovaloramostraValidainstanteAceitoApresentação correta
Nenhuma leitura aceita—false—Ausente
Leitura aceita às 9000 ms0true9000 msAntiga: histórico 0
Leitura aceita às 10800 ms0true10800 msAtual: 0
Tentativa falhou às 11900 ms; última aceita às 9000 ms27,4true9000 msAntiga: histórico 27,4

Aceite antes de atualizar

Atualize somente no caminho aceito

Trecho para estudar: valor, amostraValida e instanteAceito só mudam depois que a resposta passa pelos critérios de aceitação. O estado da tentativa muda separadamente.

cpp
float valor = 0.0f;
bool amostraValida = false;
unsigned long instanteAceito = 0;

enum EstadoTentativa { AGUARDANDO, ACEITA, FALHOU };
EstadoTentativa estado = AGUARDANDO;

void tratarResposta(bool respostaAceita, float valorLido) {
  if (respostaAceita) {
    valor = valorLido;
    amostraValida = true;
    instanteAceito = millis();
    estado = ACEITA;
  } else {
    estado = FALHOU;
    // Não alterar valor, amostraValida ou instanteAceito.
  }
}

bool amostraAtual(unsigned long agora) {
  const unsigned long limiteIdade = 2000;
  return amostraValida && (agora - instanteAceito <= limiteIdade);
}

Dica

Apresente o estado de forma explícita

Após uma falha, mantenha o último valor apenas se ele for útil como histórico identificado. Mostre, por exemplo, “última leitura: 27,4 (antiga)”; não mostre “27,4” como se fosse uma leitura recém-obtida.

Se nenhuma amostra foi aceita, apresente “sem dado” em vez de inventar 0.

Pratique a separação dos estados

Prática: preserve a amostra anterior

Complete o caminho de aceitação de uma leitura. O bloco else deve preservar a última amostra aceita.

cpp
if (respostaAceita) {
  valor = ;
  amostraValida = ;
  instanteAceito = ;
  estado = ACEITA;
} else {
  estado = FALHOU;
}

Verifique a classificação

Relacione cada condição à classificação correta.

Toque em um item e depois no par correspondente.

Passo 7 de 10

Limitar esperas e novas tentativas

Defina tentativas com prazo, intervalo e encerramento explícito, sem esperas ou novas tentativas ilimitadas.

Definir os limites da operação

Uma política que termina

Uma operação de leitura precisa terminar em sucesso ou em falha explícita. Defina quatro elementos:

  • prazo por tentativa: quanto tempo uma tentativa pode permanecer em andamento;
  • máximo total de tentativas: inclui a primeira tentativa;
  • intervalo entre tentativas: espera antes de repetir após uma falha;
  • estado final de falha: destino quando o limite se esgota.

Use uma convenção sem ambiguidade: MAX_TENTATIVAS = 3 significa, no máximo, as tentativas 1, 2 e 3. Se a terceira não for aceita, a operação termina em FALHOU.

O contador pertence à operação em curso. Ele é zerado quando um evento explícito solicita uma nova leitura, e não a cada passagem pelo loop(). Sucesso ou falha encerram a operação atual.

Tentativas delimitadas

Diagrama de uma primeira tentativa iniciada imediatamente, seguido de até duas repetições separadas por intervalos e com saídas para sucesso ou falha.

A primeira tentativa começa com o evento; o intervalo existe somente entre tentativas.

Atenção

Dois limites independentes

Os limites são independentes:

  • O máximo de tentativas impede que a operação recomece para sempre.
  • O prazo por tentativa impede esperar para sempre dentro de uma tentativa.

Um laço externo com três repetições não ajuda se a primeira chamada de comunicação puder esperar indefinidamente por bytes. O prazo só é real quando a função chamada pode retornar: por exemplo, porque a API documenta um timeout configurável ou porque a arquitetura inicia a solicitação e depois consulta seu estado.

Não presuma que toda biblioteca oferece isso. Se uma chamada síncrona não tem timeout documentado, não a apresente como espera limitada nem construa sobre ela uma política não bloqueante.

Agendar cada tentativa

Primeira tentativa imediata; repetições agendadas

Neste exemplo, a comunicação segue uma arquitetura por consulta: iniciarConsulta() dispara a solicitação e retorna rapidamente; consultarResposta() informa depois se ela está pendente, completa ou inválida.

A primeira tentativa começa diretamente quando ocorre o evento. Somente depois de uma tentativa inválida ou vencida é aplicado INTERVALO_MS antes da próxima. Assim, o loop() continua atendendo as demais tarefas entre consultas e entre tentativas.

Este modelo exige que a interface, a biblioteca ou uma camada já existente no firmware realmente ofereça esse comportamento. Em uma API exclusivamente síncrona, use apenas um timeout documentado e reconheça que a chamada ocupará o processador até retornar.

Agendar sem bloquear o loop

Esqueleto para estudar. Como consultarResposta() não informa o instante em que a resposta chegou, uma resposta observada depois do prazo é rejeitada. O prazo é verificado antes de aceitar COMPLETA.

cpp
enum EstadoLeitura {
  OCIOSA,
  EM_ANDAMENTO,
  ESPERANDO_REPETICAO,
  FALHOU
};

enum ResultadoConsulta { PENDENTE, COMPLETA, INVALIDA };

const byte MAX_TENTATIVAS = 3;  // inclui a primeira
const unsigned long PRAZO_MS = 40;
const unsigned long INTERVALO_MS = 200;

EstadoLeitura estado = OCIOSA;
byte tentativas = 0;
unsigned long inicioTentativa = 0;
unsigned long inicioIntervalo = 0;

void iniciarProximaTentativa(unsigned long agora) {
  tentativas++;
  iniciarConsulta();  // deve retornar rapidamente
  inicioTentativa = agora;
  estado = EM_ANDAMENTO;
}

void solicitarNovaLeitura(unsigned long agora) {
  if (estado != OCIOSA && estado != FALHOU) return;

  tentativas = 0;
  iniciarProximaTentativa(agora);  // tentativa 1, sem intervalo inicial
}

void agendarOuFalhar(unsigned long agora) {
  if (tentativas >= MAX_TENTATIVAS) {
    estado = FALHOU;
  } else {
    inicioIntervalo = agora;
    estado = ESPERANDO_REPETICAO;
  }
}

void atualizarLeitura(unsigned long agora) {
  if (estado == ESPERANDO_REPETICAO &&
      agora - inicioIntervalo >= INTERVALO_MS) {
    iniciarProximaTentativa(agora);
  }

  if (estado != EM_ANDAMENTO) return;

  // Sem instante de chegada fornecido pela API, não aceite após o prazo.
  if (agora - inicioTentativa >= PRAZO_MS) {
    agendarOuFalhar(agora);
    return;
  }

  ResultadoConsulta resultado = consultarResposta();
  if (resultado == COMPLETA) {
    aceitarNovaAmostra();
    estado = OCIOSA;
  } else if (resultado == INVALIDA) {
    agendarOuFalhar(agora);
  }
}

Dica

Prazo antes da aceitação

A ordem da verificação temporal é importante. Neste modelo, COMPLETA significa apenas “a resposta foi observada agora”; ela não traz o instante em que chegou. Por isso, se o prazo já venceu quando o programa consulta o resultado, a resposta é rejeitada e a política segue para repetição ou falha.

Uma API que informe o instante de conclusão pode permitir outro critério: aceitar somente se esse instante estiver dentro do prazo. Sem essa evidência, não afirme que uma resposta tardia foi recebida a tempo.

Verificar os três limites

Prática: política completa de repetição

Complete o trecho derivado da máquina de estados. As lacunas devem: liberar a repetição após o intervalo, detectar o prazo da tentativa atual, reconhecer o limite total e realmente agendar a próxima tentativa quando ainda houver uma disponível.

Complete prazo, intervalo e limite

Complete as três constantes. O caminho else já mostra o agendamento efetivo da próxima tentativa.

cpp
if (estado == ESPERANDO_REPETICAO &&
    agora - inicioIntervalo >= ) {
  iniciarProximaTentativa(agora);
}

if (estado == EM_ANDAMENTO &&
    agora - inicioTentativa >= ) {
  if (tentativas >= ) {
    estado = FALHOU;
  } else {
    inicioIntervalo = agora;
    estado = ESPERANDO_REPETICAO;
  }
}

Reconhecer políticas que não terminam

Identifique o falso limite

Qual política ainda pode repetir indefinidamente, apesar de declarar MAX_TENTATIVAS = 3?

Confira a duração da chamada

Qual situação ainda pode bloquear o firmware, mesmo com um contador externo de três tentativas?

Passo 8 de 10

Confirmar a recuperação antes de retomar

Recupere a aquisição de modo controlado e retome a operação somente após uma nova leitura validada.

Recuperação dirigida e limitada

Recuperar não é reiniciar sem critério

Uma recuperação começa pela camada já diagnosticada. Reiniciar uma interface pode ser apropriado diante de uma falha de transação, mas não corrige uma máscara, ordem de bytes, sinal ou escala errada no firmware.

Antes de agir, encerre a tentativa que falhou. Bytes parciais e respostas chegadas depois do prazo não podem ser promovidos a resposta da próxima tentativa. Trate ou descarte esses dados conforme as regras da interface e preserve a última amostra aceita com seu instante original.

A ação deve corresponder à camada

Diagrama de camadas mostrando sinal físico, transação, bytes brutos e valor interpretado, com uma ação de recuperação direcionada a apenas uma camada.

Uma ação na comunicação não corrige, por si só, um erro de interpretação do dado.

Dica

Os limites continuam valendo

Restaure uma configuração ou reinicialize um dispositivo somente pelo procedimento documentado para o dispositivo e a biblioteca usada. Não invente pulsos, desligamentos ou comandos para “forçar” uma resposta.

Depois da ação, faça outra operação com prazo por tentativa, limite total de tentativas e estado final explícito. A recuperação também precisa terminar: não transforme falhas repetidas em um ciclo infinito de reinicializações.

Evidência para retomar

Exemplo

Caso: recuperação após leitura incompleta

Uma leitura I2C esperava 2 bytes, mas recebeu somente 1. A tentativa foi encerrada, o byte isolado não foi convertido e a última temperatura aceita permaneceu identificada como histórico, com seu instante original.

Foi executado o procedimento documentado de reinicialização da interface. Em seguida, a aplicação inicia uma nova leitura, sujeita ao prazo e ao limite de tentativas definidos. A reinicialização, isoladamente, ainda não é evidência de recuperação.

Exija uma nova leitura aceita

Qual evidência permite que a aplicação retome a operação normal?

Ordem sem aceitar dados antigos

Prática: ordene a recuperação

Organize o procedimento para uma tentativa que não recebeu todos os bytes esperados. Considere que já existe uma camada diagnosticada e uma ação de recuperação documentada para ela.

Sequência de recuperação

Coloque as ações na ordem de uma recuperação controlada.

  1. Encerrar a tentativa e rejeitar dados parciais ou atrasados.
  2. Aplicar a ação de recuperação documentada para a camada diagnosticada.
  3. Iniciar uma nova verificação com prazo e limite de tentativas.
  4. Retomar a operação normal ou permanecer em falha explícita, conforme o resultado.
  5. Aceitar a nova leitura somente se ela cumprir todos os critérios de validação.

Falha explícita também é resultado

Retomar ou permanecer em falha?

Após uma reinicialização documentada, a tentativa 1 vence o prazo. A tentativa 2 recebe apenas 1 dos 2 bytes esperados. O limite total da recuperação foi atingido. Qual decisão está correta?

Atenção

Regra de retomada

A regra de retomada é: encerrar a tentativa anterior → ação adequada à camada → nova verificação limitada → nova leitura válida ou falha explícita.

Não trate a reinicialização, uma resposta parcial ou uma resposta tardia como confirmação de recuperação. Se houver valor anterior, apresente-o como histórico identificado, nunca como leitura atual.

Passo 9 de 10

Planejar testes de falha sem danificar a montagem

Planeje uma falha de comunicação controlada, segura e reversível para verificar detecção, limite de tentativas e recuperação.

Planeje antes de alterar

Um teste que realmente informa

Um teste de falha útil é reversível: ele cria uma condição prevista, permite observar a reação do firmware e permite restaurar a operação sem expor a montagem a uma condição elétrica perigosa.

Planeje antes de testar:

  1. Hipótese: o que a ausência ou a resposta incompleta deve acionar?
  2. Condição inicial: qual é a última amostra válida e seu instante?
  3. Uma alteração: qual resposta será omitida ou truncada?
  4. Resultado esperado: timeout, tentativas limitadas e estado de falha.
  5. Critério de interrupção: quando parar e restaurar a condição normal?

Mude somente uma variável por teste. Assim, o resultado pode sustentar ou enfraquecer uma hipótese específica.

Fluxo de um teste reversível: operação normal, omissão controlada de resposta, timeout e tentativas limitadas, falha explícita e retorno após uma resposta válida.

O teste deve verificar tanto a detecção da falha quanto a aceitação de uma nova amostra após restaurar a resposta.

Preveja o que deve acontecer

Caso para análise sem equipamento

Você pode testar a lógica sem desconectar nada. Considere este caso apresentado:

  • A última leitura aceita foi 24,50 °C no instante 10 000 ms.
  • Cada tentativa espera no máximo 50 ms por 2 bytes.
  • A política permite 1 tentativa inicial + 2 novas tentativas.
  • Uma leitura só é aceita com exatamente 2 bytes.

Durante o teste, a sequência simulada é: nenhuma resposta; 1 byte; nenhuma resposta. Depois, a resposta normal de 2 bytes é restaurada.

Previsão da sequência

O valor anterior permanece apenas como histórico identificado; ele não se torna leitura atual.
EtapaResposta recebidaEfeito esperado
Tentativa 10 bytes até 50 msTimeout; não atualizar valor nem instante
Tentativa 21 byteRejeitar como incompleta; não converter
Tentativa 30 bytes até 50 msEncerrar em falha explícita
Após restaurar2 bytes válidosAceitar nova amostra e renovar instante

Mantenha o teste seguro

Atenção

Montagem própria: condição obrigatória

Em uma montagem própria, prefira testes lógicos controlados pelo firmware ou a análise do caso apresentado. Se for necessário alterar uma conexão para simular ausência de resposta, faça isso somente com todas as fontes desligadas: USB, fonte externa, bateria e qualquer alimentação vinda de outro equipamento.

Antes de religar, confira a conexão conforme a documentação do módulo. Após restaurá-la, a recuperação só foi confirmada se uma nova leitura válida for aceita dentro dos limites definidos.

Atenção

Falhas destrutivas não são teste

Não crie falhas por curto-circuito, sobretensão ou união de duas saídas que possam dirigir níveis opostos. Esses métodos podem danificar componentes e não são necessários para verificar timeout, rejeição de resposta incompleta ou recuperação.

Registre também a origem da evidência: “sequência analisada no tutorial” não é o mesmo que “medição realizada na minha montagem”. Uma observação local pode depender da versão da biblioteca, do dispositivo e das condições da montagem.

Verifique sua previsão

Planeje e registre o teste

Usando o caso apresentado, descreva um registro curto do teste. Inclua: a hipótese, a alteração única aplicada, o que deve acontecer com o valor e o instante da última amostra durante as três tentativas, o estado final esperado e a evidência que confirmaria a recuperação após restaurar a resposta.

Não é preciso possuir equipamento: baseie-se na sequência fornecida.

Escreva pelo menos 180 caracteres (0/180).

Passo 10 de 10

Concluir e documentar um diagnóstico completo

Aplique um roteiro completo de diagnóstico a registros de operação, falha e recuperação controlada.

Leia o caso como uma sequência de estados

Um caso para fechar o diagnóstico

Caso integrado: temperatura por I2C

Uma aplicação usa um MCP9808. Às 10:00:00, a última leitura aceita foi 25,00 °C. Às 10:00:10, uma nova aquisição falhou: cada tentativa recebeu NACK na seleção do endereço; portanto, não houve bytes de temperatura nem conversão válida.

A política já definida permite 3 tentativas no total (a inicial mais 2 novas), com prazo de 20 ms por tentativa e intervalo de 200 ms. Depois do terceiro NACK, o sistema entra em falha explícita.

A conexão do módulo foi conferida e restaurada somente com todas as fontes desligadas. Após religar, uma leitura nova foi aceita às 10:00:14. Seu trabalho é transformar esses fatos em uma conclusão rastreável — sem chamar a amostra de 10:00:00 de leitura atual durante a falha.

Linha do tempo com leitura válida, três tentativas I2C com NACK, intervenção segura e nova leitura válida.

A falha atual não renova nem invalida silenciosamente a marca de tempo da última amostra aceita.

Separe fatos, interpretação e decisão

Evidências fornecidas

Compare os registros pelo que eles realmente comprovam. NACK durante a seleção do endereço é um indício de transação sem resposta naquele ponto; ele não autoriza inventar bytes, converter um valor ou substituir a ausência por zero.

Registro resumido do caso. Os traços indicam informação indisponível, e não valor zero.

Apenas a leitura posterior à recuperação pode renovar valor, validade e instante da última amostra aceita.
InstanteEventoBytes brutosValorDecisão
10:00:00Leitura I2C OK01 9025,00 °CAceita; última amostra
10:00:10Tentativas 1, 2 e 3: NACK——Falha explícita após limite
10:00:12Conexão restaurada sem alimentação——Ação segura; ainda não confirma recuperação
10:00:14Leitura I2C OK01 9125,06 °CAceita; atualiza amostra e instante

Decisão fundamentada

A intervenção é uma hipótese testada, não a prova final. A evidência de recuperação é a nova transação completa aceita às 10:00:14. Durante a falha, a aplicação pode preservar 25,00 °C como histórico identificado, mas deve informar que a última atualização aceita foi às 10:00:00 e que a tentativa atual falhou.

Documente a cadeia de decisão

Aplique o roteiro ao caso

Escreva um registro de diagnóstico de 5 a 8 linhas para o caso. Inclua: sintoma; hipótese compatível com os NACKs; evidência que a sustenta; teste/intervenção segura; resultado; limite de tentativas; tratamento da amostra de 10:00:00; e critério que permitiu retomar a operação.

Não é necessário inventar uma causa elétrica específica: registre o que os dados permitem concluir.

Revise e encerre

Roteiro reutilizável

Use este roteiro curto antes de mudar configurações ou iniciar uma recuperação.
EtapaPergunta de controle
SintomaO que foi observado, sem atribuir causa?
HipóteseEm qual camada a causa pode estar?
EvidênciaQue observação diferencia hipóteses?
Teste seguroQual alteração única e reversível será feita?
LimiteQuando a tentativa termina em falha explícita?
RetomadaQual nova leitura válida confirma a recuperação?

Resumo

Síntese final

  • Registre separadamente o sintoma, a hipótese, a evidência, o teste e a decisão.
  • Bytes ausentes e valor não convertido devem permanecer indisponíveis; nunca se tornam zero por conveniência.
  • Uma tentativa falha não atualiza o instante da última amostra aceita.
  • Defina prazo por tentativa, total máximo e estado final de falha.
  • Uma ação de recuperação só é confirmada por uma nova leitura que satisfaça os critérios de aceitação.

Tutorial concluído

Parabéns! Você concluiu: Diagnóstico de aquisição e falhas de comunicação

Diagnóstico concluído: evidência antes de suposição, falha explícita antes de repetição infinita e retomada somente após leitura válida.

Baixe o Aplicativo agora para ter acesso a + de 5000 cursos gratuitos, exercícios, certificado e muito conteúdo sem pagar nada!

  • Cursos online 100% gratuitos do início ao fim

    Milhares de cursos online em vídeo, ebooks e áudiobooks.

  • Mais de 60 mil exercícios gratuitos

    Para testar seus conhecimentos no decorrer dos cursos online

  • Certificado Digital gratuito válido em todo o Brasil

    Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail

Aplicativo Cursa na tela de ebook, na tela de curso em vídeo e na tela de exercícios do curso, mais o certificado de conclusão de curso