Бесконтактный указатель температуры с передачей данных в скопление

Эпидемия COVID-19 распространилась на огромную часть мира. Одним из симптомов инфекции (Термин означает различные виды взаимодействия чужеродных микроорганизмов с организмом человека) является увеличение температуры, сухой кашель и одышка. Контроль температуры является принципиальным инвентарем в данных критериях. В особенности это принципиально для людей, которые хворают в легкой форме в домашних критериях.

Инфракрасный указатель температуры — это самый резвый метод выяснить, высочайшая температура нет. Инфракрасный указатель температуры указывает температуру одномоментно. Можно отыскать бесконтактные инфракрасные указатели температуры в продаже, но не один из их не поддерживает функции IoT для сбора, классификации и ранения данных о температуре. Чтоб решить эту делему, мастер сделал указатель температуры IoT, который автоматом посылает данные на пасмурный сервер.

Инструменты и материалы:
-Модуль инфракрасного датчика температуры MLX90614;
-Wemos D1 mini ESP8266;
-0,96-дюймовый OLED-дисплей;
-Литий-ионная батарея 18650;
-Модуль зарядки литий-ионной батареи 1A TP4056;
-3D-принтер;
-Паяльная станция;
-Тактовая клавиша — 4 шт;
-Провода;

Шаг 1-ый: общие сведения
Функции указателя температуры:
1. Бесконтактный
2. Аккумуляторный
3. Поддержка WiFi и хранение данных в облаке
4. Просмотр данных из облака
5. Автоматический режим энергосбережения
6. Настройка и калибровка

В датчик MLX90614 встроено два устройства: одно — инфракрасный датчик, а другое — устройство обработки сигналов DSP (вычислительный модуль). Он работает на базе закона Стефана-Больцмана, который говорит, что все объекты источают инфракрасную энергию, и интенсивность данной энергии будет прямо пропорциональна температуре этого объекта. Чувствительный элемент в датчике определяет, сколько ИК (то есть тепловое, инфракрасное, на основе инфракрасного излучения)-энергии излучается объектом, а вычислительный модуль конвертирует ее в значение температуры при помощи встроенного 17-разрядного АЦП и выводит данные по протоколу связи I2C. Датчик определяет как температуру объекта, так и температуру окружающей среды для калибровки значения температуры объекта.

Wemos D1 mini — это модуль с Wi-Fi на ESP8266. Он имеет один аналоговый порт и 11 цифровых портов.
Светодиодный экран (OLED), который будет употребляться в данном проекте, — это модель SSD1306: одноцветный 0,96-дюймовый экран с разрешением 128 × 64 пикселей. OLED-дисплей не нуждается в подсветки и весьма экономный.

Шаг 2-ой: 3D дизайн и печать
Корпус для собственного устройства мастер напечатал на 3D-принтере. За шаблон он брал работу другого мастера. Скачал файл и занес в него некие конфигурации. К примеру, переработал нишу для батареи с 9 вольтовой на 18650.

Файлы для печати можно скачать ниже.
IoT Thermometer back.stl
IoT Thermometer display panel.stl
IoT Thermometer front.stl
IoT Thermometer sensor panel.stl

Шаг 3-ий: сборка
Опосля распечатки всех файлов мастер начинает сборку устройства. Поначалу необходимо приготовить плату управления с экраном. Плату обрезает в согласовании с размером фронтальной панели (28 мм х 48 мм). Монтирует три тактильные клавиши. Одна клемма всех переключателей обязана быть соединена совместно, и в предстоящем припаяна к минусу.

Опосля монтажа клавиш последующая задачка — установка монитора. Для размещения платы Wemos D1 была вырезана еще одна монтажная плата. Кабель монитора и перемычки от плат клавиш должны быть подключены к гнездовым разъемам. Потом необходимо подключить еще одну клавишу к плате, которая будет употребляться для измерения и загрузки данных в скопление и инфракрасный датчик.

В устройстве будет употребляться литий-ионная аккумуляторная батарея 18650. Аккумулятор будет установлен в ручке устройства. Для защиты и зарядки батареи употребляется модуль зарядки.

Сам модуль зарядки тоже располагается в ручке.

В верней части ручки устанавливается выключатель. При помощи него устройство будет включатся и выключатся.

Шаг 4-ый: загрузка кода
Перед загрузкой кода нужно приготовить учетную запись Adafruit IO. Наиболее тщательно как это создать можно прочитать тут. Сейчас необходимо загрузить код.

 Скетч/* This code works with MLX90614 (GY906) and OLED screen
* It measures both ambient and object temperature in Fahrenheit and display it on the screen
*
*
*
*/
#include
#include
#include
#include
#include
#include
#include
#include "AdafruitIO_WiFi.h"
#include
#include "Arduino.h"

#define IO_USERNAME "Your Adafruit IO Username"
#define IO_KEY "Your Adafruit IO Key"
#define WIFI_SSID "your wifi ssid"
#define WIFI_PASS "your wifi password"
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)

#define MENU D5
#define UP D6
#define DOWN D7
#define MEASURE D4

int menu = 0;
int celcius = 0;
int wifi = 1;
int body_temp = 1;
int patient_id = 1;
int display_on = 1;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaring the display name (display)
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);
//AdafruitIO_Feed *temperature = io.feed("temperature");

void setup() {

pinMode(MENU, INPUT_PULLUP);
pinMode(UP, INPUT_PULLUP);
pinMode(DOWN, INPUT_PULLUP);
pinMode(MEASURE, INPUT_PULLUP);

/************************Read Configuration fromEEPROM***************************/
EEPROM.begin(512); //Initialize EEPROM
celcius = EEPROM.read(0);
wifi = EEPROM.read(1);
body_temp = EEPROM.read(2);

mlx.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Start the OLED display

home_page();

Serial.begin(9600);
delay(10000);
// connect to io.adafruit.com
if(wifi)connectAIO();
if(io.status() < AIO_CONNECTED){
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setFont();
display.setCursor(0,20);
display.println("No Internet Access!");
display.display();
delay(3000);
}

// we are connected
Serial.println();
Serial.println(io.statusText());

}

long time_count = millis();
void loop() {

if(!digitalRead(MENU)){
time_count = millis();
delay(200);
menu++;
if(menu>3) {
menu = 0;
EEPROM.write(0, celcius);
EEPROM.write(1, wifi);
EEPROM.write(2, body_temp);
EEPROM.commit();
}
}

if(!digitalRead(UP)){
time_count = millis();
delay(200);
if(menu==0) patient_id++;
if(menu==1) celcius = 1;
if(menu==2) wifi = 1;
if(menu==3) body_temp = 1;
}

if(!digitalRead(DOWN)){
time_count = millis();
delay(200);
if(menu==0) patient_id—;
if(menu==1) celcius = 0;
if(menu==2) wifi = 0;
if(menu==3) body_temp = 0;
}

if(wifi){
if(WiFi.status() != WL_CONNECTED){
WiFi.forceSleepWake();
delay(1);
WiFi.mode(WIFI_STA); //
WiFi.begin(WIFI_SSID, WIFI_PASS); //
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial1.print(".");
}
}
}

if(!wifi){
WiFi.disconnect(); //
WiFi.mode(WIFI_OFF);//
WiFi.forceSleepBegin();
delay(100);
}

if(menu == 0) home_page();
else if(menu == 1) scale_setup_page();
else if(menu == 2) wifi_setup_page();
else if(menu == 3) temp_setup_page();

if(!digitalRead(MEASURE)){
time_count = millis();
display.ssd1306_command(SSD1306_DISPLAYON);
display_on = 1;
Serial.println("Button Press");
delay(5000);
if(wifi){
if(io.status() >= AIO_CONNECTED){temp_write();
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setFont();
display.setCursor(0,20);
display.println("Data Sent!");
display.display();
delay(1500);
}
else{
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setFont();
display.setCursor(0,10);
display.println("No Internet access!");
display.display();
delay(1500);
}
}
//delay(3000);
}

if((millis()>= time_count + 50000) && display_on == 1){
display.ssd1306_command(SSD1306_DISPLAYOFF);
display_on = 0;
}

//display.ssd1306_command(SSD1306_DISPLAYON);
//io.run();
//temperature->save(tempF);
//delay(3000);

}

void home_page(){
float body_tempF = mlx.readObjectTempF()+ 4.5;
float ambient_tempF = mlx.readAmbientTempF();
float body_tempC = (body_tempF-32)/1.8;
float ambient_tempC = (ambient_tempF-32)/1.8;
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setFont();
display.setCursor(0,0);
if(body_temp)
display.println("Body Temperature");
else
display.println("Ambient Temp");
display.setFont(&FreeSerif12pt7b);
display.setCursor(20,40);
if(body_temp && celcius) display.println(body_tempC,2);
else if(body_temp && !celcius) display.println(body_tempF,2);
else if(!body_temp && !celcius) display.println(ambient_tempF,2);
else if(!body_temp && celcius) display.println(ambient_tempC,2);
//display.println(mlx.readObjectTempF()+4.5,2);
display.setCursor(80,40);
display.drawCircle(85, 28, 3, WHITE);
if(celcius) display.println(" C");
else display.println(" F");
display.setFont();
display.setCursor(0,55);
display.print("ID: P0");
display.println(String(patient_id));
display.setCursor(70,55);
if(WiFi.status() == WL_CONNECTED) display.println("WiFi: ON");
else display.println("WiFi: OFF");
display.display();
}

void scale_setup_page(){
display.clearDisplay();
display.setTextColor(WHITE);
display.setFont(&FreeSerif9pt7b);
display.setCursor(0,13);
display.println("Temp Scale");
display.setFont(&FreeSerif12pt7b);
display.drawCircle(65, 25, 3, WHITE);
display.drawRect(35, 25, 15, 15, WHITE);
display.setCursor(70,39);
display.println("C");
display.drawCircle(65, 45, 3, WHITE);
display.drawRect(35, 45, 15, 15, WHITE);
display.setCursor(70,60);
display.println("F");
if(celcius)
display.fillRect(37, 27, 11, 11, INVERSE);
else
display.fillRect(37, 47, 11, 11, INVERSE);
display.display();
}

void wifi_setup_page(){
display.clearDisplay();
display.setTextColor(WHITE);
display.setFont(&FreeSerif9pt7b);
display.setCursor(0,13);
display.println("WiFi Setup");
display.setFont(&FreeSerif12pt7b);
display.drawRect(10, 25, 15, 15, WHITE);
display.setCursor(40,39);
display.println("Enable");
display.drawRect(10, 45, 15, 15, WHITE);
display.setCursor(40,60);
display.println("Disable");
if(wifi)
display.fillRect(12, 27, 11, 11, INVERSE);
else
display.fillRect(12, 47, 11, 11, INVERSE);
display.display();
}

void temp_setup_page(){
display.clearDisplay();
display.setTextColor(WHITE);
display.setFont(&FreeSerif9pt7b);
display.setCursor(0,13);
display.println("Temperature");
display.setFont(&FreeSerif12pt7b);
display.drawRect(10, 25, 15, 15, WHITE);
display.setCursor(40,39);
display.println("Body");
display.drawRect(10, 45, 15, 15, WHITE);
display.setCursor(40,60);
display.println("Ambient");
if(body_temp)
display.fillRect(12, 47, 11, 11, INVERSE);
else
display.fillRect(12, 27, 11, 11, INVERSE);
display.display();
}

void power_saving_mode(){
display.ssd1306_command(SSD1306_DISPLAYOFF);
//wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
wifi_fpm_open(); // Enables force sleep
//wifi_fpm_set_wakeup_cb(callback);
gpio_pin_wakeup_enable(GPIO_ID_PIN(MEASURE), GPIO_PIN_INTR_LOLEVEL); // GPIO_ID_PIN(2) corresponds to GPIO2 on ESP8266-01 , GPIO_PIN_INTR_LOLEVEL for a logic low, can also do other interrupts, see gpio.h above
wifi_fpm_do_sleep(0xFFFFFFF); // Sleep for longest possible time
}

void callback() {
display.ssd1306_command(SSD1306_DISPLAYON);
Serial1.println("Callback");
Serial.flush();
}

void temp_write(){
// set up `deepsleep` feed
String str = "P0";
str += patient_id;
int str_len = str.length() + 1;
char char_array[str_len];
str.toCharArray(char_array, str_len);
AdafruitIO_Feed *temperature = io.feed(char_array);
Serial.println("sending temperature to feed");
float body_tempF = mlx.readObjectTempF()+ 4.5;
float ambient_tempF = mlx.readAmbientTempF();
float body_tempC = (body_tempF-32)/1.8;
float ambient_tempC = (ambient_tempF-32)/1.8;

if(body_temp && celcius) temperature->save(body_tempC,2);
else if(body_temp && !celcius) temperature->save(body_tempF,2);
else if(!body_temp && !celcius) temperature->save(ambient_tempF,2);
else if(!body_temp && celcius) temperature->save(ambient_tempC,2);
// send data to deepsleep feed
//temperature->save(temp);
// write data to AIO
io.run();
}

void connectAIO() {
Serial.println("Connecting to Adafruit IO…");
io.connect();
long entering_time = millis();
// wait for a connection
while ((io.status() < AIO_CONNECTED) || (millis()> entering_time + 15000)) {
Serial.print(".");
delay(500);
}

// we are connected
Serial.println();
Serial.println(io.statusText());
}

Ну и крайний шаг — окончательная сборка.
Мастер устанавливает экран в корпус.

Закрепляет датчик, все платы, переключатели, клавиши. Собирает детали корпуса.

Все готово.

Источник (Source)