Medical tricorder

Medical_mathematics_notes.pdf (117856Bytes)
Medical_tricorder_Gerber.zip (347220Bytes)

While the world encounters more and more Ebola cases, the human kind seems to be more than ever in need of a medical tricorder, known from the science fiction TV show Star Trek from the 1960s. According of the wikipedia definition, a medical tricorder is a handheld portable scanning device to be used by consumers to self-diagnose medical conditions within seconds and take basic vital measurements. There are at least two devices under developement which are considered as a medical tricorder. One is the Scanadu Scout from Scanadu, the other the Checkme from Viatom Technology. Beside this a medical sensor kit for  Arduino, Raspberry Pi and Intel Galileo is available, but it does not claim to be a medical tricorder, probably because of missing diagnosis software and the multiplicity of external sensors.

As I have always been fascinated by medical electronics and medical mathematics and was sickened by a thrombosis on left calf a month ago, which nearly killed me because I didn't took the pain and the tumefaction serious for several days, I recently started to develop a simple form of a medical tricoder.

My tricorder has currently only two sensors: an infrared thermometer (MLX90614) to measure the body temperture on the forehead and a PPG (Photoplethysmograph) sensor to measure pulse/heart rate on the ear lobe. It furthermore features a monochrome 0.96" 128x64 OLED graphic display and a 5 push button keypad to insert user information, furthermore a RTC and a SD card to store data. The RTC will also give me the possibility to use the device as a medication reminder. I have to take for the next half year the oral anticoagulant Rivaroxaban, but forget nearly daily to take it on time...

During my research I was astonished, how many medical information can be computed by only knowing the body temperature, pulse rate, gender and age. By far the most interesting discovery was the use of naive Bayes classifier in automated medical diagnosis. Also very interesting are the following fever diagnoses, which are not too difficult to translate into an according algorithm: fever in adults and fever in infants and children. On hardware side I am very interested in measuring blood pressure without using a cuff, a feature that has been tried by many but never successfully and this new reflective pulse oximeter sensor from Japan.

So far I have routed a shield for the Arduino Mega, which includes all the parts I have mentioned earlier. The image below shows the routed PCB before copper fill. I have printed out the etch copper top as a sort of paper placement test for some ordered parts I was not sure. The released Gerber files can be found in the attachments now.

Medical_tricorder_pcb.jpg

Next image shows the populated board without OLED display.

The heart beat monitor consists of following components:

The ear lobe pulse sensor HRM-2511B is from Kyto Electronic. R1 and R2 biasing the IR LED and photo transistor in the ear lope sensor which is connected to the shield via 3.5mm phone connector. Safety resistor R3 and the diodes D1 and D2 building a reference voltage generator. The reference voltage is two times the diode forward voltage (approx. 0.7 V for silicon diodes, depending on current and temperature) in respect to GND. C1/R4 and C3/R7 building passive, analog, first-order high-pass filters (HPF). The cutoff frequency fc is given by

MT_EQ8.jpg

C2/R6 and C4/R9 building active low-pass filters (LPF). The cutoff frequency is here

MT_EQ9.jpg

The combination of HPFs and LPFs helps to remove the unwanted DC signal and high frequency noise coming from the sensor and boost the weak puslatile AC component, which carries the required information.

The amplification of every of the two op-amp stages with negative feedback is set to 101:

MT_EQ10.jpg

The total amplification is simply the squared single amplification: 101²=10201.

Gain can be adjusted by the potentiometer P1, which is a voltage divider.

The analog signal on the output of the second opamp stage is passed to an analog pin of the Arduino for further signal processing and to a comparator with hysteresis (Schmitt trigger) that ignores high frequency noise in its threshold voltage. Noise below the threshold is ignored, and positive feedback latches the output state until the opposite threshold is exceeded.

signal4.jpg

Image credit: http://www.techonlineindia.com

The output of the comparator is passed to an LED to indicate heart beats and to the Arduino digital pin 2, which provides for most boards a hardware interrupt.

The body core temperatue will be monitored by a MLX90614 IR thermometer for non contact temperature measurements. Both the IR sensitive thermopile detector chip and the signal conditioning ASIC are integrated in the same TO-39 can.

prodfiles_0005150_IR_sensor.jpg

Image credit: http://www.melexis.com

The schematic is straightforward, just following the data sheet:


The pull-up resistors are optional. Usually the I²C bus of Arduino boards is already equipped with 10k pull-up resistors.

The maximal skin temperature is measured on the forehead, preferable close to the temporal artery. The heat transfer per unit surface through convection was first described by Newton and the relation is known as the Newton’s Law of Cooling. The equation for convection can be expressed as:

TEMP_EQ1.jpg


q = heat transferred per unit time [W]

h = convective heat transfer coefficient of the process [W/(m²·K)]

A = heat transfer area of the skin[]

TS  = temperature of the skin [K]
T
A  = ambient temperature [K]

We neglect radiative transfer and assume further, that

TEM_EQ2.jpg

w = blood mass flow rate [kg/s]

c = heat capacity of blood [J/(kg·K)]

TC  = body core temperature [K]

Equating equation (1) and (2) yields to

TEMP_EQ3.jpg

Dividing by surface area A:

TEMP_EQ4.jpg

TEM_EQ5.jpg

where p = perfusion rate [kg/(s·A)]

Solving for TC:

TEM_EQ6.jpg

According to the US patent US 6299347 B1 h/(p∙c) can be expressed as

TEM_EQ7_0.jpg

and finally we get the body core temperature in °F by the object and ambient temperature in °F , which the MLX90614 provides:

MED_EQ17.jpg


Third video shows a test of the IR thermometer scanner with the algorithm above. I might take the age into account as a child’s forehead seems to have less radiation heat transfer than an adult. No IR thermometer up to date evaluates the age before measurement.

Example code:

#include <Wire.h>
#include <Adafruit_MLX90614.h>
Adafruit_MLX90614 mlx = Adafruit_MLX90614();

float T_SK_buffer;
float T_SK;
float T_Core;

void setup() {
  Serial.begin(9600);
  mlx.begin();
}

void loop() {
  T_SK_buffer = mlx.readObjectTempF();
  if(T_SK_buffer > T_SK) {
    T_SK = T_SK_buffer;
    T_Core = (0.001081T_SKT_SK-0.2318T_SK+12.454)(T_SK-mlx.readAmbientTempF())+T_SK;
    T_Core = (T_Core-32.0)*5.0/9.0; // convert to degrees C
    Serial.println(T_Core);
  }
}

The user interface consists of a 5 push button key pad with according pull-down resistors and a 5V-ready 128 x 64 OLED from Adafruit:

The micro SD card requires a voltage level shifter on SCK/MOSI and CS pin which is carried out with a HEF4050:

SD_socket_schematic.jpg

The Real Time Clock (RTC) is based on a DS1307 with backup battery, which should keep time for 5 years or more. Also here are no additional pull-up resistors for the I²C bus necessary.

RTC_schematic.jpg

Beside the heart rate evaluation a so called Poincare plot has been added on software side. A Poincare plot returns a map in which each result of measurement is plotted as a function of the previous one. More formally, let

MT_EQ11_0.jpg

denote the data, then the return map will be a plot of the points

MT_EQ12.jpg

In our case the data are the elapsed times between two following heart beats. The shape of the Poincare plot can be used to visualize the heart rate variability (HRV). In this paper Poincare plots of healthy and critical ill patients are shown. The image below shows a Poincare plot of my heart rate on my medical tricorder display...

The Poincare plot after sampling is just a simple for-loop:

for(byte i = 1; i < sample_size - 1; i ++) {
  unsigned int delta_x = time[i + 1] - time[i];
  unsigned int delta_y = time[i + 2] - time[i + 1]; // compute measurement as a function of previous one
  unsigned int pixel_x = map(delta_x, 0, 2000, 0, 63); // map elapsed time in ms into pixel x coordinate
  unsigned int pixel_y = map(delta_y, 0, 2000, 63, 0); // map elapsed time in ms into pixel y coordinate
  display.drawPixel(pixel_x, pixel_y, WHITE); // print pixel
  display.display();
}

I also continued to learn more about Naive Bayes classifiers and wrote a first (yet simple) medical diagnosis sketch:

void setup() {
  Serial.begin(9600);
  diagnosis(true, false, true); // user input
}

void loop() {
}

void diagnosis(boolean sneeze, boolean cough, boolean fever) {
  // probability data set used for machine learning
  float Prob[] = {0.05, 0.05, 0.9};
  float P_sneeze[] = {0.9, 0.9, 0.1};
  float P_cough[] = {0.7, 0.8, 0.1};
  float P_fever[] = {0.4, 0.7, 0.01};
  // compute arg max
  if(sneeze == false) {
    for(int i = 0; i < 3; i ++) {
      P_sneeze[i] = 1.0 - P_sneeze[i]; 
    }
  }
  if(cough == false) {
    for(int i = 0; i < 3; i ++) {
      P_cough[i] = 1.0 - P_cough[i]; 
    }
  }
  if(fever == false) {
    for(int i = 0; i < 3; i ++) {
      P_fever[i] = 1.0 - P_fever[i]; 
    }
  }
  float P_allergy, P_cold, P_healthy;
  P_allergy = Prob[0]  P_sneeze[0]  P_cough[0]  P_fever[0];
  P_cold = Prob[1] 
 P_sneeze[1]  P_cough[1]  P_fever[1];
  P_healthy = Prob[2]  P_sneeze[2]  P_cough[2] * P_fever[2];
  // print diagnosis
  if(P_allergy > P_cold && P_allergy > P_healthy) {
    Serial.println(“Diagnosis: allergy”);
  }
  if(P_cold > P_allergy && P_cold > P_healthy) {
    Serial.println(“Diagnosis: cold”);
  }
  if(P_healthy > P_allergy && P_healthy > P_cold) {
    Serial.println(“Diagnosis: healthy”);
  }
}


As the device is called Tricorder and there are three defined basic vital signs (body temperature, pulse rate and respiration rate), I want to add a respiration rate (also called breathing rate) sensor for the MK II version of the medical tricorder. I plan to do this basically with a disposable respirator- half-mask, a 3-D printed connection nipple, a piece of silicone hose and a pressure sensor like the MPXV4006GP. The images below illustrate the idea:

Clip_-_Copy.jpg

Clip_-_Copy2.jpg

Freescale_Semiconductor-MPXV4006GP-image.jpg

Image credit: http://www.freescale.com/

More details will be added as I make progress.

Till then...stay healthy!

https://www.youtube.com/watch?v=A6dti7zWh9A

Oh, I am using the MLX90614

Oh, I am using the MLX90614 for non contact temperature measurements…as mentioned in my post…Should we check your health :p?

Tri…yes…I am working on a third sensor…

This is so cool, Star Trek

This is so cool, Star Trek gave us the cellphone, the tablet, and now thanks to you, the Tricorder! Are you planning to add that little scanner attachment (on Bluetooth?) as well? Could you add an ethernet shield so it can do some web-scraping on webmd.com or something and give a diagnosis?

Markus, that’s a cool

Markus, that’s a cool approach. With a third sensor it would be a real TRIcorder indeed. How about a gas sensor?

During a hackathon in Xinchejian last month Lio and Lucio built a hightech toilet seat with heating, tilt sensor, touch sensor, gas sensor (which is being fart-tested)

X Prize

Maybe you should be on one of the teams competing for the X Prize?  http://tricorder.xprize.org/

Also, I think the most obvious diagnostic tool would be a camera.  With a database of skin rashes and other visual symptoms, this seems like a must have.  Also, just as important would be the ability to combine an image with accurate measurements so having a distance sensor (or 2 cameras for 3d diagnostics) could be useful.

great

This is a great project, I love the idea. Good luck with it :slight_smile:

Temperature

It logs also temperature? Temperature is usually correlated to heart beat. There is a way to get also hydratation state?

Yes, yes and yes :slight_smile:

Yes, yes and yes :slight_smile: