27 de outubro de 2021

Do bit Ao Byte

Embarcados, Linux e programação

Laboratório Maker 02: Leitura do BMP180 com Bus Pirate

Sniffer de barramentos | open drain | sniffing I2C com Bus Pirate

Será o último artigo da série com essa ferramenta? “Por enquanto” sim, mas se tem acompanhado desde o primeiro artigo, saiba que há muito ainda a tratar sobre esse dispositivo. Nessa primeira série focamos em uma boa apresentação e no scan e sniffing do barramento I2C. Agora vamos fechar a sequência com a leitura do BMP180 com Bus Pirate.

Se ainda não tem um BMP180, dê uma passada na CurtoCircuito, eles têm uma quantidade enorme de sensores.

Preparando o ambiente

Não se preocupe, nada de repetições. Se leram os artigos anteriores, sabem bem o que significa cada uma das flags. Agora vou apenas citar os passos para:

Entrar em modo I2Cm, 4, 3
Levantar o pull-upP
Ligar a alimentação pelo Bus Pirate para o BMP180W
Checar tensõesv
Conectar o VCC ao BMP180físicamente
Consultar o endereço do dispositivo(0), (1)

Repetir comandos

Podemos usar “:” para repetir um valor. Por exemplo, repetir 3 vezes o 2:

leitura do BMP180 - endereço do dispositivo

Conversão de base numérica

Uma ferramenta do Bus Pirate que pode ser muito útil dependendo da situação é a conversão de base numérica. Para tal, usamos o sinal de igualdade seguido do valor em qualquer base. O endereço do BMP180 encontrado foi 0x77. Qual o valor dele em binário ou decimal? Simples, basta digitar:

= 0x77

O resultado será:

conversão de base numérica no Bus Pirate

Inversão de ordem dos bits

Para inverter a ordem dos bits, usa-se pipe:

|0b00000010

Invés de 2, o resultado será 64:

Leitura do BMP180

A leitura pode ser feita de um ou vários bytes de uma vez. Cada recepção é um ACK, e a finalização é com NACK. Para essa leitura, podemos fazer:

[0xEF r r r:3]

Como não tem nada no buffer para ser lido, o retorno deve ser 0:

leitura do BMP180 - buffer vazio

A flag r lê um único byte, enquanto r:3 lê múltiplos bytes.

Quando finalizarmos a leitura do sensor,voltamos  ao modo de alta impedância para tudo voltar à configuração inicial; alta impedância, sem alimentação e sem pullup:

m
1

Agora vamos à bendita leitura.

Lendo a temperatura no BMP180

Me desculpem, mas não vou fazer a leitura e cálculos completos. Se quiserem ler mais dados, recomendo o artigo “Barômetro BMP180 com Raspberry“, no qual escrevi um programa em Python para ler o BMP180 no Raspberry em 2014, e nele estão todos os cálculos a partir das leituras. Vamos ver só algumas dessas leituras para ter algum conceito.

Para enviar o start bit usamos “[” e para enviar o stop bit usamos “]“. O endereço padrão do módulo é 0x77, e para leitura e escrita pode-se ver com a macro (1):

Instruções de escrita com 0xEE e instruções de leitura com 0xEF. O datasheet diz para lermos os dados de calibração. No programa é bem mais fácil, pois já armazenamos em variáveis e depois só aplicamos as fórmulas de cálculo. Leia o artigo supracitado para ver esses detalhes, mas veja a leitura de 2 registradores de calibração utilizados no cálculo da temperatura:

registradores de calibração do bmp180

Vamos ler os registradores mas não vamos aplicar cálculo. São 2 words cada variável, sendo que o datasheet diz para pegar o MSB, deslocar para a esquerda e adicionar o LSB:

leitura descompensada da temperatura no bmp180

Repare na temperatura. A instrução é: “ESCREVA 0x2E para 0xF4 e aguarde 4.5ms” (mínimo)

Olhe a terceira imagem de baixo para cima. A instrução de escrita é 0xEE. Vamos escrever então 0x2E para 0xF4:

[0xEE 0x2E 0xF4

Repare que não tem o stop bit, porque temos que aguardar, então ler 0xF6 e 0xF7:

[0xEE 0xF6 0xF7]

Mas por que escrevemos de novo? – Simples: estamos informando quais endereços serão lidos. Repare também que agora mandamos o stop bit, porque essa sequência foi finalizada. Agora os valores são armazenados e lidos de 0xEF:

[0xEF r:2]

Temos então os valores 0x80 e 0x00 na leitura descompensada.

Pra calcular a temperatura:

X1 = (UT - AC6) * AC5 /2^15
X2 = MC* 2^11 / (X1 * MD)
B5 = X1 + X2
T = (B5*8)/2^4

Por isso que não quero fazer manualmente. Eu até coletei uns valores, mas apenas com o intuito de mostrar no artigo mesmo.

[0xEE 0x2E 0xF4 #escreve os valores
[0xEE 0xF6 0xF7] #condicao de escrita
[0xEF r:2] # condicao de leitura e le

resultado: 0x80 0x00

[0xEE 0xB4]
[0xEF r]
[0xEE 0xB2]
[0xEF r]
#0xB4 = 0x37
#0xB2 = 0x63

Eis o print de uma das leituras:

leitura do BMP180
leitura do BMP180

Vídeo

No vídeo mostro a preparação do ambiente e a leitura de 2 registradores, só pra não passar em branco. Fazer “tudo” manualmente é insano, mas fazer uma leitura comprova o funcionamento.

Com esse artigo, finalizamos a série de leitura I2C com Bus Pirate. Aguardem boas novas em breve!

 

Revisão: Ricardo Amaral de Andrade