Minha experiência conectando o LPS331AP ao Omega Onion2

Bom dia, Habrovsk!

Breve introdução


Outro dia, tornei-me o feliz proprietário de um dos menores jogadores de placa única trabalhando no LEDE, e a primeira coisa que eu queria fazer (depois de piscar o LED) foi uma estação meteorológica doméstica, que pode ser acessada de qualquer lugar. O primeiro passo foi coletar dados de temperatura, umidade e pressão. Para isso, foram selecionados os sensores DHT11 e LPS3311AP adquiridos anteriormente (foto sob o corte).

Fotos para os interessados
imagem

Após uma breve pesquisa, verificou-se que, se a primeira família está bem documentada e tem muitas bibliotecas para trabalhar, o barômetro que eu escolhi não é tão popular, exceto pela biblioteca auto-escrita (embora de alta qualidade) para a loja do Arduino onde o sensor foi comprado (não para publicidade, apenas uma homenagem), nada foi encontrado.

Que escolha resta?

  1. Colete a camada no microcontrolador ATmega328, faça flash, preencha o código final e leia a partir dele. Muito emocionante, mas parece tentar montar uma bicicleta para uso posterior como muleta.
  2. Leia "manualmente" com o I2C, confiando na folha de dados oficial . Tentei, é possível, mas não queria produzir scripts bash e não parecia metodologicamente correto.
  3. Escreva uma biblioteca para trabalhar com o sensor da maneira que desejar.

Se você está interessado em como veio e no que veio, então seja bem-vindo ao gato.

A primeira pergunta que me deparei é a escolha do idioma. Pelo que funciona neste quadro único sem dançar com um pandeiro - C ++ e Python. Como no futuro quero colocar esse projeto no coração de uma casa inteligente para mim, a escolha recaiu sobre o último.

Devido ao efeito de patinho, não levantei a próxima pergunta (qual versão) e imediatamente coloquei o python3 leve e a biblioteca para trabalhar com o barramento I2C.

Depois, houve horas de fumar, primeiro uma folha de dados , depois um guia de software do fabricante. Eles tornaram possível preparar rapidamente o sensor para operação (embora o guia do software tenha sido mais completo, incluindo recomendações para verificar a conclusão da medição e "redefinir" o sensor para obter uma coleta mais precisa.

A primeira dificuldade que encontrei é a leitura de dados. Como os dados do termômetro são transmitidos em dois bytes e a pressão em três, é necessário obter vários bytes e combiná-los em um número grande. Mas o python converterá hex para int por padrão, e a concatenação simples não funciona. A conversão de int em hexadecimal retorna uma sequência perfeitamente concatenada, mas não convertida novamente em um número. Saída? Seria possível conectar o suporte para c-types, mas eu não queria mexer, além de entupir a memória com uma biblioteca adicional, por isso foi decidido escrever uma função em 7 (na verdade 8, se contarmos o dicionário) linhas para traduzir a sequência de pseudo-bytes para um número.

Hex contendo string para int
s_t_h = { '0' : 0, '1' : 1, '2' : 2, '3' : 3, '4' : 4, '5' : 5, '6' : 6, '7' : 7, '8' : 8, '9' : 9, 'a' : 10, 'b' : 11, 'c' : 12, 'd' : 13, 'e' : 14, 'f' : 15 } def __string_to_int(self, hex_string): l = len(hex_string) - 1 res = 0 for h in hex_string: res += s_t_h[h] * (16 ** l) l -= 1 return res 

Acredito que a pergunta “por que ler no dicionário?” Pode ser feita aqui. a resposta é simples - não me ocorreu tomar decisões óbvias sobre a conversão de tipos; se os especialistas tiverem uma resposta para essa pergunta, terei o prazer de fazer alterações.

A segunda dificuldade que me intrigou é a interpretação dos dados. Ambos os documentos acima fornecem fórmulas muito simples para conversão:

Pout(mbar)=(PRESS_OUT_H & PRESS_OUT_L & PRESS_OUT_XL)[dec] / 4096 para pressão;
T(degC) = 42.5 + (Temp_OUTH & TEMP_OUT_L)[dec] / 480 para temperatura.

O que agrada, eles oferecem imediatamente um sistema métrico.

No entanto, a primeira abordagem teimosamente me deu o resultado 0x2F8000, o que significa 760 milibares ou cerca de 585 mmHg. Art. Para uma altura de 130 metros acima do nível do mar, isso claramente não é suficiente. Verificar novamente o código, reler as informações sobre a medição da pressão, reiniciar o sensor e jogar com precisão não deu nada. Mas o estudo repetido da diretriz ajudou - 760 mbar estável é interpretado como um sinal de que o sensor está com defeito. Os leitores que examinaram cuidadosamente a foto anexada no início do artigo podem garantir que o sensor, além disso, esteja em princípio ausente no chip :) Felizmente, eu rapidamente comprei duas delas ao mesmo tempo.

Foto de um chip de trabalho e operação adequada


O pequeno quadrado preto no centro é a placa de medição HCLGA-16L, o "coração" do sensor.

imagem

Após essa descoberta, ficou óbvio que uma verificação de saúde deveria ser feita. Então a função nasceu:

working_check
 BROKEN_MARKER = 0x2f8000/4096 def __working_check(self, address): c1 = self.__read_pressure(address) c2 = self.__read_pressure(address) c3 = self.__read_pressure(address) if c1 == c2 == c3 == BROKEN_MARKER: return True else: return False 

Para evitar um caso raro, mas ainda potencialmente provável, de falsos positivos, as leituras são feitas três vezes e somente depois é emitido um veredicto de inoperabilidade. É possível usar excessivamente uma constante nesse código, mas um bom tom deve ser observado sempre que possível.

Imediatamente me ocorreu que não seria ruim durante a inicialização verificar se o endereço no barramento está correto e a função __deviceAdressCheck foi adicionada, que verifica o registro WHO_AM_I e espera receber o número estimado 0xBB.

Parece que não há mais pontos interessantes sobre isso. O código completo está disponível no github e está disponível para uso e modificação.

Source: https://habr.com/ru/post/pt471232/


All Articles