Raspberry PIのDIYサーマルイメージャー、または「今夏に何をするかわかったと思う」

画像



みなさんこんにちは!



冬が来ました、そしてそれで、タスクはdachaの田舎の住居の建物の断熱特性をチェックすることです。 そして、よく知られている中国のサイトに、かなり手頃な価格の赤外線画像モジュールが登場したことが判明しました。 エキゾチックで、おそらくは有用なものを組み立てることは可能ですか?自家製のサーマルイメージャーですか? なぜ、ラズベリーがどこかに横たわっていたように...それが何をもたらしたのか-カットの下で教えます。



MLX90640。 これは何ですか



そしてこれは、実際には、マイクロコントローラーを搭載したサーマルイメージングマトリックスです。 以前は知られていない会社Melexisの生産。 サーマルイメージングマトリックスの寸法は32 x 24ピクセルです。 これは大したことではありませんが、画像を補間するとき、少なくとも何かを確認するのに十分であるようです。



画像



センサーには2つのバージョンがあり、マトリックスの表示角度が異なる場合があります。 よりしゃがんだ構造Aは、75(垂直)度で110(水平)の角度で外の世界を見渡せます。 B-それぞれ55度下37.5度。 デバイスケースには4つの出力しかありません。2つは電源用、2つはI2Cインターフェイスを介して制御デバイスと通信するためのものです。 興味のあるデータシートはこちらからダウンロードできます



そして、GY-MCU90640とは何ですか?



中国の同志は、MLX90640を別のマイクロコントローラー(STM32F103)とともに搭載しています。 どうやら、マトリックス管理を容易にするため。 このファーム全体はGY-MCU90640と呼ばれます。 そして、5千ルーブルの地域での買収時(2018年12月末)に費用がかかります。 次のようになります。



画像



ご覧のとおり、2種類のボードがあり、ボードには狭角または広角のセンサーがあります。



どのバージョンが最適ですか? 良い質問ですが、残念なことに、モジュールが既に注文されて受領された後にのみ、私はそれを持っていました。 何らかの理由で、注文時に、私はこれらのニュアンスに注意を払いませんでした。 しかし、無駄に。



より広いバージョンは、自走式ロボットまたはセキュリティシステムに適しています(視野が広くなります)。 データシートによると、ノイズが少なく、測定精度も高くなっています。



画像



しかし、視覚化タスクについては、Bのより「長距離」バージョンをお勧めします。非常に重要な理由が1つあります。 将来的には、撮影時に(手動またはドライブのあるプラットフォームで)展開​​し、合成の「写真」を撮ることができます。これにより、32 x 24ピクセルの控えめな解像度を超えることができます。 たとえば、熱画像を64 x 96ピクセルで収集します。...まあ、大丈夫、将来的には広角バージョンAからの写真になります。



Raspberry PIに接続する



サーマルイメージングモジュールを制御するには、次の2つの方法があります。



  1. ボードの「SET」ジャンパーを短くし、I2Cを使用して内部マイクロコントローラーMLX90640に直接接続します。
  2. ジャンパーをそのままにして、RS-232経由でSTM32F103ボードにインストールされた同様のインターフェースを介してモジュールと通信します。


C ++で作成する場合は、余分なマイクロコントローラーを無視し、ジャンパーを短絡させて、メーカーのAPIを使用する方が便利です( こちら)



謙虚なパイニストも最初の道を行くことができます。 Pythonライブラリがいくつかあるようです( ここここ )。 しかし、残念なことに、私のために働いたのは一人ではありません。



高度なpythonistsは基本的にPythonでモジュール制御ドライバーを書くことができます。 フレームを取得する手順は、データシートに詳細が記載されています。 しかし、その後、すべてのキャリブレーション手順を規定する必要がありますが、これは少し面倒です。 したがって、私は2番目の道を行かなければなりませんでした。 やや厄介であることが判明しましたが、かなりまずまずです。



中国のエンジニアの洞察または幸運な偶然のおかげで、ショールは結論の非常に良い場所を持っていることが判明しました:



画像



ブロックを置き、スカーフをラズベリーコネクタに挿入するだけです。 5から3ボルトのコンバーターがボードにインストールされているため、Raspberryの繊細なRxおよびTx端子を脅かすものはないようです。



最初のオプションによる接続も可能ですが、より多くの労力とはんだ付けスキルが必要であることを追加する必要があります。 ボードは、Raspberryコネクタの反対側にインストールする必要があります(この投稿のタイトル写真に示されています)。



ソフトウェア



有名な中国のサイトでは、GY-MCU90640にアクセスするためにそのような奇跡が提供されています。



画像



どうやら、このソフトウェア製品の動作に応じて、ボードにインストールされているマイクロコントローラーとの相互作用プロトコルの説明があるはずです! スカーフの売り手との短い会話の後(これらの尊敬される紳士に関して)、そのようなプロトコルが私に送られました。 pdfおよび中国語で表示されます。



Googleの翻訳者とアクティブなコピーアンドペーストのおかげで、プロトコルは約1時間半で解読され、誰でもGithubで読むことができます。 スカーフは6つの基本的なコマンドを理解しており、その中にはCOMポートにフレームリクエストがあります。



マトリックスの各ピクセルは、実際には、このピクセルが見ているオブジェクトの温度値です。 摂氏温度の100倍の温度(2バイト数)。 実際、スカーフがマトリックスからラズベリーにフレームを毎秒4回送信する特別なモードもあります。



ここで熱画像を取得するためのスクリプト:
"""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.



All Articles