Cámara termográfica de bricolaje en Raspberry PI o "Ahora creo que sé lo que haré este verano"

imagen

Hola a todos!

Ha llegado el invierno, y con él la tarea es verificar las propiedades de aislamiento térmico de los edificios de la residencia de campo de la dacha. Y luego resultó que en el conocido sitio chino aparecían módulos de imagen térmica bastante asequibles. ¿Es posible ensamblar una cosa exótica y, posiblemente, incluso útil, una cámara termográfica casera? Por qué no, como si Raspberry estuviera acostado en alguna parte ... Lo que sucedió - Te lo diré debajo del corte.

MLX90640. Que es esto


Y esto, de hecho, es una matriz de imagen térmica con un microcontrolador a bordo. Producción de la empresa previamente desconocida Melexis. La matriz de imagen térmica tiene una dimensión de 32 por 24 píxeles. Esto no es mucho, pero al interpolar la imagen, parece ser suficiente para al menos ver algo.

imagen

El sensor está disponible en dos versiones, cuyos casos difieren en el ángulo de visión de la matriz. Una estructura más achaparrada A pasa por alto el mundo exterior en un ángulo de 110 (horizontal) a 75 grados (vertical). B - menos de 55 por 37.5 grados, respectivamente. La caja del dispositivo tiene solo cuatro salidas: dos para la alimentación, dos para comunicarse con el dispositivo de control a través de la interfaz I2C. Las hojas de datos interesantes se pueden descargar aquí .

¿Y entonces qué es el GY-MCU90640?


Los camaradas chinos incorporaron el MLX90640 con otro microcontrolador (STM32F103). Aparentemente, para una gestión de matriz más fácil. Toda esta granja se llama GY-MCU90640. Y cuesta en el momento de la adquisición (finales de diciembre de 2018) en la región de 5 mil rublos. Se ve así:

imagen

Como puede ver, hay dos tipos de placas, con una versión estrecha o gran angular del sensor a bordo.

¿Qué versión es mejor para ti? Una buena pregunta, desafortunadamente, la tuve solo después de que el módulo ya fue ordenado y recibido. Por alguna razón, en el momento de la orden, no presté atención a estos matices. Pero en vano.

Una versión más amplia será buena en robots autopropulsados ​​o en sistemas de seguridad (el campo de visión será mayor). Según la hoja de datos, también tiene menos ruido y mayor precisión de medición.

imagen

Pero para las tareas de visualización, prefiero recomendar una versión más "de largo alcance" de B. Por una razón muy importante. En el futuro, cuando se dispara, puede desplegarse (manualmente o en una plataforma con una unidad) y tomar "fotos" compuestas, aumentando así la resolución más que modesta de 32 por 24 píxeles. Recopile imágenes térmicas de 64 por 96 píxeles, por ejemplo ... Bueno, está bien, en el futuro las fotos serán de la versión de gran angular A.

Conéctese a Raspberry PI


Hay dos formas de controlar el módulo de imagen térmica:

  1. Acorte el puente "SET" en la placa y use I2C para contactar directamente al microcontrolador MLX90640 interno.
  2. Deje el puente solo y comuníquese con el módulo a través de una interfaz similar instalada en la placa STM32F103 a través de RS-232.

Si escribe en C ++, probablemente sea más conveniente ignorar el microcontrolador adicional, cortocircuitar el puente y usar la API del fabricante, que se encuentra aquí .

Los pitonistas humildes también pueden ir por el primer camino. Parece que hay un par de bibliotecas de Python ( aquí y aquí ). Pero desafortunadamente, ninguno funcionó para mí.

Los pitonistas avanzados básicamente pueden escribir un controlador de control de módulo en Python. El procedimiento para obtener un marco se describe en detalle en la hoja de datos. Pero luego tendrá que prescribir todos los procedimientos de calibración, lo que parece un poco pesado. Por lo tanto, tuve que ir por el segundo camino. Resultó ser moderadamente espinoso, pero bastante aceptable.

Gracias a la visión de los ingenieros chinos o simplemente a una feliz coincidencia, el chal resultó tener una muy buena ubicación de las conclusiones:

imagen

Solo queda colocar el bloque e insertar la bufanda en el conector de frambuesa. Se instala un convertidor de 5 a 3 voltios en la placa, por lo que parece que nada amenaza los delicados terminales Rx y Tx de Raspberry.

Debe agregarse que la conexión de acuerdo con la primera opción también es posible, pero requiere más mano de obra y habilidades de soldadura. La placa debe instalarse en el otro lado del conector Raspberry (que se muestra en la foto del título de esta publicación).

Software


En un sitio chino conocido, se ofrece un milagro para acceder al GY-MCU90640:

imagen

Lo más probable es que debería haber alguna descripción del protocolo de interacción con el microcontrolador instalado en la placa, de acuerdo con el cual funciona este producto de software. Después de una breve conversación con el vendedor de bufandas (respeto a estos respetados caballeros), me enviaron dicho protocolo. Apareció en pdf y en chino puro.

Gracias al traductor de Google y la copia activa y el pegado, el protocolo se descifró en aproximadamente una hora y media, y todos pueden leerlo en Github . Resultó que la bufanda comprende seis comandos básicos, entre los cuales hay una solicitud de trama en el puerto COM.

Cada píxel de la matriz es, de hecho, el valor de temperatura del objeto que está mirando este píxel. Temperatura en grados Celsius por 100 (número de doble byte). En realidad, incluso hay un modo especial en el que la bufanda enviará fotogramas desde la matriz a la Frambuesa 4 veces por segundo.

El guión para obtener imágenes térmicas aquí:
"""MIT License

Copyright (c) 2019 

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE."""

import serial, time
import datetime as dt
import numpy as np
import cv2

# function to get Emissivity from MCU
def get_emissivity():
	ser.write(serial.to_bytes([0xA5,0x55,0x01,0xFB]))
	read = ser.read(4)
	return read[2]/100

# function to get temperatures from MCU (Celsius degrees x 100)
def get_temp_array(d):

	# getting ambient temperature
	T_a = (int(d[1540]) + int(d[1541])*256)/100

	# getting raw array of pixels temperature
	raw_data = d[4:1540]
	T_array = np.frombuffer(raw_data, dtype=np.int16)
	
	return T_a, T_array

# function to convert temperatures to pixels on image
def td_to_image(f):
	norm = np.uint8((f/100 - Tmin)*255/(Tmax-Tmin))
	norm.shape = (24,32)
	return norm

########################### Main cycle #################################
# Color map range
Tmax = 40
Tmin = 20

print ('Configuring Serial port')
ser = serial.Serial ('/dev/serial0')
ser.baudrate = 115200

# set frequency of module to 4 Hz
ser.write(serial.to_bytes([0xA5,0x25,0x01,0xCB]))
time.sleep(0.1)

# Starting automatic data colection
ser.write(serial.to_bytes([0xA5,0x35,0x02,0xDC]))
t0 = time.time()

try:
	while True:
		# waiting for data frame
		data = ser.read(1544)
		
		# The data is ready, let's handle it!
		Ta, temp_array = get_temp_array(data)
		ta_img = td_to_image(temp_array)
		
		# Image processing
		img = cv2.applyColorMap(ta_img, cv2.COLORMAP_JET)
		img = cv2.resize(img, (320,240), interpolation = cv2.INTER_CUBIC)
		img = cv2.flip(img, 1)
		
		text = 'Tmin = {:+.1f} Tmax = {:+.1f} FPS = {:.2f}'.format(temp_array.min()/100, temp_array.max()/100, 1/(time.time() - t0))
		cv2.putText(img, text, (5, 15), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 0), 1)
		cv2.imshow('Output', img)
		
		# if 's' is pressed - saving of picture
		key = cv2.waitKey(1) & 0xFF
		if key == ord("s"):
			fname = 'pic_' + dt.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + '.jpg'
			cv2.imwrite(fname, img)
			print('Saving image ', fname)
		
		t0 = time.time()

except KeyboardInterrupt:
	# to terminate the cycle
	ser.write(serial.to_bytes([0xA5,0x35,0x01,0xDB]))
	ser.close()
	cv2.destroyAllWindows()
	print(' Stopped')

# just in case 
ser.close()
cv2.destroyAllWindows()



, Raspberry PI, 4 . , . OpenCV. «s» « » jpg.

image

. , . — . 20 40 . Ctrl + C.

image

Raspberry Pi Zero W Pi 3 B+. VNC . , , powerbank' VNC . , , .

. .

, , . . , . - , .

!

UPD: . . - , , . . — .

image

. +20...+40 -10...+5.

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


All Articles