Temperature Checker
The goal of this project is to create a new object that would be able to detect changes in body temperature
With Covid it was difficult to understand if people started to have temperature because it is not felt in the first 2 days but during these days people would be contagious.
So my idea was to have an early warning system that would check my temperature each time I was in front of the mirror in the bathroom
I named this object Early Temperature Detector (EDT)
Please note, this instructable uses degree celcius and centimeters
Supplies
https://eu.mouser.com/ProductDetail/DFRobot/SEN0263?qs=%252BEew9%252B0nqrB%2FzoCKvi5KUA==
https://supergyg.com/index.php?main_page=product_info&products_id=550903
https://www.amazon.com/gp/product/B072Q2X2LL/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1
https://www.amazon.com/gp/product/B012ZZ4LPM/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1
https://store-usa.arduino.cc/products/arduino-mkr-wifi-1010
https://www.amazon.com/Breadboard-Solderless-Prototype-PCB-Board/dp/B077DN2PS1/ref=sxin_22_ac_d_rm?ac_md=3-3-YnJlYWRib2FyZHMgYXJkdWlubw%3D%3D-ac_d_rm_rm_rm&cv_ct_cx=breadboard&dchild=1&keywords=breadboard&pd_rd_i=B077DN2PS1&pd_rd_r=4f078da9-8d23-4d05-8f11-854eb2419a75&pd_rd_w=4CqY4&pd_rd_wg=lc0tV&pf_rd_p=de2528a5-aaee-45ae-afe7-277ddc135414&pf_rd_r=6DH1DET9VKDHAMCQN3T1&psc=1&qid=1635700793&sr=1-4-12d4272d-8adb-4121-8624-135149aa9081
General Concept
Step one is to design the concept. Other concepts could be derived from what i did
EDT can work on battery or with USB plug: https://www.arduino.cc/en/Guide/MKRWiFi1010/powering-with-batteries
If EDT is battery powered, saving energy is critical so i put a motion detector. if there is no motion the software and other components do not work. If EDT runs on USB plug then no need to have a motion detector.
The infrared thermal camera loses precisions as the target measure is further away and that is why I connected a range sensor to measure the distance. The goal is to define the most precise distance at which the measure needs to take place. I took multiple measures and plotted this chart. It is in centimeters for distance horizontally and degree Celsius vertically. What the chart is telling us is that as long as the targeted object is within 30 cm, the readings are accurate enough
for quality control i added a LED screen to plot both distance and temperature and other useful information if needed
finally the led changes color depending on the detected temperature. Right now i have 3 options:
- green no temperature
- yellow some temperature
- red high temperature
you can easily add intermediate options
I selected an Arduino MKR Wifi1010 so i could potentially store all measurements to the cloud and look at trends or even use machine learning algorythms to detect different users.
Finally i also added a buzzer in case you want EDT to work for visually impaired
Wiring
you can see the complete wiring from all of the pictures
Prototype
In order to test, you need a flat surface. here i used a cardboard to embed all the components
Coding
#include <Wire.h>
//LED
#include <FastLED.h>
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS 6
CRGB leds[NUM_LEDS];
#define DATA_PIN 2
#define SSD1306_BLACK 0
#define SSD1306_WHITE 1
#define SSD1306_INVERSE 2
#define BRIGHTNESS 96
int indexLight=0;
bool interruptOccurred = false;
void interruptCallback(){
interruptOccurred = true;
}
//range sensor
#include <VL53L1X.h>
VL53L1X RangeSensor;
//thermal camera
#include <Adafruit_MLX90614.h>
Adafruit_MLX90614 MLX90614 = Adafruit_MLX90614();
//lcd screen
#include <ArducamSSD1306.h> // Modification of Adafruit_SSD1306 for ESP8266 compatibility
#define OLED_RESET 16 // Pin 15 -RESET digital signal
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
ArducamSSD1306 display(OLED_RESET); // FOR I2C
//timer motion
unsigned long DELAY_TIME = 5000; // 5 sec
unsigned long delayStart = 0; // the time the delay started
bool delayRunning = false; // true if still waiting for delay to finish
void setup() {
//serial monitor
Serial.begin(115200);
Wire.begin();
Wire.setClock(400000); // use 400 kHz I2C
InitRangeSensor();
//buzzer
pinMode(5, OUTPUT);
//motion
pinMode(1, INPUT);
//thermal camera
MLX90614.begin();
//led
FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
//blue led
setcolor(3);
// start measuring time for motion sensor
delayStart = millis();
//LCD display init
display.begin(); // Switch OLED
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.display();
ShowLabel("Init...");
//ConnectWifi();
}
void loop() {
indexLight++;
int Motion = digitalRead(1);
double range=RangeSensor.ranging_data.range_mm;
range=RangeSensor.read();
Serial.println(range);
if ((Motion) || (range<700)){
delayStart = millis();
//Serial.println("Motion");
}
else{
//Serial.println("No presence");
}
if (millis() - delayStart < DELAY_TIME)
{
//double TempObject=MLX90614.readObjectTemp();
double TempObject=MLX90614.readObjectTempC();
Serial.println(TempObject);
if (range<700)
{
ShowMeasures(TempObject,range);
if (TempObject>32)
{
//tone(5, 1000);
setcolor(1);
}
else if (TempObject>29)
{
setcolor(4);
//noTone(5);
//indexLight=0;
}
else
{
setcolor(2);
//noTone(5);
}
}
else{
setcolor(5);
//noTone(5);
ShowLabel("Too far");
}
delay(200);
}
else
{
//noTone(5);
setcolor(0);
ShowLabel("No Motion");
}
}
void InitRangeSensor()
{
// Enable the data ready interrupts
/*sensor.enableInterruptOnDataReady();
sensor.startMeasurement();*/
RangeSensor.setTimeout(500);
if (!RangeSensor.init())
{
Serial.println("Failed to detect and initialize sensor!");
while (1);
}
// Use long distance mode and allow up to 50000 us (50 ms) for a measurement.
// You can change these settings to adjust the performance of the sensor, but
// the minimum timing budget is 20 ms for short distance mode and 33 ms for
// medium and long distance modes. See the VL53L1X datasheet for more
// information on range and timing limits.
RangeSensor.setDistanceMode(VL53L1X::Long);
RangeSensor.setMeasurementTimingBudget(50000);
// Start continuous readings at a rate of one measurement every 50 ms (the
// inter-measurement period). This period should be at least as long as the
// timing budget.
RangeSensor.startContinuous(50);
}
void setcolor(int Color)
{
double Rvalue1=255, Rvalue2=128;
for (int i=0;i<NUM_LEDS;i++)
{
if (Color==0) //off
leds[i] = CRGB(0,0,0);
else if (Color==1) //red
leds[i] = CRGB(255,0,0);
else if (Color==2) //Green
leds[i] = CRGB(0,255,0);
else if (Color==3) //Blue
leds[i] = CRGB(0,0,255);
else if (Color==4) //yellow
leds[i] = CRGB(255,128,0);
else if (Color==5) //white
leds[i] = CRGB(255,255,255);
}
FastLED.show();
//delay(17);
}
double getcolorintensity(int timelength,int NumLed,int Compression,int LedCycle)
{
double Rvalue = 0.5*pow(((sin(-1.570796+(1.047198*NumLed)+(timelength*6.28319/LedCycle))+1)/2),Compression);
return Rvalue;
}
void ShowMeasures(double temperature, double range)
{
display.clearDisplay();
display.setCursor(10,20);
display.print(temperature);
display.setCursor(55,20);
display.print(" C");
String stringOne = String(range/10,0)+" cm";
display.setCursor(10,40);
display.print(stringOne);
display.display();
}
void ShowLabel(char Label[])
{
display.clearDisplay();
display.setCursor(5,30);
display.print(Label);
display.display();
}
void testdrawline() {
int16_t i;
display.clearDisplay(); // Clear display buffer
for(i=0; i<display.width(); i+=4) {
display.drawLine(0, 0, i, display.height()-1, SSD1306_WHITE);
display.display(); // Update screen with each newly-drawn line
delay(1);
}
for(i=0; i<display.height(); i+=4) {
display.drawLine(0, 0, display.width()-1, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for(i=0; i<display.width(); i+=4) {
display.drawLine(0, display.height()-1, i, 0, SSD1306_WHITE);
display.display();
delay(1);
}
for(i=display.height()-1; i>=0; i-=4) {
display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for(i=display.width()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE);
display.display();
delay(1);
}
for(i=display.height()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for(i=0; i<display.height(); i+=4) {
display.drawLine(display.width()-1, 0, 0, i, SSD1306_WHITE);
display.display();
delay(1);
}
for(i=0; i<display.width(); i+=4) {
display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_WHITE);
display.display();
delay(1);
}
delay(2000); // Pause for 2 seconds
}
Downloads
Making the Case
i worked with a friend to use the free 3d Modeler Fusion 360 to design a basic case and 3D print it
depending on component and bread board you can easily design a case
mine is a bit tied. its good for the bread board as it does not move on the longer side but i wish i add more room as i had to reconnect the wires and did not have a lot of room