Text
                    Техника
ТЕПЛОВИЗОР НА RASBERRY
MLX90640 - это тепловизорная матрица с микроконтроллером, производства ра-
нее фирмы Melexis. Тепловизорная матрица имеет размерность 32 на 24 пикселя.
Это немного, но при интерполяции изображения вроде как достаточно, чтобы хоть
что-нибудь разглядеть.
Сенсор выпускается в двух модификациях, корпуса которых отличаются углом
обзора матрицы. Более приземистая конструкция А обозревает окружающий мир под
углом 110 (по горизонтали) на 75 (по вертикали) градусов. В — под 55 на 37,5
градусов соответственно. Корпус устройства имеет только четыре вывода — два
для питания, два для общения с управляющим устройством по 12С интерфейсу.
Китайские товарищи ставят MLX90640 на плату с еще одним микроконтроллером
на борту (STM32F103). По всей видимости, для более простого управления матри-
цей. Называется всё это хозяйство GY-MCU90640. И стоит на момент приобретения
(конец декабря 2018 года) в районе 5 тыс. руб. Выглядит следующим образом:


Как можно заметить, есть две разновидности плат, с узко- или широкоугольной версией сенсора на борту. Более широкоугольная версия будет хороша на самоходных роботах или в систе- мах безопасности (поле зрения будет больше). Согласно даташиту, она обладает также меньшим шумом и большей точностью измерения. Но для задач визуализации я бы больше рекомендовал более «дальнобойную» версию В. По одной очень значимой причине. В перспективе при съемке её можно разворачивать (вручную или на платформе с приводом) и делать составные «фо- то», увеличивая тем самым более чем скромное разрешение в 32 на 24 пикселя. Собирать тепловизорные снимки 64 на 96 пикселей, например... В дальнейшем по тексту фото будут с моей широкоугольной версией А. Управлять тепловизорным модулем можно двумя способами: 1. Закоротить перемычку «SET» на плате и по 12С обращаться напрямую к внут- реннему микроконтроллеру MLX90640. 2. Оставить перемычку в покое и общаться с модулем через установленный на плате STM32F103 через RS-232 подобный интерфейс. Если вы пишете на C++, наверное, будет удобнее проигнорировать лишний мик- роконтроллер , закоротить перемычку и воспользоваться API от производителя1. Начинающим питонистам тоже можно пойти первым путём. Вроде как есть пара библиотек на Python2. Но у меня, к сожалению, с ходу ни одна не заработала. Продвинутым питонистам можно в принципе написать драйвер управления модулем на Питоне. Процедура получения кадра подробно расписана в даташите3. Но тогда придется прописывать все калибровочные процедуры, что кажется слегка обреме- нительным. Поэтому пришлось пойти вторым путем. Он оказался умеренно терни- стым, но вполне проходимым. Благодаря прозорливости китайских инженеров или просто счастливому стечению обстоятельств у платки оказалось очень удачное расположение выводов: 1 ftp://homelab.homelinuxserver.org/pub/arhiv/2019-04-al.rar (mlx90640-library- master.zip) 2 MLX90640-python-master.zip и mlx90640-library-master-l.zip в архиве. 3 MLX90640-Datasheet-Melexis.pdf в архиве.
Осталось только поставить колодку и вставить платку в разъем Rasberry. На плате установлен преобразователь 5 в 3 вольта, поэтому нежным Rx и Тх выводам Raspberry вроде как ничего не угрожает. Надо добавить, что подключение по первому варианту тоже возможно, но требу- ет больших трудозатрат и паяльной сноровки. Плату нужно ставить с другой сто- роны разъема Raspberry: т «• , • , 1$Х90640 •ex?(*T wo, •тх. \g, psoJ 41 """"IjJ Tn r. -^ |L- ЕЯ . к г a?* p Г f **** ^^fl • * ,# \ гП i"V! SU5= SJIB • я 5^И а. У &лч 1 I Ш 1 ^1 [fp^ : , '" f'.J •. Li |£5j* У На известном китайском сайте для доступа к GY-MCU90640 предлагается соот- ветствующее программное обеспечение:
По всей видимости, должно быть и какое-то описание протокола взаимодействия с установленным на плате микроконтроллером, по которому сей программный про- дукт работает! После недолгого общения с продавцом платки таковой протокол мне и был выслан. Он оказался в pdf и на чистом китайском языке. Благодаря переводчику Google и активному копипастингу примерно через час- полтора протокол был расшифрован4. Оказалось, что платка понимает шесть базо- вых команд, среди которых есть запрос кадра по СОМ порту. Каждый пиксель матрицы — это, по сути, значение температуры объекта, на ко- торый этот пиксель смотрит. Значение температуры в градусах Цельсия, умножен- ных на 100 (двухбайтное число). Собственно, есть даже специальный режим, в котором платка будет слать кадры с матрицы на Raspberry 4 раза в секунду. Скрипт для получения тепловизорных снимков: 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,OxFB])) read = ser.read(4) return read[2]/100 # function to get temperatures from MCU (Celsius degrees x 100) def get_temp_array(d): 4 GY-MCU90640-RPI-Python-master.zip в архиве.
# 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 (f Configuring Serial portf) ser = serial.Serial (f/dev/serialOf) ser.baudrate = 115200 # set frequency of module to 4 Hz ser.write(serial.to_bytes([0xA5,0x25,0x01,OxCB])) time.sleep(0.1) # Starting automatic data colection ser.write(serial.to_bytes([0xA5,0x35,0x02,OxDC])) tO = time . time () try: while True: # waiting for data frame data = ser.read(1544) # The data is ready, letfs handle it! Та, 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 = fTmin = {: + .lf} Tmax = {: + .lf} FPS = {:.2f}! . format (temp_ar ray .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(f Outputf , img)
# if f sf is pressed - saving of picture key = cv2.waitKey(1) & OxFF if key == ord("s"): fname = fpic_f + dt. date time. now () . strf time (f %Y-%m-%d_%H-%M- %Sf) + f.jpgf cv2.imwrite(fname , img) print(f Saving image f , fname) tO = time.time() except Keyboardlnterrupt: # to terminate the cycle ser.write(serial.to_bytes([0xA5,0x35,0x01,OxDB])) ser.close() cv2 . destroyAHWindows () print(f Stoppedf) # just in case ser.close() cv2 . destroyAHWindows () Скрипт опрашивает тепловизорную матрицу и выводит кадры на консоль монито- ра, на который подключен Raspberry PI, 4 раза в секунду. Этого достаточно для того, чтобы не испытывать большого дискомфорта при съемке объектов. Для ви- зуализации кадра используется пакет OpenCV. При нажатии на кнопку «s» в папке со скриптом сохраняются тепловизорные «тепловые карты» в формате jpg.
Для большей информативности я вывел минимальную и максимальную температуры на кадре. То есть, глядя на окраску, можно видеть какая примерно температура у наиболее разогретых или охлажденных предметов. Погрешность измерения — при- мерно градус с большую сторону. Тепловой диапазон задан от 20 до 40 градусов. Выход из скрипта по нажатию Ctrl + С. Скрипт работает примерно одинаково и на Raspberry Pi Zero W и на Pi 3 В+. Я установил VNC сервер на смартфон. Таким образом, взяв в руки Raspberry, под- ключенную к powerbankf у и смарфтон с запущенным VNC можно получить переносной тепловизор с возможностью сохранения тепловых снимков. Возможно, это не со- всем удобно, но вполне функционально. После первого запуска возможно некорректное измерение максимальной темпера- туры . В этом случае нужно выйти из скрипта и запустить повторно.