CPR Trainer Final
By: Daniel Bustamante and Joe Solimanto
Description
The CPR trainer project uses the accelerometer in a Wii Nunchuck to find the rate of compressions. The one set of LEDs uses the acceleration to show whether the compressions are reaching the correct depth, and the second set registers the amount of time between compressions (time and depth attained from health teacher and are .5 seconds a compression and 2 inches for the depth). Currently, the LEDs are set so the ideal compression depth and timing will light up the third LED. The LEDs are set so the minimum LED starts lit (which also shows if the nunchuck is upside down). Too much pressure and too long of compressions will light up the 4th and 5th LED, while too little pressure and too short of compressions will light up the 1st and 2nd LED.
Programming Description
The CPR trainer uses a nunchuck library attained online. This library allows the arduino to access the nunchucks data for acceleration and for the buttons. However, the CPR trainer program only uses one of the accelerations (which is why the nunchuck is on its side) For the CPR trainer, the program primarily uses if else functions to determine which LEDs will light for the depth. For timing, the programing once again uses if else functions, but this time it is based off a counter (millis) that starts when the program starts. Also, the if statement only measures for compressions that reach the ideal depth in order to avoid multiple points for a single compression.
The Program
#include <Wire.h> //pulls up wire.h library
#include "nunchuck_funcs.h" //pulls up nunchuck_funcs.h library
int loop_cnt=0; //adds loop_cnt as a variable
int t = 2500; //sets t as a variable
long time; //sets time as a large variable
long x = 0; //sets x as a large variable
long y = 0; //sets y as a large variable
long z =0; //sets z as a large variable
int d = 8; //sets d as 8
int e = 2; //sets e as 2
int a = 5; //sets a as 5
int b = 6; //sets b as 6
int c = 7; //sets c as 7
int f = 10; //sets f as 10
int g = 11; //sets g as 11
int h = 12; //sets h as 12
int i = 13; //sets i as 13
int j = 9; //sets j as 9
byte accx,accy,zbut,cbut; //sets accx,accy,zbut,cbut as bytes
void setup()
{
pinMode (a, OUTPUT); //sets pin a as an output
pinMode (b, OUTPUT); //sets pin b as an output
pinMode (c, OUTPUT); //sets pin c as an output
pinMode (d, OUTPUT); //sets pin d as an output
pinMode (e, OUTPUT); //sets pin e as an output
pinMode (f, OUTPUT); //sets pin f as an output
pinMode (g, OUTPUT); //sets pin g as an output
pinMode (h, OUTPUT); //sets pin h as an output
pinMode (i, OUTPUT); //sets pin i as an output
pinMode (j, OUTPUT); //sets pin j as an output
Serial.begin(19200); // arduino sends data back in 19200
nunchuck_setpowerpins(); //sets analog pins as ground and positive for nunchuck
nunchuck_init(); // send the initilization handshake
Serial.print("WiiChuckDemo ready\n"); // prints WiiChuckDemo ready in serial moniter
}
void loop()
{
if( loop_cnt > 100 ) { // every 100 msecs get new data
loop_cnt = 0; // sets loop_cnt equal to 0
nunchuck_get_data(); // recieves data from nunchuck
accx = nunchuck_accelx(); // ranges from approx 70 - 182
if (accx > 160) {
digitalWrite (a,HIGH);} //if accx > 160 a is on
else {
digitalWrite (a, LOW);} //if accx< 160 a is off
if (accx > 183) {
digitalWrite (b,HIGH);} //if accx>183 b is on
else {
digitalWrite (b, LOW);} //if accx<183 b is off
if (accx > 190) {
digitalWrite (c,HIGH);} //if accx>190 c is on
else {
digitalWrite (c, LOW);} //if accx<190 c is off
if (accx > 205) {
digitalWrite (d,HIGH);} //if accx>205 d is on
else {
digitalWrite (d, LOW);} //if accx<205 d is off
if (accx > 220) {
digitalWrite (e,HIGH);} //if accx>220 e is on
else {
digitalWrite (e, LOW);} //if accx<220 e is off
if (accx > 190)
{
Serial.print("accx: "); Serial.print((byte)accx,DEC); //prints byte for accx when >190 Serial.print("time: "); Serial.println((long)millis(), DEC); //prints time for accx
x=millis(); //sets x equal to time in mseconds
z=x-y; //sets z equal to new time minus old time
if (z<1500){ //uses z only when difference of time less than 1.5 seconds
if (z > 100) {
digitalWrite (f,HIGH);} //when z >100 f is on
else {
digitalWrite (f, LOW);} //when z <100 f is off
if (z > 250) {
digitalWrite (g,HIGH);} //when z >250 g is on
else {
digitalWrite (g, LOW);} //when z < 250 g is off
if (z > 400) {
digitalWrite (h,HIGH);} //when z >400 h is on
else {
digitalWrite (h, LOW);} //when z<400 h is off
if (accx > 750) {
digitalWrite (i,HIGH);} //when z>750 i is on
else {
digitalWrite (i, LOW);} //when z<750 i is off
if (accx > 1000) {
digitalWrite (j,HIGH);} //when z>1000 j is on
else {
digitalWrite (j, LOW);} //when z<1000 j is off
}
}
y=x; //sets y equal to old time
}
loop_cnt++; //adds 1 to loop_cnt variable
delay(1); //delays for one microsecond
}
Problems
One problem encountered is the multiple data points for a single compression. So, if the arduino records two data points for a single compression, then the timing will register as too short. The best solution found so far is to only have the arduino register data above a certain acceleration so only one point will register for peak. However, this also creates the problem of too soft of compressions not registering a time. Currently, there is no solution we have found to having too soft of compressions register a time without having multiple points register for harder compressions.
Future Additions
If we had more time and money, we would like to work more on the timing problem. Also, there is probably a way to reduce the size of the current program. Another issue we could address is having the program work even when the nunchuck is upside down.