Текущая пандемия коронавируса внесла существенные коррективы в жизнь людей по всему миру. Одним из значительных изменений, которые постигли человечество в этом плане, является необходимость в измерении температуры на входе во многие здания, чтобы таким образом уменьшить вероятность проникновения в здание людей с симптомами COVID-19. Делается это с помощью бесконтактных термометров, которые с начала пандемии стали дефицитным товаром и существенно повысилась цена их приобретения. Поэтому, возможно, вас заинтересует проект бесконтактного термометра, который можно сделать своими руками.
На нашем сайте ранее мы уже рассматривали бесконтактный термометр на основе платы Arduino и датчике температуры MLX90614, который выводит измеренное значение температуры на экран OLED дисплея. В этой же статье мы рассмотрим создание более простого в изготовлении, но более функционального бесконтактного инфракрасного термометра на основе платы Arduino и смартфона на операционной системе Android, с помощью которого можно будет измерять температуру и вести лог измерений температуры с фотографиями лиц, у которых производилось измерение температуры. В дальнейшем этот лог температуры с фотографиями можно будет передавать для хранения в какое-нибудь централизованное место.
Как уменьшить стоимость бесконтактного термометра?
При ближайшем рассмотрении нам для изготовления бесконтактного термометра понадобятся инфракрасный датчик температуры, микроконтроллер, дисплей, драйвер дисплея и батарейка. Одним из самых дорогих устройств в этом списке будет бесконтактный инфракрасный датчик температуры. К сожалению, выбор среди доступных на рынке подобных датчиков невелик и придется выбирать между MLX90614 и MLX90615. Существенно сэкономить в этом плане можно с помощью аналогового датчика температуры (если вы умеете уверенно с ними работать), но общая схема термометра в этом случае немного усложнится и вам придется терпеть некоторые "муки", связанные с калибровкой подобного устройства. Но здесь выбор за вами. Мы же для нашего проекта решили использовать датчик MLX90615 от компании Melexis.
Когда датчик температуры выбран, нам осталось определиться с микроконтроллером, дисплеем и батареей. С целью удешевления проекта нашего термометра мы решили использовать в его составе смартфон потому что смартфоны сейчас уже не являются новинкой – они есть у большинства активного населения. Поэтому мы написали приложение на Android под названием “Easy Scan” (его можно скачать далее в статье), которое будет взаимодействовать с нашим термометром и выполнять ряд операций – вести лог данных температуры и захватывать изображения. С помощью данного подхода мы не только сможем просто хранить необходимые нам данные, но также мы сможем их передавать по электронной почте, по WhatsApp и т.п.
Поэтому теперь для нашего проекта бесконтактного термометра понадобятся лишь следующие компоненты:
- MLX90615 IR Temperature Sensor – инфракрасный датчик температуры MLX90615 (купить на AliExpress). К сожалению, на момент публикации данной статьи удалось найти на Aliexpress данный датчик только вместе с платой (это дороже), возможно, вам удастся найти его в продаже в виде отдельного датчика (это будет дешевле).
- TCRT5000 IR Sensor – инфракрасный датчик TCRT5000 (купить на AliExpress).
- Плата Arduino Nano (купить на AliExpress).
- Резисторы (купить на AliExpress).
Почему TCRT5000 и Arduino Nano?
Инфракрасный датчик TCRT5000 в нашем проекте будет использоваться для определения позиции (точки измерения температуры) и обеспечения автоматического считывания значений температуры. С помощью него нам не будет нужно производить никаких "танцев с бубном" в Android приложении и работа с ним значительно упростится. Также дополнительным достоинством использования данного датчика в нашем проекте является то, что с его помощью значения температуры будут считываться только тогда, когда человек находится на "правильном" расстоянии от нашего термометра, поэтому нам не нужно будет беспокоиться о ложных считываниях.
Причина, по которой в данном проекте мы будем использовать плату Arduino Nano, заключается в том, что у данной платы есть встроенный USB интерфейс – а он нам крайне важен для обеспечения взаимодействия между платой и смартфоном.
Схема проекта
Схема бесконтактного термометра на основе платы Arduino и смартфона представлена на следующем рисунке.
Как видите, схема достаточно проста – нам в ней нужно всего лишь подключить датчики MLX90615 и TCRT5000 к плате Arduino Nano.
Датчики MLX90615 и TCRT500 работают от питающих напряжений 3.3V и 5V соответственно, поэтому мы без проблем сможем запитать их от платы Arduino. Контакты интерфейса I2C платы Arduino A4 (SDA) и A5 (SCL) используются для взаимодействия с датчиком MLX90615. Обычно датчик TCRT5000 используется вместе с операционным усилителем в режиме компаратора, но в нашей схеме инфракрасный датчик должен быть невосприимчив к солнечному свету. Поэтому мы подключили инфракрасный диод (IR diode) к цифровому контакту платы Arduino, а фотодиод – к ее аналоговому контакту. Таким образом мы сможем измерять значение с выхода фотодиода в режиме нормального функционирования и после приема сигнала с инфракрасного диода, разница между этими двумя значениями будет помогать нам в борьбе с шумом. Более подробно это будет рассмотрено в разделе про объяснение кода программы.
Вы можете собрать устройство на печатной плате, но мы в целях убыстрения процесса спаяли компоненты проекта на перфорированной плате. А в дальнейшем мы напечатали корпус устройства на 3D принтере исходя из размеров нашей перфорированной платы.
Объяснение программы для Arduino
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Программа для нашего термометра значительно упрощается благодаря библиотеке для работы с датчиком MLX90615, разработанной Сергеем Киселевым, скачать ее можно по следующей ссылке.
Вначале в коде программы нам будет необходимо подключить используемые библиотеки и объявить необходимые переменные. В нашем проекте будут использоваться две важные для нас переменные: error_correction value (ошибка коррекции) и range sensitivity value (значение диапазона чувствительности). Хотя датчик MLX90615 поставляется уже откалиброванным с завода-изготовителя, мы обнаружили, что показания с него будут обладать большей чувствительностью (точностью), если мы добавим к ним значение ошибки коррекции. В нашем случае мы будем добавлять 3.2 к значению, которое мы будем получать с датчика. Мы проверяли работу нашего термометра вместе с сертифицированным термометром и обнаружили, что добавление данного корректировочного значения делает показания нашего термометра более надежными (точными). Следующая важная переменная у нас – это Range sensitivity (чувствительность и диапазон). Если мы будем уменьшать ее значение, то диапазон работы нашего термометра будет увеличиваться.
1 2 3 4 5 |
float calibration = 3.2; //add this to actual value int Range_sensitivity = 200; //Decrease this value to increase range #include <Wire.h> #include "MLX90615.h" MLX90615 mlx = MLX90615(); |
Защита от ложных показаний при попадании солнечного света на инфракрасный датчик
Следующее устройство, которое нуждается в корректировке в нашем проекте, это датчик TCRT5000. Если использовать его "обычным" способом, то в нашем случае он будет значительно страдать от попадания на него солнечного цвета.
Для борьбы с этой проблемой мы будем снимать, как уже указывалось в схеме, два показания с выхода этого датчика. Излучающий светодиод инфракрасного датчика подключен к цифровому контакту платы Arduino, а приемный светодиод – к ее аналоговому контакту. Поэтому в нашем случае мы будем считывать два значения с инфракрасного датчика (IR sensor) – одно значение это будет шум (Noise), а другое значение это будет шум + сигнал (Noise plus Signal). Значение шума будет измеряться в то время, когда излучающий светодиод выключен, то есть приемный инфракрасный светодиод в это время будет принимать излучение Солнца, которое практически всегда в какой то степени присутствует в месте работы нашего термометра. А после включения излучающего светодиода мы приемным светодиодом будем измерять уже смесь сигнал + шум. Затем в программе мы будем просто вычитать из значения сигнал + шум значение шума и будем в результате подучать значение сигнала. Строки программы, реализующие этот процесс, будут выглядеть следующим образом:
1 2 3 4 5 6 7 |
digitalWrite(2,HIGH); // Turn on IR LED delayMicroseconds(500); // Forward rise time of IR LED Noise_P_Signal=analogRead(A7); // Read value from A0 => noise+signal digitalWrite(2,LOW); // Turn off IR LED delayMicroseconds(500); // Fall time of IR LED Noise=analogRead(A7); // Read value from A0 => noise only Signal = Noise - Noise_P_Signal; |
Поскольку мы будем знать значения сигнала (Signal) и шума (Noise), мы можем сравнить их со значением Range_sensitivity чтобы проверить достаточно ли близко расположен датчик к коже человека и если это так, мы можем передавать измеренное значение температуры с помощью последовательной связи, а если датчик будет находиться достаточно далеко от кожи человека (то есть измерение температуры в этом случае будет неточным), мы будем на выход передавать просто position_error (ошибка положения). Если значение шума будет очень большим (в нашем случае больше 500) это будет означать что датчик направлен прямо на Солнце и в этом случае уже можно не рассчитывать на точное измерение температуры, поэтому в данном случае мы считывание измерений температуры не производим.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
if (Signal>Range_sensitivity && Noise >500) //dec. signal to increase rage { if (trigger == true) Serial.println("start"); digitalWrite(13,HIGH); temperature = (mlx.get_object_temp()) + error_correction; Serial.println(temperature,1); delay(100); trigger = false; } else { delay(100); trigger = true; digitalWrite(13,LOW); Serial.println("position_error"); } |
Android приложение Easy Scan
Одной из значимых частей нашего проекта является Android приложение Easy Scan. Вы можете скачать установочный (APK) файл данного приложения по следующей ссылке:
Download Easy Scan Android Application
Как уже было отмечено раньше, наше Android приложение позволяет сохранять значения температуры вместе с фотографиями лиц, у которых производились измерения температуры) и делиться полученным excel файлом через Whatsapp, E-mail и т.д. Несколько скриншотов работы данного приложения показаны на следующем рисунке.
Печать корпуса термометра на 3D принтере
Основная идея конструирования нашего проекта термометра заключалась в том, чтобы сделать его достаточно компактным - чтобы его легко можно было монтировать сверху смартфона. Для этого мы разработали CAD модель корпуса термометра небольшого размера, который можно закрепить на смартфоне с помощью скрепки для бумаг.
Его дизайн достаточно простой – просто коробка, куда можно было бы спрятать все электронные части термометра, отверстие для установки инфракрасного датчика и датчика температуры, а также слот для подсоединения USB кабеля к плате Arduino Nano. Датчик температуры устанавливается под углом наклона 30 градусов чтобы он находился приблизительно в перпендикулярном положении когда мы его держим у головы человека, которому хотим измерить температуру. STL файлы для печати корпуса нашего термометра на 3D принтере вы можете скачать по следующей ссылке:
Download STL files from Thingiverse
При этом учитывайте, что размеры корпуса термометра подогнаны под размеры нашей перфорированной платы, у вас они могут быть немного другими, поэтому вам может понадобиться небольшая корректировка размеров корпуса в наших файлах.
Тестирование работы термометра
После того как аппаратная часть проекта будет готова, загрузите код программы в плату Arduino. После этого откройте окно монитора последовательной связи (serial monitor) и вы увидите что в нем будет печататься ошибка определения положения (position error). Если вы поднесете термометр достаточно близко к своей руке, вы увидите что в этом окне начнут выводиться измеренные значения температуры. Если у вас есть под рукой сертифицированный термометр, то вы можете откалибровать работу нашего самодельного термометра с его помощью изменяя значение корректировочного значения в программе (error correction value).
После этого используйте соединитель OTG типа чтобы подключить термометр к своему смартфону. Мы протестировали его работу со смартфонами с разъемами Type-C и micro USB – в обоих случаях проблем не возникло. Только проверьте в своем смартфоне правильность настроек при подключении к нему устройств с помощью OTG. Некоторые смартфоны "спрашивают" об этом при подключении устройств, а некоторые – нет.
После выполнения всех необходимых подключений установите приложение Easy Scan (ссылка на его скачивание приведена выше в статье) и запустите его. Поместите получившуюся конструкцию напротив человека, температуру которого необходимо измерить, и если все работает нормально, вы должны увидеть на экране приложения измеренное значение температуры.
В приложении можно будет установить границу температуры, при превышении которой необходимо будет также делать фотографию лица с повышенной температурой. Все собранные сведения можно будет просмотреть в приложении в удобном виде, также они могут быть "расшарены" в Excel формате для других лиц. Более подробно работу с нашим самодельным термометром вы можете посмотреть на видео, приведенном в конце статьи.
Исходный код программы (скетча)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
float error_correction = 3.5; //мы будем добавлять это корректировочное значение к показаниям int Range_sensitivity = 200; //уменьшите это значение чтобы увеличить диапазон работы термометра #include <Wire.h> //библиотека для протокола I2C #include "MLX90615.h" MLX90615 mlx = MLX90615(); void setup() { Serial.begin(9600); delay(100); while (! Serial); pinMode(2,OUTPUT); mlx.begin(); } int Noise; int Signal; int Noise_P_Signal; boolean trigger = true; float temperature; float pvs_temperature; void loop() { digitalWrite(2,HIGH); // включаем инфракрасный светодиод delayMicroseconds(500); // время, в течение которого инфракрасный светодиод будет находиться во включенном состоянии Noise_P_Signal=analogRead(A7); // считываем значение с контакта A0 => noise+signal (шум + сигнал) digitalWrite(2,LOW); // выключаем инфракрасный светодиод delayMicroseconds(500); // время, в течение которого инфракрасный светодиод будет находиться в выключенном состоянии Noise=analogRead(A7); // считываем значение с контакта A0 => noise only (только шум) Signal = Noise - Noise_P_Signal; //Serial.print("Noise + Signal = "); Serial.println(Noise_P_Signal); //Serial.print("Noise ="); Serial.println(Noise); //Serial.print ("--> Signal ="); Serial.println (Signal); //temperature = (mlx.get_object_temp()) + error_correction; //Serial.println(temperature,1); //delay(100); if (Signal>Range_sensitivity && Noise >500) // уменьшаем сигнал чтобы увеличить диапазон { if (trigger == true) Serial.println("start"); digitalWrite(2,LOW); //выключаем инфракрасный датчик чтобы предотвратить помехи for (int i=1; i<=3; i++) { temperature = (mlx.get_object_temp()) + error_correction; Serial.println(temperature,1); delay(150); } trigger = false; } else { delay(100); trigger = true; digitalWrite(13,LOW); Serial.println("position_error"); } } |