|
|
| Line 257: |
Line 257: |
|
| |
|
| ===Defines - Variables - Routines=== | | ===Defines - Variables - Routines=== |
| <code> | | <nowiki> |
| //low range of the sensor (this will be blue on the screen)
| | #include <Wire.h> |
| | #include <SPI.h> |
|
| |
|
| <nowiki>#</nowiki>define MINTEMP 20 | | #include <Adafruit_GFX.h> |
| | #include <Adafruit_ST7735.h> |
| | #include "Adafruit_VL53L0X.h" |
| | #include <Adafruit_AMG88xx.h> |
| | #include <MAX30105.h> |
| | #include <SparkFunMLX90614.h> |
| | #include <DFRobot_ID809.h> |
| | #include "bmpHeader.h" |
| | #include <SD.h> |
|
| |
|
| //high range of the sensor (this will be red on the screen)
| | #include "TFT_Stuff.h" |
|
| |
|
| <nowiki>#</nowiki>define MAXTEMP 28
| | #include "HB_Stuff.h" |
| | | #include "AMG_Stuff.h" |
| //the colors we will be using
| | #include "VL_Stuff.h" |
| | | #include "CT_Stuff.h" |
| const uint16_t camColors[] = {0x480F,
| | #include "FP_Stuff.h" |
| 0x400F, 0x400F, 0x400F, 0x4010, 0x3810, 0x3810, 0x3810, 0x3810, 0x3010, 0x3010,
| |
| 0x3010, 0x2810, 0x2810, 0x2810, 0x2810, 0x2010, 0x2010, 0x2010, 0x1810, 0x1810,
| |
| 0x1811, 0x1811, 0x1011, 0x1011, 0x1011, 0x0811, 0x0811, 0x0811, 0x0011, 0x0011,
| |
| 0x0011, 0x0011, 0x0011, 0x0031, 0x0031, 0x0051, 0x0072, 0x0072, 0x0092, 0x00B2,
| |
| 0x00B2, 0x00D2, 0x00F2, 0x00F2, 0x0112, 0x0132, 0x0152, 0x0152, 0x0172, 0x0192,
| |
| 0x0192, 0x01B2, 0x01D2, 0x01F3, 0x01F3, 0x0213, 0x0233, 0x0253, 0x0253, 0x0273,
| |
| 0x0293, 0x02B3, 0x02D3, 0x02D3, 0x02F3, 0x0313, 0x0333, 0x0333, 0x0353, 0x0373,
| |
| 0x0394, 0x03B4, 0x03D4, 0x03D4, 0x03F4, 0x0414, 0x0434, 0x0454, 0x0474, 0x0474,
| |
| 0x0494, 0x04B4, 0x04D4, 0x04F4, 0x0514, 0x0534, 0x0534, 0x0554, 0x0554, 0x0574,
| |
| 0x0574, 0x0573, 0x0573, 0x0573, 0x0572, 0x0572, 0x0572, 0x0571, 0x0591, 0x0591,
| |
| 0x0590, 0x0590, 0x058F, 0x058F, 0x058F, 0x058E, 0x05AE, 0x05AE, 0x05AD, 0x05AD,
| |
| 0x05AD, 0x05AC, 0x05AC, 0x05AB, 0x05CB, 0x05CB, 0x05CA, 0x05CA, 0x05CA, 0x05C9,
| |
| 0x05C9, 0x05C8, 0x05E8, 0x05E8, 0x05E7, 0x05E7, 0x05E6, 0x05E6, 0x05E6, 0x05E5,
| |
| 0x05E5, 0x0604, 0x0604, 0x0604, 0x0603, 0x0603, 0x0602, 0x0602, 0x0601, 0x0621,
| |
| 0x0621, 0x0620, 0x0620, 0x0620, 0x0620, 0x0E20, 0x0E20, 0x0E40, 0x1640, 0x1640,
| |
| 0x1E40, 0x1E40, 0x2640, 0x2640, 0x2E40, 0x2E60, 0x3660, 0x3660, 0x3E60, 0x3E60,
| |
| 0x3E60, 0x4660, 0x4660, 0x4E60, 0x4E80, 0x5680, 0x5680, 0x5E80, 0x5E80, 0x6680,
| |
| 0x6680, 0x6E80, 0x6EA0, 0x76A0, 0x76A0, 0x7EA0, 0x7EA0, 0x86A0, 0x86A0, 0x8EA0,
| |
| 0x8EC0, 0x96C0, 0x96C0, 0x9EC0, 0x9EC0, 0xA6C0, 0xAEC0, 0xAEC0, 0xB6E0, 0xB6E0,
| |
| 0xBEE0, 0xBEE0, 0xC6E0, 0xC6E0, 0xCEE0, 0xCEE0, 0xD6E0, 0xD700, 0xDF00, 0xDEE0,
| |
| 0xDEC0, 0xDEA0, 0xDE80, 0xDE80, 0xE660, 0xE640, 0xE620, 0xE600, 0xE5E0, 0xE5C0,
| |
| 0xE5A0, 0xE580, 0xE560, 0xE540, 0xE520, 0xE500, 0xE4E0, 0xE4C0, 0xE4A0, 0xE480,
| |
| 0xE460, 0xEC40, 0xEC20, 0xEC00, 0xEBE0, 0xEBC0, 0xEBA0, 0xEB80, 0xEB60, 0xEB40,
| |
| 0xEB20, 0xEB00, 0xEAE0, 0xEAC0, 0xEAA0, 0xEA80, 0xEA60, 0xEA40, 0xF220, 0xF200,
| |
| 0xF1E0, 0xF1C0, 0xF1A0, 0xF180, 0xF160, 0xF140, 0xF100, 0xF0E0, 0xF0C0, 0xF0A0,
| |
| 0xF080, 0xF060, 0xF040, 0xF020, 0xF800,
| |
| };
| |
| | |
| Adafruit_AMG88xx amg;
| |
| | |
| unsigned long delayTime;
| |
| | |
| <nowiki>#</nowiki>define AMG_COLS 8
| |
| | |
| <nowiki>#</nowiki>define AMG_ROWS 8
| |
| | |
| float pixels[AMG_COLS * AMG_ROWS];
| |
| | |
| <nowiki>#</nowiki>define INTERPOLATED_COLS 24
| |
| | |
| <nowiki>#</nowiki>define INTERPOLATED_ROWS 24
| |
| | |
| | |
| float get_point(float *p, uint8_t rows, uint8_t cols, int8_t x, int8_t y);
| |
| | |
| void set_point(float *p, uint8_t rows, uint8_t cols, int8_t x, int8_t y, float f);
| |
| | |
| void get_adjacents_1d(float *src, float *dest, uint8_t rows, uint8_t cols, int8_t x, int8_t y);
| |
| | |
| void get_adjacents_2d(float *src, float *dest, uint8_t rows, uint8_t cols, int8_t x, int8_t y);
| |
| | |
| float cubicInterpolate(float p[], float x);
| |
| | |
| float bicubicInterpolate(float p[], float x, float y);
| |
| | |
| void interpolate_image(float *src, uint8_t src_rows, uint8_t src_cols, float *dest, uint8_t dest_rows, uint8_t dest_cols);
| |
| | |
| void setup_AMG()
| |
| {
| |
| | |
| if (!amg.begin())
| |
| {
| |
| Serial.println("Could not find a valid AMG88xx sensor, check wiring!");
| |
| | |
| while (1) { delay(1); }
| |
| }
| |
| | |
| // Serial.println("-- Thermal Camera Test --");
| |
| | |
| }
| |
| | |
| | |
| void drawpixels(int x_offset, int y_offset, float *p, uint8_t rows, uint8_t cols, uint8_t boxWidth, uint8_t boxHeight)
| |
| {
| |
| int colorTemp;
| |
| // int x_offset = 4, y_offset = 0;
| |
|
| |
| for (int y = 0; y < rows; y++)
| |
| {
| |
| for (int x = 0; x < cols; x++)
| |
| {
| |
| float val = get_point(p, rows, cols, x, y);
| |
| if (val >= MAXTEMP) colorTemp = MAXTEMP;
| |
| else if (val <= MINTEMP) colorTemp = MINTEMP;
| |
| else colorTemp = val;
| |
| | |
| uint8_t colorIndex = map(colorTemp, MINTEMP, MAXTEMP, 0, 255);
| |
| colorIndex = constrain(colorIndex, 0, 255);
| |
| //draw the pixels!
| |
| uint16_t color;
| |
| color = val * 2;
| |
| tft.fillRect(x_offset + (boxWidth * x), y_offset + (((rows-1) - y) * boxHeight), boxWidth, boxHeight, camColors[colorIndex]);
| |
| }
| |
| }
| |
| }
| |
| | |
| int AMG_x_offset = 44;
| |
| int AMG_y_offset = 0;
| |
| int AMG_x_width = 74;
| |
| int AMG_y_height = 74;
| |
| | |
| | |
| void AMG_Frame()
| |
| {
| |
| | |
| int AMG_box_top = AMG_y_offset;
| |
| int AMG_box_left = AMG_x_offset;
| |
| int AMG_box_bottom = AMG_box_top + AMG_y_height;
| |
| int AMG_box_right = AMG_box_left + AMG_x_width;
| |
| int AMG_box_width = AMG_x_width;
| |
| int AMG_box_height = AMG_y_height;
| |
| int AMG_frame_left = AMG_box_left + 1;
| |
| int AMG_frame_top = AMG_box_top + 1;
| |
|
| |
| int box_size = 3;
| |
|
| |
| //read all the pixels
| |
| amg.readPixels(pixels);
| |
| float dest_2d[INTERPOLATED_ROWS * INTERPOLATED_COLS];
| |
| int32_t t = millis();
| |
| interpolate_image(pixels, AMG_ROWS, AMG_COLS, dest_2d, INTERPOLATED_ROWS, INTERPOLATED_COLS);
| |
| // Serial.print("Interpolation took "); Serial.print(millis() - t); Serial.println(" ms");
| |
| // uint16_t boxsize = min(tft.width() / INTERPOLATED_COLS, tft.height() / INTERPOLATED_COLS);
| |
| tft.drawRect(AMG_box_left, AMG_box_top, AMG_box_width, AMG_box_height, ST7735_ORANGE);
| |
| drawpixels(AMG_frame_left,AMG_frame_top,dest_2d, INTERPOLATED_ROWS, INTERPOLATED_COLS, box_size, box_size);
| |
| }
| |
|
| |
|
| void setup() | | void setup() |
| Line 416: |
Line 299: |
| Serial.println("SETUP - End"); | | Serial.println("SETUP - End"); |
| } | | } |
| | |
| | |
|
| |
|
| void loop() | | void loop() |
| Line 425: |
Line 310: |
| HB_Frame(); | | HB_Frame(); |
| } | | } |
| | | </nowiki> |
| </code> | |
Pseudo-Medical Monitor for Christmas Cheap Gift
In preparation for the expected Christmas Gift availability crisis, I present the Pseudo-Gift of the season. The time honored tradition of knockoff products hitting the market before Christmas is alive and well. What better than a multi-property knockoff device? Star Trek / Arduino / Medical knockoff device gift for everyone. This Pseudo-Medical Tricorder ripoff is the stocking stuffer for 2021.
Operations
- Thermal Image from AMG8833 Sensor.
- Ambient and Object Temperature from MLX90614 Sensor.
- Distance of device from user via VL53L0X Laser TOF Sensor.
- Pulse Rate from MAX30102 Sensor
- Fingerprint Scan image capture from Capacitive Sensor with ID809 processing capabilities.
Parts List
- Arduino Due Generic Clone (alternative: ITEADUINO DUE)
- Arduino Mega Prototype Shield Generic Clone (alternative: KEYESTUDIO)
- MLX90614 Contactless Temperature Sensor Generic Clone (alternative: )
- AMG8833 Thermal Imager Sensor Generic Clone (alternative: TinyCircuits)
- VL53L0X TOF Laser Distance Sensor Generic Clone (alternative: Onyehn)
- MAX30102 Pulse and O2 Saturation Sensor Generic Clone (alternative: MH-ET Live)
- Capacitive Touch Fingerprint Scanner Generic Clone (alternative: DFROBOT)
- 160x128 LCD TFT SPI 1.8" Module with SD Socket Generic Clone (alternative: Heyaodz111208)
Wiring
| Pin Mapping
|
| Due Pin
|
Function
|
MLX90614
|
AMG8833
|
VL53L0X
|
MAX30102
|
FP Scan
|
TFT
|
SD Socket
|
| 3
|
Interrupt
|
|
|
|
|
IRQ
|
|
|
| 4
|
Interrupt
|
|
|
|
INT
|
|
|
|
| 5
|
Interrupt
|
|
INT
|
|
|
|
|
|
| 6
|
Digital I/O
|
|
|
GPIO1
|
|
|
|
|
| 7
|
Digital I/O
|
|
|
XSHUT
|
|
|
|
|
| 8
|
Digital I/O
|
|
|
|
|
|
|
SD_CS
|
| 9
|
Digital I/O
|
|
|
|
|
|
RST
|
|
| 10
|
Digital I/O
|
|
|
|
|
|
CS
|
|
| 11
|
Digital I/O
|
|
|
|
|
|
AO
|
|
| 18
|
TX_1
|
|
|
|
|
RX
|
|
|
| 19
|
RX_1
|
|
|
|
|
TX
|
|
|
| 20
|
SDA
|
SDA
|
SDA
|
SDA
|
SDA
|
|
|
|
| 21
|
SCL
|
SCL
|
SCL
|
SCL
|
SCL
|
|
|
|
| SPI
|
MISO
|
|
|
|
|
|
|
SD_MISO
|
| SPI
|
MOSI
|
|
|
|
|
|
SDA
|
SD_MOSI
|
| SPI
|
SCK
|
|
|
|
|
|
SCK
|
SD_SCK
|
Code
Libraries
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <Adafruit_VL53L0X.h>
#include <Adafruit_AMG88xx.h>
#include <MAX30105.h>
#include <SparkFunMLX90614.h>
#include <DFRobot_ID809.h>
#include <SD.h>
Library Modification
// In this Library : #include <SparkFunMLX90614.h>
//Change the following line in the bool IRTherm::I2CReadWord(byte reg, int16_t * dest) routine.
//
// I2C processing change needed for Arduino Due implementation
//
// Comment Out Line Below
// _i2cPort->requestFrom(_deviceAddress, (uint8_t) 3, (uint8_t) true);
// Add Line Below
_i2cPort->requestFrom(_deviceAddress, (uint8_t) 3, (uint32_t)reg, (uint8_t)1, (uint8_t)true);
Defines - Variables - Routines
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include "Adafruit_VL53L0X.h"
#include <Adafruit_AMG88xx.h>
#include <MAX30105.h>
#include <SparkFunMLX90614.h>
#include <DFRobot_ID809.h>
#include "bmpHeader.h"
#include <SD.h>
#include "TFT_Stuff.h"
#include "HB_Stuff.h"
#include "AMG_Stuff.h"
#include "VL_Stuff.h"
#include "CT_Stuff.h"
#include "FP_Stuff.h"
void setup()
{
Wire.begin();
Serial.begin(115200);
Serial.println("SETUP - Begin");
Serial.println("TFT");
setup_TFT();
Serial.println("CT");
setup_CT();
Serial.println("AMG");
setup_AMG();
Serial.println("VL");
setup_VL();
Serial.println("HB");
setup_HB();
Serial.println("FP");
setup_FP();
Serial.println("SETUP - End");
}
void loop()
{
VL_Frame();
AMG_Frame();
CT_Frame();
FP_Frame();
HB_Frame();
}