Difference between revisions of "Pseudo-Medical Monitor Code"

From LVL1
Jump to navigation Jump to search
 
(37 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Special Libraries ==
+
Being written on the fly, expect rewrites and restructures.  Enough information is here for writing code on the completed hardware. 
<code>
 
  
<nowiki>#</nowiki>include <Adafruit_GFX.h>
+
= Basic Software Load for Main Device Only. Later Update to Incorporate Port Usage with External Units. =
  
<nowiki>#</nowiki>include <Adafruit_ST7735.h>
+
== Hardware Libraries ==
 
+
<nowiki>
<nowiki>#</nowiki>include <Adafruit_VL53L0X.h>
+
#include <Wire.h>
 
+
#include <SPI.h>
<nowiki>#</nowiki>include <Adafruit_AMG88xx.h>
+
#include <Adafruit_GFX.h>
 
+
#include <Adafruit_ST7735.h>
<nowiki>#</nowiki>include <MAX30105.h>
+
#include <Adafruit_VL53L0X.h>
 
+
#include <Adafruit_AMG88xx.h>
<nowiki>#</nowiki>include <SparkFunMLX90614.h>  
+
#include <MAX30105.h>
 
+
#include <SparkFunMLX90614.h>  
<nowiki>#</nowiki>include <DFRobot_ID809.h>
+
#include <DFRobot_ID809.h>
 
+
#include <SD.h>
<nowiki>#</nowiki>include <SD.h>
+
#include <pu2clr_pcf8574.h>
 
+
#include <TCA9548A.h>
<nowiki>#</nowiki>include <Adafruit_MPU6050.h>
+
</nowiki>
 
 
<nowiki>#</nowiki>include <pu2clr_pcf8574.h>
 
 
 
<nowiki>#</nowiki>include <TCA9548A.h>
 
 
 
</code>
 
  
 
== Library Modification ==
 
== Library Modification ==
Line 42: Line 35:
  
 
== Defines - Variables - Routines ==
 
== Defines - Variables - Routines ==
Updates Needed
 
  
 
The following code is a mixing and matching of the example code provided by the referenced Special Libraries.   
 
The following code is a mixing and matching of the example code provided by the referenced Special Libraries.   
==== Includes ====
+
==== Custom Includes ====
<nowiki>
 
#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"
+
[[Pseudo-Medical Monitor Code I2CMUX STUFF|#include "I2CMUX_Stuff.h"]]
 
 
#include "HB_Stuff.h"
 
#include "AMG_Stuff.h"
 
#include "VL_Stuff.h"
 
#include "CT_Stuff.h"
 
#include "FP_Stuff.h"
 
#include "EXG_Stuff.h"
 
 
 
</nowiki>
 
 
 
==== VL53L0X Sensor (VL_Stuff.h) ====
 
<nowiki>
 
#define START_DISTANCE 500
 
#define EXG_DISTANCE 150
 
 
 
Adafruit_VL53L0X lox = Adafruit_VL53L0X();
 
  
bool EXG_Mode = false;
+
[[Pseudo-Medical Monitor Code TFT STUFF|#include "TFT_Stuff.h"]]
  
int last_range_measurement = -1;
+
[[Pseudo-Medical Monitor Code SD STUFF|#include "SD_Stuff.h"]]
int VL_x_offset = 118;
 
int VL_y_offset = 0;
 
int VL_x_width = 10;
 
int VL_y_height = 74;
 
  
void setup_VL()
 
{
 
  lox.begin();
 
}
 
  
void VL_Reset()
 
{
 
  last_range_measurement = -1;
 
}
 
  
void range_display(int range_measurement)
+
[[Pseudo-Medical Monitor Code HeartBeat_STUFF|#include "HeartBeat_Stuff.h"]]
{
 
  int box_top = VL_y_offset;
 
  int box_bottom = box_top + VL_y_height;
 
 
 
  int box_left = VL_x_offset;
 
  int box_right = box_left + VL_x_width;
 
 
 
  int box_width = VL_x_width;
 
  int box_height = VL_y_height;
 
 
 
  int bar_top = box_top + 1;
 
  int bar_bottom = box_bottom - 1;
 
  
  int bar_left = box_left + 1;
+
Two related include files from Library for MAX30105 examples not included here
  int bar_right = box_right -1;
+
* bmpHeader.h
 +
* Interoplation.
  
  int bar_width = VL_x_width - 2;
 
  int bar_height = VL_y_height - 2;
 
  
  int bar_measure;
+
[[Pseudo-Medical Monitor Code ThermalImage_STUFF|#include "ThermalImager_Stuff.h"]]
 
 
  if (last_range_measurement == -1)
 
    {
 
      // Draw Box
 
      tft.fillRect(box_left, box_top, box_width, box_height, ST7735_BLACK);   
 
      tft.drawRect(box_left, box_top, box_width, box_height, ST7735_YELLOW);   
 
    }
 
 
 
  if (last_range_measurement != range_measurement)
 
    {
 
      tft.fillRect(bar_left, bar_top, bar_width, bar_height, ST7735_BLACK);
 
      if (range_measurement > START_DISTANCE)
 
        tft.fillRect(bar_left, bar_top, bar_width, bar_height, ST7735_RED);
 
      else
 
        {
 
          if (range_measurement < EXG_DISTANCE)
 
            {
 
              bar_measure = ((float)range_measurement / (float)START_DISTANCE) * bar_height;
 
              tft.fillRect(bar_left, bar_bottom - bar_measure, bar_width, bar_measure, ST7735_BLUE);             
 
            }
 
          else
 
            {
 
              bar_measure = ((float)range_measurement / (float)START_DISTANCE) * bar_height;
 
              tft.fillRect(bar_left, bar_bottom - bar_measure, bar_width, bar_measure, ST7735_GREEN);
 
            }
 
        }
 
    } 
 
  
  last_range_measurement = range_measurement;
+
[[Pseudo-Medical Monitor Code TOFLaser_STUFF|#include "TOFLaser_Stuff.h"]]
}
 
  
int VL_Reading()
+
[[Pseudo-Medical Monitor Code NonContactThermometer_STUFF|#include "NonContactThermometer_Stuff.h"]]
{
 
  int range_measure;
 
 
 
  VL53L0X_RangingMeasurementData_t measure;
 
  lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!
 
  if (measure.RangeStatus != 4)
 
    {  // phase failures have incorrect data         
 
      range_measure = measure.RangeMilliMeter;
 
    }
 
  else
 
    {
 
      range_measure = 9999;
 
    }
 
  
  if (range_measure < EXG_DISTANCE)
+
[[Pseudo-Medical Monitor Code FingerPrint_STUFF|#include "FingerPrint_Stuff.h"]]
    EXG_Mode = true;
 
  else
 
    EXG_Mode = false;
 
  
  return(range_measure); 
 
}
 
  
void VL_Frame()
+
[[Pseudo-Medical Monitor Code ControlPanel_STUFF|#include "ControlPanel_Stuff.h"]]
{
 
  int range_measure;
 
 
 
  range_measure = VL_Reading();
 
 
 
  range_display(range_measure); 
 
  
//  delay(100); 
+
[[Pseudo-Medical Monitor Code AudioBoard_STUFF|#include "AudioBoard_Stuff.h"]]
}
 
</nowiki>
 
  
==== Heart Beat Sensor (HB_Stuff.h) ====
 
 
  <nowiki>
 
  <nowiki>
  
static const unsigned char PROGMEM still_heart_logo_bmp[] =
+
#include "I2CMUX_Stuff.h"
{
+
#include "TFT_Stuff.h"
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
#include "SD_Stuff.h"
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0F, 0x00, 0x00, 0x67, 0x18, 0xC0, 0x00, 0xC1, 0xB0, 0x60,
 
0x01, 0x80, 0xE0, 0x20, 0x01, 0x00, 0xC0, 0x30, 0x01, 0x00, 0x40, 0x10, 0x01, 0x00, 0x40, 0x10,
 
0x01, 0x04, 0x00, 0x10, 0x01, 0x04, 0x00, 0x10, 0x01, 0x0C, 0x00, 0x30, 0x00, 0x88, 0x80, 0x20,
 
0x00, 0x8B, 0x80, 0x40, 0x0F, 0xF3, 0x70, 0x80, 0x00, 0x13, 0x01, 0x80, 0x00, 0x19, 0x03, 0x00,
 
0x00, 0x0C, 0x06, 0x00, 0x00, 0x06, 0x0C, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00, 0x01, 0xB0, 0x00,
 
0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 
};
 
 
 
static const unsigned char PROGMEM beat_heart_logo_bmp[] =
 
{
 
0x01, 0xF0, 0x0F, 0x80, 0x06, 0x1C, 0x38, 0x60, 0x18, 0x06, 0x60, 0x18, 0x10, 0x01, 0x80, 0x08,
 
0x20, 0x01, 0x80, 0x04, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x08, 0x03,
 
0x80, 0x00, 0x08, 0x01, 0x80, 0x00, 0x18, 0x01, 0x80, 0x00, 0x1C, 0x01, 0x80, 0x00, 0x14, 0x00,
 
0x80, 0x00, 0x14, 0x00, 0x80, 0x00, 0x14, 0x00, 0x40, 0x10, 0x12, 0x00, 0x40, 0x10, 0x12, 0x00,
 
0x7E, 0x1F, 0x23, 0xFE, 0x03, 0x31, 0xA0, 0x04, 0x01, 0xA0, 0xA0, 0x0C, 0x00, 0xA0, 0xA0, 0x08,
 
0x00, 0x60, 0xE0, 0x10, 0x00, 0x20, 0x60, 0x20, 0x06, 0x00, 0x40, 0x60, 0x03, 0x00, 0x40, 0xC0,
 
0x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x30, 0x0C, 0x00,
 
0x00, 0x08, 0x10, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x01, 0x80, 0x00 
 
};
 
 
 
MAX30105 particleSensor;
 
 
 
#define HB_INT 4
 
 
 
int HB_x_offset = 0;
 
int HB_y_offset = 78;
 
int HB_x_width = 46;
 
int HB_y_height = 82;
 
 
 
int HB_initialize_screen = -1;
 
 
 
void HB_Reset()
 
{
 
  HB_initialize_screen = -1; 
 
}
 
 
 
void setup_HB()
 
{
 
  // Initialize sensor
 
  if (!particleSensor.begin()) //Use default I2C port, 400kHz speed
 
  {
 
    Serial.println("MAX30105 was not found. Please check wiring/power. ");
 
    while (1);
 
  }
 
//  Serial.println("Place your index finger on the sensor with steady pressure.");
 
 
 
  particleSensor.setup(); //Configure sensor with default settings
 
  particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
 
  particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
 
 
 
}
 
 
 
 
 
void HB_Frame()
 
{
 
  int box_top = HB_y_offset;
 
  int box_bottom = box_top + HB_y_height;
 
 
 
  int box_left = HB_x_offset;
 
  int box_right = box_left + HB_x_width;
 
 
 
  int box_width = HB_x_width;
 
  int box_height = HB_y_height;
 
 
 
  const byte RATE_SIZE = 6; //Increase this for more averaging. 4 is good.
 
  byte rates[RATE_SIZE]; //Array of heart rates
 
  long pulse_ir[RATE_SIZE];
 
  long pulse_red[RATE_SIZE];
 
 
 
  byte rateSpot = 0;
 
  byte O2Spot = 0;
 
  long O2AVG = 0;
 
  long lastBeat = 0; //Time at which the last beat occurred
 
  float beatsPerMinute;
 
  int beatAvg = -1, lastAvg = 0;
 
  long irAVG = 0;
 
  long redAVG = 0;
 
 
 
  bool beatDetect = false;
 
  int latentBeatMax = 2;
 
  int latentBeat = 0;
 
 
 
  long irValue = 0;
 
  long redValue = 0;
 
  long maxValue = 0; 
 
  long lastValue = 0;
 
  long turnValue = 0;
 
  long lastMax = 0;
 
 
 
  int tft_HB_Screen = 0;
 
  int last_HB_Screen = -1;
 
 
 
  unsigned long start_time;
 
  unsigned long delta = 0;
 
  int HB_detect_threshold = 7000;
 
 
 
  // Clear rate calculating array
 
  for(byte x = 0; x < RATE_SIZE ; ++x)
 
    rates[x] = 0;
 
 
 
  if (HB_initialize_screen == -1)
 
    {
 
      tft.fillRect(box_left, box_top, box_width, box_height, ST7735_BLACK);
 
      tft.drawRect(box_left, box_top, box_width, box_height, ST7735_BLUE);
 
      tft.setTextColor(ST7735_WHITE, ST7735_BLACK);           
 
      tft.setCursor(box_left + 3,box_top + 4);               
 
      tft.println("Place ");
 
      tft.setCursor(box_left + 3,box_top + 16);
 
      tft.println("your ");           
 
      tft.setCursor(box_left + 3,box_top + 28);
 
      tft.println("finger ");           
 
      tft.setCursor(box_left + 3,box_top + 40);
 
      tft.println("on ");                       
 
      tft.setCursor(box_left + 3,box_top + 52);
 
      tft.println("sensor ");                                   
 
      HB_initialize_screen = 0;
 
      for (byte x = 0 ; x < RATE_SIZE ; x++)
 
        rates[x] = 0;
 
    }
 
 
 
  irValue = particleSensor.getIR();
 
  redValue = particleSensor.getRed();
 
 
 
  while(irValue > HB_detect_threshold)
 
    {
 
      irValue = particleSensor.getIR();    //Reading the IR value it will permit us to know if there's a finger on the sensor or not
 
      redValue = particleSensor.getRed();
 
     
 
//      Serial.print(irValue);
 
//      Serial.print(",");
 
//      Serial.print(redValue);
 
//      Serial.print(",");
 
//      Serial.print(maxValue);
 
//      Serial.print(",");
 
//      Serial.print(turnValue);
 
//      Serial.print(",");
 
//      Serial.print(lastMax);
 
      Serial.println();
 
         
 
      if (irValue > 7000)
 
        { 
 
          //finger is detected
 
          tft_HB_Screen = 1;
 
          if (irValue > maxValue)
 
            maxValue = irValue;
 
 
 
//        if ((irValue < maxValue - 200) && (irValue > lastValue + 20)) // alternate detect beat method
 
          if (irValue < maxValue - 200)
 
            {
 
              beatDetect = true;
 
              lastMax = maxValue;
 
              maxValue = irValue;
 
              turnValue = lastValue;
 
              latentBeat = latentBeatMax;
 
            }
 
 
 
          lastValue = irValue; 
 
         
 
          if (beatDetect == true)
 
            {
 
              beatDetect = false;
 
 
 
              //We sensed a beat!
 
              delta = millis() - lastBeat;                  //Measure duration between two beats
 
              lastBeat = millis();
 
 
 
              beatsPerMinute = 60 / (delta / 1000.0);          //Calculating the BPM
 
              lastAvg = beatAvg;           
 
 
 
              pulse_ir[O2Spot++] = irValue;
 
              pulse_red[O2Spot] = redValue;
 
/*             
 
              if (O2Spot == RATE_SIZE)
 
                {
 
                  for (byte x = 0; x < RATE_SIZE; ++x)
 
                    {
 
                      irAVG = irAVG + pulse_ir[x];
 
                      redAVG = redAVG + pulse_red[x];
 
                    }
 
                  O2AVG = ((float)irAVG / (float) redAVG) * 100;
 
                  tft.setCursor(box_left + 4,box_top + 56);               
 
                  tft.println(O2AVG);                       
 
                  O2Spot = 0;
 
                }
 
*/             
 
              if ((beatsPerMinute < 255.0) && (beatsPerMinute > 20.0))              //To calculate the average we strore some values (4) then do some math to calculate the average
 
                {
 
                  rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
 
                  rateSpot %= RATE_SIZE; //Wrap variable
 
 
 
                  //Take average of readings
 
 
 
                  beatAvg = 0;
 
                  for (byte x = 0 ; x < RATE_SIZE ; x++)
 
                    beatAvg += rates[x];
 
                  beatAvg /= RATE_SIZE;
 
                }
 
            }
 
        }
 
 
 
 
 
      if (irValue < 7000)
 
        {      //If no finger is detected it inform the user and put the average BPM to 0 or it will be stored for the next measure
 
          tft_HB_Screen = 0;
 
          beatAvg=0;
 
          lastAvg = 0;
 
          for(byte x = 0; x < RATE_SIZE ; ++x)
 
            rates[x] = 0;
 
        }
 
   
 
      switch(tft_HB_Screen)
 
        {
 
          case 0:           
 
            if (last_HB_Screen != 0)
 
              tft.fillRect(box_left + 1, box_top + 1, box_width - 2, box_height - 2, ST7735_BLACK);             
 
            tft.setTextColor(ST7735_WHITE, ST7735_BLACK);           
 
            tft.setCursor(box_left + 3,box_top + 4);               
 
            tft.println("Place ");
 
            tft.setCursor(box_left + 3,box_top + 16);
 
            tft.println("your ");           
 
            tft.setCursor(box_left + 3,box_top + 28);
 
            tft.println("finger ");           
 
            tft.setCursor(box_left + 3,box_top + 40);
 
            tft.println("on ");                       
 
            tft.setCursor(box_left + 3,box_top + 52);
 
            tft.println("sensor ");                                   
 
            break;
 
          case 1:       
 
            if (last_HB_Screen != 1)
 
              tft.fillRect(box_left + 1,box_top + 1,32,33,ST7735_BLACK);
 
            tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
 
            if (latentBeat == latentBeatMax) 
 
              {
 
                tft.fillRect(box_left + 1,box_top + 1, box_width - 2, 33, ST7735_BLACK);
 
                tft.drawBitmap(box_left + 2,box_top + 2, beat_heart_logo_bmp, 32, 32, ST7735_RED);    //Draw the second picture (bigger heart)             
 
              }
 
            if (latentBeat == 0)
 
              {
 
                tft.fillRect(box_left + 1,box_top + 1, box_width - 2, 33, ST7735_BLACK);
 
                tft.drawBitmap(box_left + 2, box_top + 2, still_heart_logo_bmp, 32, 32, ST7735_WHITE);      //Draw the first bmp picture (little heart)
 
                latentBeat = -1;
 
              }                                         
 
            if (latentBeat > 0)
 
              -- latentBeat;             
 
            if (lastAvg != beatAvg)
 
              {
 
                tft.fillRect(box_left + 1,box_top + 34 ,box_width - 2,box_height - 35, ST7735_BLACK);
 
                tft.setCursor(box_left + 4,box_top + 34);               
 
                tft.println("BPM");           
 
                tft.setCursor(box_left + 4,box_top + 44);               
 
                tft.println(beatAvg);         
 
                lastAvg = beatAvg;
 
              }
 
            break;
 
          case 2:
 
            tft.fillRect(box_left + 1,box_top + 2, 32, 32, ST7735_BLACK);
 
            tft.drawBitmap(box_left + 2,box_top + 2, beat_heart_logo_bmp, 32, 32, ST7735_RED);    //Draw the second picture (bigger heart)             
 
 
 
            tft.fillRect(box_left + 1,box_top + 34 ,box_width - 2,box_height - 35, ST7735_BLACK);
 
            tft.setCursor(box_left + 4,box_top + 34);               
 
            tft.println("BPM");           
 
            tft.setCursor(box_left + 4,box_top + 44);               
 
            tft.println(beatAvg);                     
 
            break; 
 
          case 3:
 
            break;   
 
        }
 
    last_HB_Screen = tft_HB_Screen;   
 
    delay(100);
 
    }
 
}
 
 
 
</nowiki>
 
 
 
==== Fingerprint Scanner (FP_Stuff.h) ====
 
<nowiki>
 
#define FPSerial Serial1
 
#define FP_INIT 3
 
 
 
DFRobot_ID809 fingerprint;
 
String desc;
 
File myFile;
 
 
 
//#define QUARTER
 
#ifdef  QUARTER
 
uint8_t data[6400];  //Quarter image
 
#else
 
uint8_t data[25600];  //Full image
 
#endif
 
 
 
int FP_x_offset = 46;
 
int FP_y_offset = 78;
 
int FP_x_width = 82;
 
int FP_y_height = 82;
 
 
 
bool fingerprint_captured = false;
 
bool FP_first_pass = true;
 
 
 
void setup_FP()
 
{
 
  pinMode(FP_INIT,INPUT);
 
  /*Init FPSerial*/
 
  FPSerial.begin(115200);
 
  /*Take FPSerial as communication port of fingerprint module */
 
  fingerprint.begin(FPSerial);
 
 
 
  /*Wait for Serial to open*/
 
  /*Test whether device can communicate properly with mainboard
 
    Return true or false
 
    */
 
  while(fingerprint.isConnected() == false)
 
  {
 
    Serial.println("Communication with device failed, please check connection");
 
    /*Get error code information */
 
    desc = fingerprint.getErrorDescription();
 
    Serial.println(desc);
 
    delay(1000);
 
  }
 
}
 
 
 
 
 
void FP_Reset()
 
{
 
  fingerprint_captured = false;
 
  FP_first_pass = true; 
 
}
 
 
 
void FP_Frame()
 
{
 
  int box_top = FP_y_offset;
 
  int box_bottom = box_top + FP_y_height;
 
 
 
  int box_left = FP_x_offset;
 
  int box_right = box_left + FP_x_width;
 
 
 
  int box_width = FP_x_width;
 
  int box_height = FP_y_height;
 
 
 
  int p_x, p_y, p_i, p_data, p_temp;
 
 
 
  if (FP_first_pass)
 
    {
 
      tft.drawRect(box_left, box_top, box_width, box_height, ST7735_MAGENTA);
 
      tft.fillRect(box_left + 1, box_top + 1, box_width - 2, box_height - 2, ST7735_BLACK);
 
      fingerprint.ctrlLED(/*LEDMode = */fingerprint.eBreathing, /*LEDColor = */fingerprint.eLEDRed, /*blinkCount = */0);
 
      tft.setCursor(box_left + 4, box_top + 4);
 
      tft.println("Place Finger");
 
      tft.setCursor(box_left + 4, box_top + 16);
 
      tft.println("on scanner.");     
 
      FP_first_pass = false;
 
    }
 
 
 
  if ((fingerprint.detectFinger()) && (!fingerprint_captured))
 
    {
 
      tft.setCursor(box_left + 4, box_top + 4);
 
      tft.println("Keep Finger ");
 
      tft.setCursor(box_left + 4, box_top + 16);
 
      tft.println("on scanner.");     
 
     
 
      fingerprint.getFingerImage(data);
 
      fingerprint.ctrlLED(/*LEDMode = */fingerprint.eKeepsOn, /*LEDColor = */fingerprint.eLEDGreen, /*blinkCount = */0);
 
      for (p_x=0; p_x < 80; ++p_x)
 
        for (p_y=0; p_y < 80; ++p_y)
 
          {
 
            p_temp = (p_x * 2);
 
            p_temp = p_temp + (p_y * 160);
 
            p_data = data[p_temp]/4; // image element
 
 
 
            p_temp = p_temp + 1;
 
            p_data = p_data + data[p_temp]/4; // image element to the right
 
 
 
            p_temp = (p_x * 2);
 
            p_temp = p_temp + ((p_y + 1) * 160);
 
            p_data = p_data + data[p_temp]/4;  // image element below
 
 
 
            p_temp = (p_x + 1) * 2;
 
            p_temp = p_temp + ((p_y + 1) * 160);
 
            p_data = p_data + data[p_temp]/4;  // image element to the right, one element down
 
               
 
            p_data = p_data/4;
 
            tft.drawPixel(box_left+1+p_x,box_top+1+p_y,p_data<<5);
 
          }       
 
    }
 
   
 
}
 
 
 
</nowiki>
 
 
 
==== MLX90614 Sensor Code (CT_Stuff.h) ====
 
<nowiki>
 
IRTherm therm; // Create an IRTherm object to interact with throughout
 
 
 
int last_object_measurement = -1;
 
int last_ambient_measurement = -1;
 
 
 
int CT_x_offset = 0;
 
int CT_y_offset = 0;
 
int CT_x_width = 44;
 
int CT_y_height = 74;
 
 
 
void setup_CT()
 
{
 
  if (therm.begin() == false) { // Initialize thermal IR sensor
 
    Serial.println("IR thermometer Failed");
 
    while (1);
 
  }
 
 
 
  therm.setUnit(TEMP_F); // Set the library's units to Farenheit
 
 
 
}
 
 
 
 
 
void CT_Reset()
 
{
 
  last_object_measurement = -1;
 
  last_ambient_measurement = -1; 
 
}
 
 
 
void CT_Frame()
 
{
 
  int box_top = CT_y_offset;
 
  int box_bottom = box_top + CT_y_height;
 
 
 
  int box_left = CT_x_offset;
 
  int box_right = box_left + CT_x_width;
 
 
 
  int box_width = CT_x_width;
 
  int box_height = CT_y_height;
 
 
 
  int ambient_x_offset = box_left + 1;
 
  int ambient_y_offset = box_top + 8;
 
  int object_x_offset = box_left + 1;
 
  int object_y_offset = ambient_y_offset + 20;
 
 
 
  int ambient_measurement;
 
  int object_measurement;
 
 
 
  if ((last_ambient_measurement == -1) && (last_object_measurement == -1))
 
    {
 
      tft.drawRect(box_left, box_top, box_width, box_height, ST7735_RED);
 
      tft.setCursor(ambient_x_offset, ambient_y_offset);
 
      tft.println("MLX90XX");
 
      tft.setCursor(object_x_offset, object_y_offset);
 
      tft.println("Object");
 
     
 
    } 
 
 
 
  therm.read();
 
  ambient_measurement = therm.ambient();
 
  object_measurement = therm.object();
 
 
 
  if ( last_ambient_measurement != ambient_measurement)
 
    {
 
      tft.setCursor(ambient_x_offset, ambient_y_offset + 8);
 
      tft.println(String(therm.ambient(), 2));
 
    }
 
 
 
  if ( last_object_measurement != object_measurement)
 
    { 
 
      tft.setCursor(object_x_offset, object_y_offset + 8);
 
      tft.println(String(therm.object(), 2));
 
    }
 
 
 
  last_ambient_measurement = ambient_measurement;
 
  last_object_measurement = object_measurement;     
 
}
 
 
 
</nowiki>
 
 
 
====AMG8833 Sensor (AMG_Stuff.h) ====
 
<nowiki>
 
//low range of the sensor (this will be blue on the screen)
 
#define MINTEMP 20
 
 
 
//high range of the sensor (this will be red on the screen)
 
#define MAXTEMP 28
 
 
 
//the colors we will be using
 
const uint16_t camColors[] = {0x480F,
 
                              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;
 
 
 
#define AMG_COLS 8
 
#define AMG_ROWS 8
 
float pixels[AMG_COLS * AMG_ROWS];
 
 
 
#define INTERPOLATED_COLS 24
 
#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 AMG_Reset()
 
{
 
 
 
}
 
 
 
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); 
 
}
 
 
 
</nowiki>
 
 
 
==== BioAmp EXG (EXG_Stuff.h) ====
 
<nowiki>
 
#define EXG_SAMPLE_SIZE 155
 
#define EXG_PIN A0
 
 
 
int EXG_x_offset = 0;
 
int EXG_y_offset = 0;
 
int EXG_x_width = 128;
 
int EXG_y_height = 160;
 
 
 
void EXG_Frame()
 
 
 
 
  int box_top = EXG_y_offset;
 
  int box_bottom = box_top + EXG_y_height;
 
 
 
  int box_left = EXG_x_offset;
 
  int box_right = box_left + EXG_x_width;
 
 
 
  int box_width = EXG_x_width;
 
  int box_height = EXG_y_height;
 
 
 
  tft.fillRect(box_left, box_top, box_width, box_height, ST7735_WHITE);
 
  tft.drawRect(box_left+1, box_top+1, box_width-3, box_height-3, ST7735_BLACK);
 
 
 
}
 
  
void EXG_Display_Data(int * EXG_data)
+
#include "HeartBeat_Stuff.h"
{
+
#include "ThermalImager_Stuff.h"
  int box_top = EXG_y_offset;
+
#include "TOFLaser_Stuff.h"
  int box_bottom = box_top + EXG_y_height;
+
#include "NonContactThermometer_Stuff.h"
 
+
#include "FingerPrint_Stuff.h"
  int box_left = EXG_x_offset;
 
  int box_right = box_left + EXG_x_width;
 
 
 
  int box_width = EXG_x_width;
 
  int box_height = EXG_y_height;
 
 
 
  int max_value = -5000;
 
  int min_value = 5000;
 
  int data_point1,data_point2;
 
 
 
  tft.fillRect(box_left+2, box_top+2, box_width-5, box_height-5, ST7735_WHITE);
 
 
 
  for(int x=0;x<EXG_SAMPLE_SIZE; ++x)
 
    {
 
      if (EXG_data[x] > max_value)
 
        max_value = EXG_data[x];
 
      if (EXG_data[x] < min_value)
 
        min_value = EXG_data[x];       
 
    }
 
  for(int x=0;x<EXG_SAMPLE_SIZE-1; ++x)
 
  {
 
    data_point1 = map(EXG_data[x],min_value,max_value,2,124);
 
    data_point2 = map(EXG_data[x+1],min_value,max_value,2,124);
 
    tft.drawLine(data_point1,x+2,data_point2,x+3,ST7735_RED);
 
    Serial.println(data_point1);
 
  }
 
   
 
}
 
 
 
void EXG_Collect()
 
{
 
  int EXG_Delay = 30; 
 
  int EXG_data[EXG_SAMPLE_SIZE];
 
 
 
  for(int x=0;x<EXG_SAMPLE_SIZE; ++x)
 
    {
 
      EXG_data[x] = analogRead(EXG_PIN);
 
      delay(EXG_Delay);
 
    }
 
  
  EXG_Display_Data(EXG_data);
+
#include "ControlPanel_Stuff.h"
 
+
#include "AudioBoard_Stuff.h"
}
 
  
 
void EXG_Demo()
 
{
 
  EXG_Frame();
 
  while(1)
 
    {
 
      EXG_Collect();     
 
    }
 
}
 
</nowiki>
 
 
==== Core ====
 
<nowiki>
 
 
void setup()
 
void setup()
 
{
 
{
 
   Wire.begin();
 
   Wire.begin();
 +
  Wire1.begin();
 
   Serial.begin(115200);
 
   Serial.begin(115200);
  
 +
  analogReadResolution(12);
 +
 
 
   Serial.println("SETUP - Begin");
 
   Serial.println("SETUP - Begin");
 
   Serial.println("TFT");
 
   Serial.println("TFT");
 
   setup_TFT();
 
   setup_TFT();
 +
  Serial.println("SD Card");
 +
  setup_SD();
 +
 
   Serial.println("CT");
 
   Serial.println("CT");
   setup_CT();
+
   setup_NonContactThermometer();
   Serial.println("AMG");
+
   Serial.println("ThermalImager");
   setup_AMG();
+
   setup_ThermalImager();
   Serial.println("VL");
+
   Serial.println("TOFLaser");
   setup_VL();   
+
   setup_TOFLaser();   
   Serial.println("HB");
+
   Serial.println("HeartBeat");
   setup_HB();
+
   setup_HeartBeat();
   Serial.println("FP");
+
   Serial.println("FingerPrint");
   setup_FP();
+
   setup_FingerPrint();
 +
  Serial.println("ControlPanel");
 +
  setup_ControlPanel();
 +
  Serial.println("AudioBoard");
 +
  setup_AudioBoard();
 
   Serial.println("SETUP - End");
 
   Serial.println("SETUP - End");
 
}
 
}
 +
  
 
void loop()
 
void loop()
 
{
 
{
 
+
      TOFLaser_Frame();
  VL_Frame();
+
      ThermalImager_Frame();
  AMG_Frame();
+
      NonContactThermometer_Frame();
  CT_Frame();
+
      FingerPrint_Frame();
  FP_Frame();
+
      HeartBeat_Frame();
  HB_Frame();
+
}
  
  if (EXG_Mode)
 
    {
 
      EXG_Frame();
 
      while(EXG_Mode)
 
        {
 
          EXG_Collect();
 
          VL_Reading();
 
        }
 
      TFT_Reset();
 
      VL_Reset();
 
      AMG_Reset();
 
      CT_Reset();
 
      FP_Reset(); 
 
      HB_Reset();
 
    } 
 
}
 
 
  </nowiki>
 
  </nowiki>
  
 
[[Pseudo-Medical Monitor]]
 
[[Pseudo-Medical Monitor]]

Latest revision as of 16:18, 14 December 2021

Being written on the fly, expect rewrites and restructures. Enough information is here for writing code on the completed hardware.

Basic Software Load for Main Device Only. Later Update to Incorporate Port Usage with External Units.

Hardware 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>
 #include <pu2clr_pcf8574.h>
 #include <TCA9548A.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

The following code is a mixing and matching of the example code provided by the referenced Special Libraries.

Custom Includes

#include "I2CMUX_Stuff.h"

#include "TFT_Stuff.h"

#include "SD_Stuff.h"


#include "HeartBeat_Stuff.h"

Two related include files from Library for MAX30105 examples not included here

  • bmpHeader.h
  • Interoplation.


#include "ThermalImager_Stuff.h"

#include "TOFLaser_Stuff.h"

#include "NonContactThermometer_Stuff.h"

#include "FingerPrint_Stuff.h"


#include "ControlPanel_Stuff.h"

#include "AudioBoard_Stuff.h"

#include "I2CMUX_Stuff.h"
#include "TFT_Stuff.h"
#include "SD_Stuff.h"

#include "HeartBeat_Stuff.h"
#include "ThermalImager_Stuff.h"
#include "TOFLaser_Stuff.h"
#include "NonContactThermometer_Stuff.h"
#include "FingerPrint_Stuff.h"

#include "ControlPanel_Stuff.h"
#include "AudioBoard_Stuff.h"

void setup()
{
  Wire.begin();
  Wire1.begin();
  Serial.begin(115200);

  analogReadResolution(12);
  
  Serial.println("SETUP - Begin");
  Serial.println("TFT");
  setup_TFT();
  Serial.println("SD Card");
  setup_SD();

  Serial.println("CT");
  setup_NonContactThermometer();
  Serial.println("ThermalImager");
  setup_ThermalImager();
  Serial.println("TOFLaser");
  setup_TOFLaser();  
  Serial.println("HeartBeat");
  setup_HeartBeat();
  Serial.println("FingerPrint");
  setup_FingerPrint();
  Serial.println("ControlPanel");
  setup_ControlPanel();
  Serial.println("AudioBoard");
  setup_AudioBoard();
  Serial.println("SETUP - End");
}


void loop()
{
      TOFLaser_Frame();
      ThermalImager_Frame();
      NonContactThermometer_Frame();
      FingerPrint_Frame();
      HeartBeat_Frame();
}

 

Pseudo-Medical Monitor