-
Product design
05/14/2015 at 03:34 • 0 commentsWhile I was waiting for parts to arrive [sigh], I put some thoughts into product design.
Screws and stand-offs attached:
Syringes attached to inject reagents into the Lab-on-a-chip:
-
LOC prototype
05/12/2015 at 05:55 • 0 commentsA simple Lab-on-a-chip prototype has been built from two microscope slides, a piece of 2 mm ABS sheet and three syringe needles (tip removed) to study the fluid mixing behavior.
-
Lab on a chip design
05/08/2015 at 04:24 • 0 commentsAs mentioned already under "Project details" I am planning to add a Lab-on-a-chip system as a peripheral device for the medical tricorder. It is basically a photometer/color sensor mounted beneath a translucent micro reaction chamber with two inlets for the reagents and one outlet for the waste. The volume of the reaction chamber is approx. 1.87 ml.
So far I have designed the 3-D printed parts and PCB and sent them off to the fab house. Below rendering shows how the LOC will look like.
Schematics:
I am using a TCS3472 color sensor. The mosfets Q2/Q3 (BSS138) building a logic level shifter for the 3.3V/5V I2C bus. R1 to R4 are the required pullup-resistors for the I2C bus. R6 is the pullup resistor for the gate of Q1, R5 is used as the series resistor for LED1. MC 33269D-3.3 is a low dropout, 800 mA positive voltage regulator. It requires an output capacitor of at least 10 μF for stability. As it is recommended I added an input capacitor with the same value as well.
Routed PCB:I will use the k-NN (k-nearest neighbors) algorithm, one of the simplest of all machine learning algorithms, to classify the detected color and assign it to the concentration of the detected substance, e.g. glucose via Trinder glucose activity test:
As the training set of colors associated to the concentration of a certain substance will only contain one sample per color, k = 1. And as we have RGB values, we will work in a 3-dimensional Euclidean space. So all we have to do is to find the smallest Euclidean distance from the sample point to any of the training points.
In general, for an n-dimensional Euclidean space, the Euclidean distance between two points
and
is given by
Example pH. The triangle shaped-point is a new sample which needs to be classified. In this case the nearest neighbor is the point with the marker 'pH=7.5.
-
Blood type calculator
05/03/2015 at 07:09 • 0 commentsDo you know your blood type and Rh factor? I always forget mine. Somewhere I should have a vaccination record, but where? I forget as well, where I put it.
Is there a way to evaluate my blood type and Rh factor without a blood test? If you know the blood types and Rh factors of your parents, you can at least limit the blood type and Rh factor you may have, using following algorithm and you can compute the highest probability, because blood types and Rh factors are not equally distributed.I started with a ABO blood type and Rh factor look-up table, transformed the tables into 2-dimensional char arrays and by studying the blood type distribution by country and the weighted mean, not only all possible blood types and Rh factors but also the ones with the maximum probability could be easily computed
// your input: String father_bloodtype = "AB"; String mother_bloodtype = "AB"; String father_RHtype = "-/-"; String mother_RHtype = "-/-"; void setup() { Serial.begin(9600); char* bloodtypes[] = {"A", "B", "AB", "O"}; char* RHtypes[] = {"+/+", "+/-", "-/-"}; char* your_bloodtype[4][4] = { {"A, B", "A, B, AB, O", "A, B, AB", "A, O"}, {"A, B, AB, O", "B, O", "A, B, AB", "B, O"}, {"A, B, AB", "A, B, AB", "A, B, AB", "A, B"}, {"A, O", "B, O", "A, B", "O"} }; char* your_bloodtype_prob[4][4] = { {"A", "O", "A", "O"}, {"O", "O", "A", "O"}, {"A", "A", "A", "A"}, {"O", "O", "A", "O"} }; char* your_RHtype[3][3] = { {"+/+", "+/+, -/-", "+/-"}, {"+/+, -/-", "+/+, +/-, -/-", "+/-, -/-"}, {"+/-", "+/-, -/-", "-/-"} }; char* your_RHtype_prob[3][3] = { {"+", "+", "+"}, {"+", "+", "+"}, {"+", "+", "-"} }; byte father_row; byte mother_col; for(byte i = 0; i < 4; i ++) { if(father_bloodtype.compareTo(bloodtypes[i]) == 0) father_row = i; if(mother_bloodtype.compareTo(bloodtypes[i]) == 0) mother_col = i; } Serial.print("Possible blood types: "); Serial.println(your_bloodtype[father_row][mother_col]); Serial.print("Blood type with highest probability: "); Serial.println(your_bloodtype_prob[father_row][mother_col]); for(byte i = 0; i < 3; i ++) { if(father_RHtype.compareTo(RHtypes[i]) == 0) father_row = i; if(mother_RHtype.compareTo(RHtypes[i]) == 0) mother_col = i; } Serial.print("Possible Rh factors: "); Serial.println(your_RHtype[father_row][mother_col]); Serial.print("Rh factor with highest probability: "); Serial.println(your_RHtype_prob[father_row][mother_col]); } void loop() { }
-
Relationship between systolic blood pressure, total/HDL cholesterol and BMI
05/02/2015 at 03:00 • 0 commentsThe relationship between total/HDL cholesterol and BMI can be expressed by simple linear regression models:
The relationship between the systolic blood pressure and BMI can be expressed by a simple multiple regression model:
Now diabetes type 2 and Framingham risk score calculator can be combined as mentioned in my previous project log. With the data we get from the diabetes type 2 questionnaire, we can compute total/HDL cholesterol and systolic blood pressure which are needed for the Framingham risk score algorithm. Video after the code snippet...
/* diabetes type 2 & heart attack risk calculator total/HDL cholesterol and systolic blood pressure estimated by linear regression models */ char commandbuffer[10]; int commandbuffer_index; void setup (){ Serial.begin(9600); Serial.flush(); } void loop () { char* a_c[] = {"a) ", "b) ", "c) "}; char* questionary[8][4] = { {"1. GENDER", "Female", "Male"}, {"2. HIGH BLOOD PRESSURE MEDICATION", "Yes", "No"}, {"3. STEROIDS MEDICATION", "Yes", "No"}, {"4. AGE [years]"}, {"5. BODY MASS [kg]"}, {"6. BODY HEIGHT [m]"}, {"7. FAMILY MEDICAL HISTORY", "No 1st degree family members with diabetes", "Parent OR siblings with diabetes mellitus", "Parent AND siblings with diabetes mellitus"}, {"8. SMOKER", "Non smoker", "Used to smoke", "Smoker"} }; int column_index[] = {2, 2, 2, 0, 0, 0, 3, 3}; boolean smoker, gender, medication; float score[6][4] = { {-0.879, 0.0}, {1.222, 0.0}, {2.191, 0.0}, {0.0, 0.699, 1.97, 2.518}, {0.0, 0.728, 0.753}, {0.0, -0.218, 0.855} }; float terms[7]; float mass, height, age, BMI, TC, HDLC, SBP; for(int i = 0; i < 8; i++) { for(int j = 0; j < column_index[i] + 1; j++) { if(j > 0) Serial.print(a_c[j-1]); Serial.println(questionary[i][j]); } while(1) { user_input(); if(i < 3 && ((commandbuffer_index > 0 && strcmp("a", commandbuffer) == 0) || (commandbuffer_index > 0 && strcmp("b", commandbuffer) == 0))) { if(strcmp("a", commandbuffer) == 0) { if(i == 0) gender = false; if(i == 1) medication = true; terms[i] = score[i][0]; break; } if(strcmp ("b", commandbuffer) == 0) { if(i == 0) gender = true; if(i == 1) medication = false; terms[i] = score[i][1]; break; } } if(i == 3 && user_input_to_int() > 0 && user_input_to_int() < 121) { Serial.print("Age: "); Serial.print(user_input_to_int()); Serial.println(" year(s)"); terms[i] = user_input_to_float(); age = user_input_to_float(); clear_buffer(); break; } if(i == 4 && user_input_to_float() > 5.0 && user_input_to_float() < 250.0) { Serial.print("Body mass: "); Serial.print(user_input_to_float()); Serial.println(" kg"); mass = user_input_to_float(); clear_buffer(); break; } if(i == 5 && user_input_to_float() > 0.4 && user_input_to_float() < 2.5) { Serial.print("Body height: "); Serial.print(user_input_to_float()); Serial.println(" m"); height = user_input_to_float(); BMI = mass / pow(height, 2.0); Serial.print("BMI: "); Serial.print(BMI); Serial.println(" kg/m^2"); if(BMI < 25.0) terms[i-1] = score[i-2][0]; if(BMI >= 25.0 && BMI < 27.5) terms[i-1] = score[i - 2][1]; if(BMI >= 27.5 && BMI < 30) terms[i-1] = score[i - 2][2]; if(BMI >= 30.0) terms[i-1] = score[i-2][3]; clear_buffer(); break; } if(i > 5 && ((commandbuffer_index > 0 && strcmp("a", commandbuffer) == 0) || (commandbuffer_index > 0 && strcmp("b", commandbuffer) == 0) || (commandbuffer_index > 0 && strcmp("c", commandbuffer) == 0))) { if(strcmp("a", commandbuffer) == 0) { if(i == 7) smoker = false; terms[i-1] = score[i-2][0]; break; } if(strcmp("b", commandbuffer) == 0) { if(i == 7) smoker = true; terms[i-1] = score[i-2][1]; break; } if(strcmp("c", commandbuffer) == 0) { if(i == 7) smoker = true; terms[i-1] = score[i-2][2]; break; } } } Serial.println(""); } // compute diabetes type 2 risk float exponent = 6.322-terms[0]-terms[1]-terms[2]-0.063*terms[3]-terms[4]-terms[5]-terms[6]; float risk = 100.0/(1+exp(exponent)); Serial.print("RISK TO SUFFER FROM TYPE 2 DIABETES: "); Serial.print(risk, 3); Serial.println(" %"); Serial.println(""); // compute total cholesterol TC = 28.07+6.49*BMI; if(TC < 130.0) TC = 130.0; // set limits if(TC > 320.0) TC = 320.0; // compute HDL cholesterol HDLC = 111.79-2.35*BMI; if(HDLC < 20.0) HDLC = 20.0; // set limits if(HDLC > 60.0) HDLC = 60.0; char* cholesterol_text[] ={"ESTIMATED ", "TOTAL ", "HDL ", "CHOLESTEROL: ", " mg/dl"}; Serial.print(cholesterol_text[0]); Serial.print(cholesterol_text[1]); Serial.print(cholesterol_text[3]); Serial.print(TC); Serial.println(cholesterol_text[4]); Serial.print(cholesterol_text[0]); Serial.print(cholesterol_text[2]); Serial.print(cholesterol_text[3]); Serial.print(HDLC); Serial.println(cholesterol_text[4]); // compute systolic blood pressure SBP = 68.15+0.58*BMI+0.65*age+0.94*float(gender)+6.44*float(medication); if(SBP < 90.0) SBP = 90.0; // set limits if(SBP > 200.0) SBP = 200.0; Serial.print(cholesterol_text[0]); Serial.print("SYSTOLIC BLOOD PRESSURE: "); Serial.print(SBP); Serial.println(" mm Hg"); // Framingham risk score only valid for age between 20 and 79 if(int(age) >= 20 && int(age) <= 79) { Serial.println(""); int CHD_score; // look-up tables obtained from http://en.wikipedia.org/wiki/Framingham_Risk_Score int score_age_women_men[10][4] = { {20, 34, -7, -9}, {35, 39, -3, -4}, {40, 44, 0, 0}, {45, 49, 3, 3}, {50, 54, 6, 6}, {55, 59, 8, 8}, {60, 64, 10, 10}, {65, 69, 12, 11}, {70, 74, 14, 12}, {75, 79, 16, 13} }; int tot_cholesterol_women_men[5][12] = { {130, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {160, 199, 4, 3, 2, 1, 1, 4, 3, 2, 1, 0}, {200, 239, 8, 6, 4, 2, 1, 7, 5, 3, 1, 0}, {240, 279, 11, 8, 5, 3, 2, 9, 6, 4, 2, 1}, {280, 320, 13, 10, 7, 4, 2, 11, 8, 5, 3, 1} }; int smoker_women_men[5][2] = { {9, 8}, {7, 5}, {4, 3}, {2, 1}, {1, 1} }; int HDL_cholesterol_women_men[4][3] = { {60, 100, -1}, {50, 59, 0}, {40, 49, 1}, {20, 39, 2} }; int blood_pressure_women_men[5][6] = { {90, 119, 0, 0, 0, 0}, {120, 129, 1, 3, 0, 1}, {130, 139, 2, 4, 1, 2}, {140, 159, 3, 5, 1, 2}, {160, 200, 4, 6, 2, 3} }; int CHD_risk_score[14][6] = { {-10, 8, -10, 0, 1, 1}, {9, 12, 1, 4, 1, 1}, {13, 14, 5, 6, 2, 2}, {15, 15, 7, 7, 3, 3}, {16, 16, 8, 8, 4, 4}, {17, 17, 9, 9, 5, 5}, {18, 18, 10, 10, 6, 6}, {19, 19, 11, 11, 8, 8}, {20, 20, 12, 12, 11, 10}, {21, 21, 13, 13, 14, 12}, {22, 22, 14, 14, 17, 16}, {23, 23, 15, 15, 22, 20}, {24, 24, 16, 16, 27, 25}, {25, 46, 17, 46, 30, 30} }; // compute age score for(int i = 0; i < 10; i++) { if(gender == false && int(age) >= score_age_women_men[i][0] && int(age) <= score_age_women_men[i][1]) { CHD_score = score_age_women_men[i][2]; break; } if(gender == true && int(age) >= score_age_women_men[i][0] && int(age) <= score_age_women_men[i][1]) { CHD_score = score_age_women_men[i][3]; break; } } // get age index for cholesterol and smoker score int j; for(j = 0; j < 9; j += 2) { if(int(age) >= score_age_women_men[j][0] && int(age) <= score_age_women_men[j+1][1]) { j = j/2; break; } } // compute cholesterol and smoker score for(int i = 0; i < 5; i++) { if(int(TC) >= tot_cholesterol_women_men[i][0] && int(TC) <= tot_cholesterol_women_men[i][1]) { if(gender == false) { CHD_score += tot_cholesterol_women_men[i][j+2]; if(smoker == true) CHD_score += smoker_women_men[j][0]; } if(gender == true) { CHD_score += tot_cholesterol_women_men[i][j+7]; if(smoker == true) CHD_score += smoker_women_men[j][1]; } break; } } // compute HDL cholesterol score for(int i = 0; i < 4; i++) { if(int(HDLC) >= HDL_cholesterol_women_men[i][0] && int(HDLC) <= HDL_cholesterol_women_men[i][1]) { CHD_score += HDL_cholesterol_women_men[i][2]; break; } } // compute blood pressure score for(int i = 0; i < 5; i++) { if(int(SBP) >= blood_pressure_women_men[i][0] && int(SBP) <= blood_pressure_women_men[i][1]) { if(gender == false) { if(medication == false) CHD_score += blood_pressure_women_men[i][2]; if(medication == true) CHD_score += blood_pressure_women_men[i][3]; } if(gender == true) { if(medication == false) CHD_score += blood_pressure_women_men[i][4]; if(medication == true) CHD_score += blood_pressure_women_men[i][5]; } } } // compute 10 year CHD risk for(int i = 0; i < 14; i++) { if(gender == false) { if(CHD_score >= CHD_risk_score[i][0] && CHD_score <= CHD_risk_score[i][1]) { if(i == 0) Serial.print("< "); if(i == 13) Serial.print("> "); Serial.print(CHD_risk_score[i][4]); break; } } if(gender == true) { if(CHD_score >= CHD_risk_score[i][2] && CHD_score <= CHD_risk_score[i][3]) { if(i == 0) Serial.print("< "); if(i == 13) Serial.print("> "); Serial.print(CHD_risk_score[i][5]); break; } } } Serial.println(" of 100 PEOPLE WITH THIS LEVEL OF RISK WILL HAVE A HEART ATTACK IN THE NEXT 10 YEARS"); Serial.println(""); } } void user_input() { commandbuffer_index = 0; if(Serial.available()){ delay(100); while(Serial.available() && commandbuffer_index < 9) { commandbuffer[commandbuffer_index++] = Serial.read(); } commandbuffer[commandbuffer_index++] = '\0'; } if(commandbuffer_index > 0) { Serial.print("Your answer: "); Serial.println((char*)commandbuffer); } } int user_input_to_int() { return atoi(commandbuffer); } float user_input_to_float() { return atof(commandbuffer); } void clear_buffer() { memset(commandbuffer, 0, strlen(commandbuffer)); }
-
Framingham risk score
05/01/2015 at 14:22 • 0 commentsThe Framingham risk score is an algorithm to estimate the 10-year risk of developing coronary heart disease (CHD). I want to combine the diabetes type 2 risk calculator with this algorithm because many of the input data are the same. Furthermore I want to research if total/HDL cholesterol as well as systolic blood pressure can be estimated from simple to obtain numerical data (e.g. BMI) or Boolean data (e.g. on high blood pressure medication? - yes, no) in case the user has no access to laboratory diagnosis and blood pressure monitor.
Code snippet of Framingham risk score algorithm below:
// Framingham Risk Score void setup() { Serial.begin(9600); } void loop() { // user input data boolean gender = true; // false: female, true: male boolean smoker = true; boolean medication = true; // high blood pressure medication int age = 60; int total_cholesterol = 200; // mg/dL int HDL_cholesterol = 20; // mg/dL int systolic_blood_pressure = 200; // mm Hg int CHD_score; // look-up tables obtained from http://en.wikipedia.org/wiki/Framingham_Risk_Score int score_age_women_men[10][4] = { {20, 34, -7, -9}, {35, 39, -3, -4}, {40, 44, 0, 0}, {45, 49, 3, 3}, {50, 54, 6, 6}, {55, 59, 8, 8}, {60, 64, 10, 10}, {65, 69, 12, 11}, {70, 74, 14, 12}, {75, 79, 16, 13} }; int tot_cholesterol_women_men[5][12] = { {130, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {160, 199, 4, 3, 2, 1, 1, 4, 3, 2, 1, 0}, {200, 239, 8, 6, 4, 2, 1, 7, 5, 3, 1, 0}, {240, 279, 11, 8, 5, 3, 2, 9, 6, 4, 2, 1}, {280, 320, 13, 10, 7, 4, 2, 11, 8, 5, 3, 1} }; int smoker_women_men[5][2] = { {9, 8}, {7, 5}, {4, 3}, {2, 1}, {1, 1} }; int HDL_cholesterol_women_men[4][3] = { {60, 100, -1}, {50, 59, 0}, {40, 49, 1}, {20, 39, 2} }; int blood_pressure_women_men[5][6] = { {90, 119, 0, 0, 0, 0}, {120, 129, 1, 3, 0, 1}, {130, 139, 2, 4, 1, 2}, {140, 159, 3, 5, 1, 2}, {160, 200, 4, 6, 2, 3} }; int CHD_risk_score[14][6] = { {-10, 8, -10, 0, 1, 1}, {9, 12, 1, 4, 1, 1}, {13, 14, 5, 6, 2, 2}, {15, 15, 7, 7, 3, 3}, {16, 16, 8, 8, 4, 4}, {17, 17, 9, 9, 5, 5}, {18, 18, 10, 10, 6, 6}, {19, 19, 11, 11, 8, 8}, {20, 20, 12, 12, 11, 10}, {21, 21, 13, 13, 14, 12}, {22, 22, 14, 14, 17, 16}, {23, 23, 15, 15, 22, 20}, {24, 24, 16, 16, 27, 25}, {25, 46, 17, 46, 30, 30} }; // compute age score for(int i = 0; i < 10; i++) { if(gender == false && age >= score_age_women_men[i][0] && age <= score_age_women_men[i][1]) { CHD_score = score_age_women_men[i][2]; break; } if(gender == true && age >= score_age_women_men[i][0] && age <= score_age_women_men[i][1]) { CHD_score = score_age_women_men[i][3]; break; } } // get age index for cholesterol and smoker score int j; for(j = 0; j < 9; j += 2) { if(age >= score_age_women_men[j][0] && age <= score_age_women_men[j+1][1]) { j = j/2; break; } } // compute cholesterol and smoker score for(int i = 0; i < 5; i++) { if(total_cholesterol >= tot_cholesterol_women_men[i][0] && total_cholesterol <= tot_cholesterol_women_men[i][1]) { if(gender == false) { CHD_score += tot_cholesterol_women_men[i][j+2]; if(smoker == true) CHD_score += smoker_women_men[j][0]; } if(gender == true) { CHD_score += tot_cholesterol_women_men[i][j+7]; if(smoker == true) CHD_score += smoker_women_men[j][1]; } break; } } // compute HDL cholesterol score for(int i = 0; i < 4; i++) { if(HDL_cholesterol >= HDL_cholesterol_women_men[i][0] && HDL_cholesterol <= HDL_cholesterol_women_men[i][1]) { CHD_score += HDL_cholesterol_women_men[i][2]; break; } } // compute blood pressure score for(int i = 0; i < 5; i++) { if(systolic_blood_pressure >= blood_pressure_women_men[i][0] && systolic_blood_pressure <= blood_pressure_women_men[i][1]) { if(gender == false) { if(medication == false) CHD_score += blood_pressure_women_men[i][2]; if(medication == true) CHD_score += blood_pressure_women_men[i][3]; } if(gender == true) { if(medication == false) CHD_score += blood_pressure_women_men[i][4]; if(medication == true) CHD_score += blood_pressure_women_men[i][5]; } } } // compute 10 year CHD risk for(int i = 0; i < 14; i++) { if(gender == false) { if(CHD_score >= CHD_risk_score[i][0] && CHD_score <= CHD_risk_score[i][1]) { if(i == 0) Serial.print("< "); if(i == 13) Serial.print("> "); Serial.print(CHD_risk_score[i][4]); break; } } if(gender == true) { if(CHD_score >= CHD_risk_score[i][2] && CHD_score <= CHD_risk_score[i][3]) { if(i == 0) Serial.print("< "); if(i == 13) Serial.print("> "); Serial.print(CHD_risk_score[i][5]); break; } } } Serial.println(" of 100 people with this level of risk will have a heart attack in the next 10 years"); while(1) { } }
-
Second approach of a diabetes type 2 risk calculator
04/22/2015 at 12:30 • 0 commentsBased on this reference I started to develop a second diabetes type 2 risk calculator:
Term
Classification
Value
Sex Female -0.879 Male 0 Rx HTN
(High blood pressure medication)Yes 1.222 No 0 Rx Steroids
(Steroids medication)Yes 2.191 No 0 Age / [years] BMI
(Body mass index in kg/m²)< 25 0 25 - 27.49 0.699 27.5 - 29.99 1.97 ≥ 30 2.518 FMH
(Family medical history)No 1st degree family members with diabetes 0 Parent OR siblings with diabetes mellitus 0.728 Parent AND siblings with diabetes mellitus 0.753 Smoker Non smoker 0 Used to smoke -0.218 Smoker 0.855 The risk to suffer from diabetes type 2 is then given by
That's a logistic function of the form
with L = 100, midpoint x-value x0 = 0 and steepness k = -1. The plot of the risk function looks as follows:
Example code:
String commandbuffer; void setup() { Serial.begin(9600); } void loop() { char* a_c[] = {"a) ", "b) ", "c) "}; char* questionary[8][4] = { {"1. GENDER", "Female", "Male"}, {"2. HIGH BLOOD PRESSURE MEDICATION", "Yes", "No"}, {"3. STEROIDS MEDICATION", "Yes", "No"}, {"4. AGE [years]"}, {"5. BODY MASS [kg]"}, {"6. BODY HEIGHT [m]"}, {"7. FAMILY MEDICAL HISTORY", "No 1st degree family members with diabetes", "Parent OR siblings with diabetes mellitus", "Parent AND siblings with diabetes mellitus"}, {"8. SMOKER", "Non smoker", "Used to smoke", "Smoker"} }; int column_index[] = {2, 2, 2, 0, 0, 0, 3, 3}; float score[6][4] = { {-0.879, 0.0}, {1.222, 0.0}, {2.191, 0.0}, {0.0, 0.699, 1.97, 2.518}, {0.0, 0.728, 0.753}, {0.0, -0.218, 0.855} }; float terms[7]; float mass, height, BMI; for(int i = 0; i < 8; i++) { for(int j = 0; j < column_index[i] + 1; j++) { if(j > 0) Serial.print(a_c[j-1]); Serial.println(questionary[i][j]); } while(1) { user_input(); if(i < 3 && (commandbuffer == "a" || commandbuffer == "b")) { if(commandbuffer == "a") { input_reset(); terms[i] = score[i][0]; break; } if(commandbuffer == "b") { input_reset(); terms[i] = score[i][1]; break; } } if(i == 3 && commandbuffer.toInt() > 0 && commandbuffer.toInt() < 121) { Serial.print("Age: "); Serial.print(commandbuffer.toInt()); Serial.println(" year(s)"); terms[i] = float(commandbuffer.toInt()); input_reset(); break; } if(i == 4 && commandbuffer.toFloat() > 5.0 && commandbuffer.toFloat() < 250.0) { Serial.print("Body mass: "); Serial.print(commandbuffer.toFloat()); Serial.println(" kg"); mass = commandbuffer.toFloat(); input_reset(); break; } if(i == 5 && commandbuffer.toFloat() > 0.4 && commandbuffer.toFloat() < 2.5) { Serial.print("Body height: "); Serial.print(commandbuffer.toFloat()); Serial.println(" m"); height = commandbuffer.toFloat(); BMI = mass / pow(height, 2.0); Serial.print("BMI: "); Serial.print(BMI); Serial.println(" kg/m^2"); if(BMI < 25.0) terms[i-1] = score[i-2][0]; if(BMI >= 25.0 && BMI < 27.5) terms[i-1] = score[i - 2][1]; if(BMI >= 27.5 && BMI < 30) terms[i-1] = score[i - 2][2]; if(BMI >= 30.0) terms[i-1] = score[i-2][3]; input_reset(); break; } if(i > 5 && (commandbuffer == "a" || commandbuffer == "b" || commandbuffer == "c")) { if(commandbuffer == "a") { input_reset(); terms[i-1] = score[i-2][0]; break; } if(commandbuffer == "b") { input_reset(); terms[i-1] = score[i-2][1]; break; } if(commandbuffer == "c") { input_reset(); terms[i-1] = score[i-2][2]; break; } } else input_reset(); } Serial.println(""); } float exponent = 6.322-terms[0]-terms[1]-terms[2]-0.063*terms[3]-terms[4]-terms[5]-terms[6]; float risk = 100.0/(1+exp(exponent)); Serial.print("RISK TO SUFFER FROM TYPE 2 DIABETES: "); Serial.print(risk, 3); Serial.println(" %"); Serial.println(""); } void user_input() { if(Serial.available()){ delay(100); while(Serial.available()) { commandbuffer += (char)Serial.read(); } } } void input_reset() { commandbuffer = ""; }
-
Type 2 diabetes risk assessment
04/16/2015 at 07:17 • 0 commentsA risk assessment tool has been coded based on a short list of questions to assess the risk of developing type 2 diabetes over the next ten years. Example Arduino code below:
char incomingLetter; void setup() { Serial.begin(9600); } void loop() { Serial.println("TYPE 2 DIABETES RISK ASSESSMENT"); Serial.println(""); int score = 0; char * a_to_d[] = {"a) ", "b) ", "c) ", "d) "}; char * questionary[8][5] = { {"1. AGE", "Under 45 years", "45-54 years", "55-64 years", "Over 64 years"}, {"2. BODY-MASS INDEX, BMI = MASS [kg]/(HEIGHT [m])^2", "Lower than 25 kg/m^2", "25-30 kg/m^2", "Higher than 30 kg/m^2"}, {"3. WAIST CIRCUMFERENCE BELOW RIBS", "Men: Less than 94 cm, Women: Less than 80 cm", "Men: 94-102 cm, Women: 80-88 cm", "Men: More than 102 cm, Women: More than 88 cm"}, {"4. DAILY AT LEAST 30 MINUTES PHYSICAL ACTIVITY?", "Yes", "No"}, {"5. HOW OFTEN DO YOU EAT VEGETABLES OR FRUITS?", "Every day", "Not every day"}, {"6. HAVE YOU EVER TAKEN MEDICATION FOR HIGH BLOOD PRESSURE ON REGULARY BASIS?", "No", "Yes"}, {"7. HAVE YOU EVER BEEN FOUND TO HAVE HIGH BLOOD GLUCOSE?", "No", "Yes"}, {"8. HAVE ANY OF THE MEMBERS OF YOUR IMMEDIATE FAMILY BEEN DIAGNOSED WITH DIABETES TYPE 1 OR 2?", "No", "Yes: grandparent, aunt, uncle, first cousin (but no own parent, sister, brother or child)", "Yes: own parent, sister, brother or child"} }; int questionary_col_index[] = {3, 2, 2, 1, 1, 1, 1, 2}; int score_table[8][4] = { {0, 2, 3, 4}, {0, 1, 3}, {0, 3, 4}, {0, 2}, {0, 1}, {0, 2}, {0, 5}, {0, 3, 5} }; for(int i = 0; i < 8; i ++) { for(int j = 0; j < questionary_col_index[i] + 2; j ++) { if(j > 0) Serial.print(a_to_d[j - 1]); Serial.println(questionary[i][j]); } Serial.println(""); while(1) { user_input(); if(incomingLetter == 'a') { score += score_table[i][0]; reset_input(); break; } if(incomingLetter == 'b') { score += score_table[i][1]; reset_input(); break; } if(questionary_col_index[i] > 1 && incomingLetter == 'c') { score += score_table[i][2]; reset_input(); break; } if(questionary_col_index[i] > 2 && incomingLetter == 'd') { score += score_table[i][3]; reset_input(); break; } } } char * risk_assessment[] = { "estimated ", "LOW:", "1 in 100", "SLIGHTLY ELEVATED:", "1 in 25", "MODERATE:", "1 in 6", "HIGH:", "1 in 3", "VERY HIGH:", "1 in 2" }; Serial.print("THE RISK OF DEVELOPING TYPE 2 DIABETES WITHIN 10 YEARS IS "); if(score < 7) { Serial.println(risk_assessment[1]); Serial.print(risk_assessment[0]); Serial.print(risk_assessment[2]); } if(score > 6 && score < 12) { Serial.println(risk_assessment[3]); Serial.print(risk_assessment[0]); Serial.print(risk_assessment[4]); } if(score > 11 && score < 15) { Serial.println(risk_assessment[5]); Serial.print(risk_assessment[0]); Serial.print(risk_assessment[6]); } if(score > 14 && score < 21) { Serial.println(risk_assessment[7]); Serial.print(risk_assessment[0]); Serial.print(risk_assessment[8]); } if(score > 20) { Serial.println(risk_assessment[9]); Serial.print(risk_assessment[0]); Serial.print(risk_assessment[10]); } Serial.println(" will develope disease"); Serial.println(""); } void user_input() { if(Serial.available()) { delay(50); while(Serial.available()) { incomingLetter = Serial.read(); } } } void reset_input() { incomingLetter = ' '; }