Последнее время появилось довольно много обзоров тепловизионной приставки к смартфону Seek Thermal. Однако, Seek Thermal не единственный тепловизор доступный широким массам пользователей – всем известная компания FLIR также выпускает свою тепловизионную приставку FLIR One трёх разных поколений. В данной статье речь пойдёт о приставке второго поколения FLIR One Gen 2 для Android, имеющей разрешение болометрической матрицы 160x120 пикселей.

Купил я эту приставку на ebay три месяца назад с надеждой подключить к персональному компьютеру по USB и, надо сказать, моя надежда оправдалась.

Первое, что потребовалось сделать, так это собрать кабель с micro-USB (мама) на USB (папа). Тут проблем не возникнет.

Дальше — интереснее. На форуме eevblog.com tomas123 вскрыл протокол обмена по USB и написал для Linux своё консольное приложение для получения картинки с тепловизионной и обычной камер приставки с использованием libusb. Для Linux мне программа была не интересна, и я попробовал написать свою программу для Windows XP на базе программы tomas123. И вот тут-то и возникла проблема: libusb для Windows отказалась корректно работать, выдавая ошибку

libusb0-dll:err [submit_async] submitting request failed, win error: Параметр задан неверно.

Задав вопрос на форуме eevblog.com, я получил ответ, что я стал третьим, кто пытался безуспешно запустить эту программу для Windows с использованием libusb. Так же выяснилось, что и под Linux далеко не со всеми дистрибутивами FLIR One через libusb работает стабильно – в Ubuntu 10, например, часты ошибки “pipe error”, а в Mageia 5 таких проблем не возникает. Ну что ж, пришлось отложить программу для Windows на будущее.

Следующая ОС, для которой я попытался написать программу, была QNX 6.3. Эту ОС я использую на работе, но я никогда не писал драйвер USB для неё. С помощью форума qnx.org.ru мне всё же удалось написать нечто более-менее корректно работающее по USB с FLIR One. Вот на картинке интерфейс получившейся программы:


Программа для QNX 6.3.

Однако программа работает нестабильно – io-usb очень часто спустя пару-тройку минут погибает в неравном бою с тепловизором. Более того, на некоторых машинах система даже не замечает подключение устройства! Оказалось, что переключив в BIOS работу портов в USB 1, система всё же оживает и начинает обнаруживать устройство и работать с ним, пусть и с пониженным FPS. Я полагаю, что, возможно, FLIR One использует не совсем стандартный USB, и это и приводит к подобным проблемам. Но главное – программа работает и картинка строится.

Дальше настало время вернуться к Windows. С помощью вот этой темы я написал драйвер для Windows XP. Вылетев раз 20 в BSOD в процессе отладки, драйвер ожил, и я получил картинку с тепловизора в программе для Windows XP. Победа! Однако, всё опять-таки, не так радужно, как казалось сначала. На некоторых компьютерах (и даже с разных USB-разъёмов одного и того же компьютера) с Windows XP драйвера просто невозможно установить – система видит FLIR One как составное USB-устройство и совершенно не желает его разделить на три устройства с окончаниями на .iAP, .FileIO и .Frame. Такая же проблема обнаружилась и в Windows 7, что также не позволило мне установить драйвер для этой ОС. Как эту проблему обойти, мне до сих пор неизвестно.

Собственно, в настоящий момент, на этом разработка программ для FLIR One у меня и остановилась.


Программа для Windows XP.

Итак, что же представляет этот тепловизор с точки зрения обмена с ним по USB:
Идентификатор производителя: 0x09CB.
Идентификатор устройства: 0x1996.
Тепловизор имеет три интерфейса:
  1. iAP с конечными точками: 0x00 (чтение и запись), 0x81 (чтение) и 0x02 (запись);
  2. FileIO с конечными точками: 0x00 (чтение и запись), 0x83 (чтение) и 0x04 (запись);
  3. Frame с конечными точками: 0x00 (чтение и запись), 0x85 (чтение) и 0x06 (запись).

Все эти конечные точки имеют тип bulk.

Интерфейс iAP позволяет управлять остальными двумя интерфейсами, посылая в iAP управляющую команду с нужными параметрами (они есть в приложенных файлах программ и драйверов). Чтобы получить тепловое изображение достаточно производить чтение и расшифровку данных из конечной точки 0x85 интерфейса Frame и не забывать читать данные и из конечных точек 0x81 и 0x83, иначе тепловизор может остановить передачу данных через некоторое время.
Принятые данные выглядят примерно вот так:
  1. Четыре “магических” байта, отделяющие пакеты друг от друга: 0xEF,0xBE,0x00,0x00;
  2. Заголовок, в котором указаны размеры данных тепловой и обычной камеры, общий размер кадра и данных состояния устройства.
  3. Данные кадра тепловой камеры.
  4. Прочие данные.

Что же именно передаётся во всём кадре, я не изучал; мне было достаточно данных от тепловой камеры.

Принятые данные с тепловой камеры представляют собой массив 14 битных значений показаний АЦП с болометрической матрицы, начинающиеся с заголовков блоков данных для каждых 80 пикселей (один пиксель занимает 2 байта типа unsigned short). Заголовок выглядит так (взято из документации на тепловизионный модуль Lepton 3, используемый в FLIR One Gen 2):


Заголовок блока данных в 80 пикселей.

Из этого заголовка нас интересует только код CRC, вычисляемый по полиному, указанному в документации.

Чтобы построить красивую картинку достаточно просто найдя максимум и минимум привести полученные показания в диапазон 0-255 (по числу цветов палитры). Собственно, на этом построение красочных картинок и заканчивается. Если же есть желание по данным показаний вычислить температуру, то тут потребуются интересные формулы с набором коэффициентов для конкретной модели тепловизора. К счастью, эти коэффициенты для FLIR One Gen 2 известны.
А формула, согласно документации “FLIR Lepton with Radiometry Quick start Guide”, вот какая:



Мда… Хорошо, что tomas123 уже озаботился такими вычислениями и в своей программе написал функцию вычисления температуры объекта. В моей переделке она выглядит вот так:

#define EPS 0.0000000001

double PlanckR1=16528.178;
double PlanckB=1427.5;
double PlanckF=1.0;
double PlanckO=-1307.0;
double PlanckR2=0.012258549;

double TempReflected=20;

double Emissivity=0.95;

//---------------------------------------------------------------------------
//вычислить температуру
//---------------------------------------------------------------------------
bool GetTemperature(unsigned short raw14,double &value)
{
 if (raw14>0x10000) return(false);
 raw14*=4;    
 double zn=(PlanckR2*(exp(PlanckB/(TempReflected+273.15))-PlanckF));
 if (fabs(zn)<EPS) return(false);
 double RAWrefl=PlanckR1/zn-PlanckO;
 double RAWobj=(raw14-(1-Emissivity)*RAWrefl)/Emissivity;
 double lgr=PlanckR1/(PlanckR2*(RAWobj+PlanckO)+PlanckF);
 if (lgr<=EPS) return(false);
 value=PlanckB/log(lgr)-273.15; 
 return(true);
}

Здесь TempReflected – температура болометрической матрицы, а Emissivity- коэффициент излучения измеряемой поверхности. Константы PlanckR1, PlanckB, PlanckF, PlanckO, и PlanckR2 специфичны для данной модели тепловизора.

Как можно заметить, моя программа для Windows сохраняет RAW-файлы. Для их анализа я также написал отдельное приложение. Выглядит оно вот так вот:


Анализатор RAW-файлов для Windows XP.

А вот примеры снимков с данного тепловизора, полученные программой для Windows XP:

image

image

image

image

image

Собственно, на этом всё. Исходники и сами программы прилагаются по ссылкам ниже (я так и не понял, как их разместить на github).

  1. Для QNX 6.3
  2. Для Windows XP
  3. Программа для анализа RAW-изображений для Windows


P.S. Оказалось, что с 4pda без регистрации не скачать приложенные файлы. Сделал ссылку на другой ресурс.
Поделиться с друзьями
-->

Комментарии (4)


  1. VBKesha
    12.05.2017 14:05

    QNX и USB охх было у меня много веселья. Но в 6.5 вроде бы получше всё стало.


  1. da-nie
    12.05.2017 19:14

    Исправил ссылки и мелкие ошибки.


    1. nwanomaly
      12.05.2017 21:12
      +1

      А хорошо он батареи снимает )

      image


      1. da-nie
        12.05.2017 21:13

        Ну, это с MSX. ;)