Mi experiencia conectando LPS331AP a Omega Onion2

¡Buen día, Habrovsk!

Breve introducción


El otro día, me convertí en el feliz propietario de uno de los pagadores individuales más pequeños que trabajaban en LEDE, y lo primero que quería hacer (después de parpadear el LED) era una estación meteorológica doméstica, a la que se puede acceder desde cualquier lugar. El primer paso fue tomar datos sobre temperatura, humedad y presión. Para esto, se seleccionaron los sensores DHT11 y LPS3311AP adquiridos anteriormente (foto debajo del corte).

Fotos para los interesados
imagen

Después de una breve búsqueda en Google, resultó que si la primera familia está bien documentada y tiene muchas bibliotecas para trabajar, entonces el barómetro que elegí no es tan popular, excepto por la biblioteca autoescrita (aunque de muy alta calidad) para la tienda Arduino donde se compró el sensor (no publicidad, solo un tributo), no se pudo encontrar nada.

¿Qué opción queda?

  1. Recoja la capa en el microcontrolador ATmega328, actualícela, complete el código terminado y lea de ella. Muy emocionante, pero suena como tratar de armar una bicicleta para usarla más tarde como una muleta.
  2. Lea "manualmente" con I2C, confiando en la hoja de datos oficial . Lo intenté, es posible, pero no quería producir scripts de bash y no parecía metodológicamente correcto.
  3. Escriba una biblioteca para trabajar con el sensor de la manera que desee.

Si está interesado en cómo surgió y qué surgió, entonces bienvenido a cat.

La primera pregunta que encontré es la elección del idioma. De lo que funciona en este tablero único sin bailar con una pandereta: C ++ y Python. Como en el futuro quiero poner este proyecto en el corazón de un hogar inteligente para mí, la elección recayó en este último.

Debido al efecto de patito, no planteé la siguiente pregunta (qué versión) e inmediatamente puse el ligero python3 y la biblioteca para trabajar con el bus I2C.

Luego hubo horas de fumar, primero una hoja de datos , luego una guía de software del fabricante. Permitieron preparar rápidamente el sensor para la operación (aunque la guía del software resultó ser más completa, incluso en relación con las recomendaciones para verificar la finalización de la medición y "reiniciar" el sensor para una recolección más precisa.

La primera dificultad que encontré es leer datos. Dado que los datos del termómetro se transmiten en dos bytes y la presión en tres, es necesario obtener varios bytes y combinarlos en un gran número. Pero python convertirá hexadecimal a int por defecto, y la concatenación simple no funciona. La conversión de int a hexadecimal devuelve una cadena que está perfectamente concatenada pero no convertida de nuevo a un número. Salida? Sería posible conectar el soporte para c-types, pero no quería perder el tiempo, así como obstruir la memoria con una biblioteca adicional, por lo que se decidió escribir una función en 7 (en realidad 8, si contamos el diccionario) líneas para traducir la cadena de pseudobyte a un número.

Hex que contiene cadena a 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 

Creo que la pregunta "¿por qué leer del diccionario?" Puede hacerse razonablemente aquí. La respuesta es simple: no se me ocurrió tomar decisiones obvias sobre la conversión de tipos, si los expertos tienen una respuesta a esta pregunta, me complacerá hacer cambios.

La segunda dificultad que me desconcertó es la interpretación de los datos. Los dos documentos anteriores dan fórmulas muy simples para la conversión:

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

Lo que agrada, inmediatamente ofrecen un sistema métrico.

Sin embargo, el primer enfoque obstinadamente me dio el resultado 0x2F8000, lo que significa 760 milibares o aproximadamente 585 mmHg. Art. Para una altura de 130 metros sobre el nivel del mar, esto claramente no es suficiente. Volver a verificar el código, volver a leer la información sobre la medición de presión, reiniciar el sensor y jugar con precisión no dio nada. Pero el estudio repetido de la guía ayudó: la estabilidad de 760 mbar se interpreta como una señal de que el sensor está defectuoso. Los lectores que miraron atentamente la foto adjunta al principio del artículo pueden asegurarse de que el sensor, además, esté en principio ausente en el chip :) Afortunadamente, compré rápidamente dos de ellos a la vez.

Foto de un chip en funcionamiento y funcionamiento correcto


El pequeño cuadrado negro en el centro es la placa de medición HCLGA-16L, el "corazón" del sensor.

imagen

Después de este descubrimiento, se hizo obvio que se debería hacer un control de salud. Entonces nació la función:

comprobación de trabajo
 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 un caso raro, pero aún potencialmente probable, de falsos positivos, las lecturas se toman tres veces y solo después de eso se emite un veredicto de inoperancia. Es posible usar excesivamente una constante en dicho código, pero se debe observar un buen tono siempre que sea posible.

Inmediatamente se me ocurrió una idea de que no sería malo durante la inicialización verificar si la dirección en el bus es correcta, y se agregó la función __deviceAdressCheck , que verifica el registro WHO_AM_I y espera recibir el querido número 0xBB.

En esto, al parecer, no hay más puntos interesantes. El código completo está disponible en el github y está disponible para su uso y modificación.

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


All Articles