Brian Zeoli, Joe Kupferberg ESE 111 Final Project

LINK TO ALL FILES (Code, Abstract, Description): https://www.dropbox.com/sh/1z8wa875yhko0gj/AADsjgJpdAS0Ass80vumunDDa?dl=0

Our device, FitItch, is the future of pedometers; safety and efficiency are of top priority. FitItch came from a need for avid runners to understand their runs while maintaining safety. The device, which tracks pace to ensure users meet their fitness goals, maintains safety by monitoring skin temperature. With this data, individuals can enjoy and understand their runs safely and efficiently. The user’s data also posts instantaneously online, to make access and analysis more accessible. FitItch makes it easier to track your run, and comes with additional settings for overall functionality. With his data, the client can text friends about calories burned or simply record and track progress. Knowing caloric expenditure makes running more competitive; users strive to beat their previous bests with each run. We hope to increase the accuracy, safety, and enjoyment of running through FitItch.

To power our device, we’ve used our MintyBoost from class with battery power supplying our device through USB. The device is based off Arduino Leonardo. To communicate our data, we have access to Wi-Fi with Adafruit CC3000, which posts data online to ThingSpeak. We’ve also wired an Ethernet shield, as Wi-Fi is finicky outside of Detkin. The shield can post data while in Penn’s Detkin network; later we hope to join Penn’s network to increase the access area. ThingSpeak records steps taken, similar to a pedometer, but also distance traveled and calories burned. This data is exactly what users want: concise, accurate numbers that are available online.

For the pedometer aspect, we’ve used the ADXL335 accelerometer, which measures acceleration in all directions. The accelerometer calculates a non-moving benchmark for comparison, which serves as a baseline for the acceleration step detect. This provides a benchmark for comparison. To detect steps, we calculated an average threshold for various runners; if the accelerometer breaks that value, a step is registered. To understand the user’s desired pace, we’ve used an input system with buttons. The top height button initializes height at 4 feet; each button click increments height by 2 inches. For example, a 5-foot individual would click the top button 6 times. The bottom button initializes minutes per mile at 4, with each button click corresponding to a 10-second increase in desired time. For example, if a client wanted to run a 6-minute mile, he should click the bottom button twelve times. With this data, we can calculate the required number of steps per 10 seconds to maintain, or even exceed, the desired pace. According to research and data online, the average stride to height ratio is 0.6. We’ve used this data to calculate the desired pace for each runner. Users are alerted if their pace falls below the threshold. Our negative feedback provides an impetus to ensure runners are achieving, or exceeding, their goals. The middle button corresponds to mode. The program is initially set to input mode for height and minute per mile goal. After the first click of the mode button, the user is in step detect, or the active pedometer. Each additional click toggles between upload and step detect mode. During upload mode, the program calculates total steps taken, total distance traveled, and calories burned during exercise. FitItch posts the data to ThingSpeak for user understanding and analysis.

Our second feature uses the LM34 temperature probe. We measure temperature with a 10-step moving average to smooth out any outliers. The device is attached to the hip to ensure accurate readings. We calculate mean body temperature, or MBT, which is the best indicator for overall safety. From research, MBT=0.66* 98.6 + 0.33*(measured skin temperature). We’ve used a thermal pad, which is currently an insulating Band-Aid, to decrease the effects of wind on our device. If the user breaks 102 degrees, the maximum safe temperature during exercise, he is alerted via repeated buzzers. Bodily functions begin to break down at this temperature; we ensure the runner’s safety with an ongoing buzz from the Piezo.

We hope with the FitItch to improve running as a whole. As the future of pedometers, FitItch services the needs of both amateur and avid runners. With the input of goals and tangible post-run evaluations, users can achieve their goals much faster and safer. Temperature monitoring ensures safety during both hot and cold days. The data posted to ThingSpeak offers an opportunity for clients to understand their runs. With the FitItch, users can reach their goals faster, maintain safety, and ultimately improve their health.

ABSTRACT:

We plan to create a device called FitItch, which uses both temperature and acceleration data to monitor your run. The device will be attached at an individual’s hip using a patch to detect temperature; direct skin contact is necessary for the device. FitItch will monitor temperature and alert the user, via buzzer, if he exceeds 102 degrees Fahrenheit. Above this temperature, bodily complications may occur as the runner’s body is overheating. As a safety feature, the user will be alerted by a long buzzer sound immediately if temperature is too high. With the accelerometer, the user will monitor running pace. He will input the desired minutes per mile; we are considering a counter button to use this. With this data, FitItch will beep twice if the user breaks the minimum speed to achieve this. If the user goes below the speed, three beeps will sound. The beeps provide a feedback for running speeds. To calculate speed, there exists a ratio of stride length equals height * 1.14. The number of steps within ten seconds will be counted using the accelerometer, similar to the pedometer. Then:

6 * (#steps/10 seconds) = # steps * 1.14 * height = distance (feet)/minute minute steps

Feet > (# mins/mile)-1 = miles / # mins * 5280 ft/mile = feet/min Min

If this equation above checks, then two beeps will occur only once. If this is false, then three beeps occur every ten seconds to alert the runner to speed up.

Every 10 seconds, update the # steps/10 seconds to continually re-measure the speed. We could use a simple moving average over 10 seconds to find # steps per 1 second, then multiply by 60 for one minute. We could also use an array and store the ten most recent values; this consumes more memory and might be slower, but is more accurate.

If the average is below the desired number, the device will beep three times every ten seconds. If he exceeds the threshold and continues to, no beeps will sound since we don’t want to annoy a successful runner.

FitItch will then send a report to the individual after his run alerting him of the number of times he fell below his desired speed. Average temperature will also be displayed in the post-run report to ensure conditions were safe for the future.

Final Code:

include

include

//#include //#include //#include

include a

// Local Network Settings byte mac[] = { 0x34, 0x17, 0xEB, 0xA5, 0x5C, 0xAB }; // Must be unique on local network

// ThingSpeak Settings char thingSpeakAddress[] = "api.thingspeak.com"; String writeAPIKey = "C6MJC5IJW04ZBNVQ"; const int updateThingSpeakInterval = 16 * 1000; // Time interval in milliseconds to update ThingSpeak (number of seconds * 1000 = interval)

// Variable Setup long lastConnectionTime = 0; boolean lastConnected = false; int failedCounter = 0; boolean done = false;

// Initialize Arduino Ethernet Client EthernetClient client;

const int startpin = 1; // feel free to change const int zpin = A0; const int ypin = A1; const int xpin = A2; const int groundpin = A3; const int powerpin = A4; const int buzzpin = 9; const int heightpin = 2; const int timepin = 0; const int temppin = A5;

int steps; int oneStep; // number of steps with one foot int numStepCheck; //check for total number of steps int flag = 0;

float zval, yval, xval; // acceleration components float zbar, ybar, xbar; // average acceleration when not in motion float totMag; // the magnitude of the acceleration vector float mpmile, height; int threshold; int val; int temp; int valheight=0; //input button int valtime=0; //input button

int valstart = 0; time_t startTime; int heightAdd=0; int timeAdd=0; int startS=0; int buttonState1 =0; int buttonState2 =0; int buttonState3 = 0; int lastButtonState1=0; int lastButtonState2=0; int lastButtonState3 = 0; int start = 0; int tempcount;

void setup(){ /* set the pin modes necessary for the accelerometer, LED, and button / / make sure that the serial monitor is initialized */ Serial.begin(9600);

pinMode(groundpin, OUTPUT); pinMode(powerpin, OUTPUT); digitalWrite(groundpin, LOW); digitalWrite(powerpin, HIGH);

pinMode(startpin,INPUT); pinMode(zpin,INPUT); pinMode(ypin,INPUT); pinMode(xpin,INPUT); pinMode (heightpin, INPUT); pinMode (timepin, INPUT);

pinMode (temppin, INPUT);

pinMode(groundpin,OUTPUT); pinMode(powerpin,OUTPUT); digitalWrite(groundpin,LOW); digitalWrite(powerpin,HIGH);

while(start == 0){ valheight = digitalRead(heightpin); valtime = digitalRead(timepin); valstart = digitalRead(startpin); temp = analogRead(temppin); tempcount = 1;

if(valheight != lastButtonState1){ if(valheight == HIGH) { heightAdd = heightAdd + 2; } } if(valtime != lastButtonState2){ if(valtime == HIGH) { timeAdd = timeAdd + 10; } } if(valstart != lastButtonState3){ if(valstart == HIGH){ start++; } } lastButtonState1=valheight; lastButtonState2=valtime; lastButtonState3 = valstart;

Serial.print("Height "); Serial.println(heightAdd); Serial.print("Time "); Serial.println(timeAdd);

}

height = 4 + heightAdd/12.0; mpmile = 4 + timeAdd/ 60.0; steps = 0; threshold = round(5280. / (6 * mpmile * .6 * height)); val =0; startEthernet(); startTime = now(); }

/* Read accelerometer data, calculate magnitude, detect number of steps per 10 seconds, beep if lower than threshold. Reset step count to 0. */ void loop(){ temp = analogRead(temppin); for (int i = 0; i<10; i++) { temp += .34*analogRead(temppin) + .66*98.6; delay(1); } temp /= 11.0; // Serial.print("temp"); // Serial.println(temp);

if (temp >= 102){ digitalWrite(buzzpin, HIGH); delay(150); digitalWrite(buzzpin, LOW);

} valstart = digitalRead(startpin); if(valstart != lastButtonState3){ if(valstart == HIGH) { start++; } } lastButtonState3 = valstart;

if(start % 2 == 1){ done = false; if (now() - startTime > 10) { if (oneStep >= threshold - 1) { Serial.print ("Success "); } else { Serial.print ("Failure "); digitalWrite(buzzpin, HIGH); delay(100); digitalWrite(buzzpin, LOW); delay(50); digitalWrite(buzzpin, HIGH); delay(100); digitalWrite(buzzpin, LOW); } Serial.print (oneStep); Serial.print ("/"); Serial.println(threshold); startTime = now(); oneStep = 0; } posCal(); stepDetect(); done = false; } else { if (start >= 2 && start%2==0) { int distance = round(steps*.6*height); int stepswalked = steps; int caloriesburned = distance/20; String data1 = "field1=" + String(distance); String data2 = "&field2=" + String(stepswalked); String data3 = "&field3=" + String(caloriesburned); String send = data1 + data2 +data3; // Print Update Response to Serial Monitor if (client.available()) { char c = client.read(); Serial.print(c); }

            // Disconnect from ThingSpeak
            if (!client.connected() && lastConnected)
            {
              Serial.println("...disconnected");
              Serial.println();
              client.stop();
            }
            // Update ThingSpeak
            if(!client.connected() && (millis() - lastConnectionTime > updateThingSpeakInterval))
            {
              updateThingSpeak(send);

            }
            // Check if Arduino Ethernet needs to be restarted
            if (failedCounter > 3 ) {
      startEthernet();
            }
            lastConnected = client.connected();

}
} }

// DOES THIS NEED TO DELAY? /* This should calibrate to the starting orientation / / In other words, this function should set xbar, ybar, and zbar to values that represent the average value of xval, yval, and zval respectively when you have the arduino placed on your body for step detection, but you are not moving. */ void updateThingSpeak(String tsData) { if (client.connect(thingSpeakAddress, 80)) { client.print("POST /update HTTP/1.1\n"); client.print("Host: api.thingspeak.com\n"); client.print("Connection: close\n"); client.print("X-THINGSPEAKAPIKEY: "+writeAPIKey+"\n"); client.print("Content-Type: application/x-www-form-urlencoded\n"); client.print("Content-Length: "); client.print(tsData.length()); client.print("\n\n"); client.print(tsData); lastConnectionTime = millis(); if (client.connected()) { Serial.println("Connecting to ThingSpeak..."); Serial.println(); failedCounter = 0; } else { failedCounter++; Serial.println("Connection to ThingSpeak failed ("+String(failedCounter, DEC)+")"); Serial.println(); } } else { failedCounter++; Serial.println("Connection to ThingSpeak Failed ("+String(failedCounter, DEC )+")"); Serial.println(); lastConnectionTime = millis(); } }

void startEthernet() { client.stop(); Serial.println("Connecting Arduino to network..."); Serial.println(); delay(1000); // Connect to network amd obtain an IP address using DHCP if (Ethernet.begin(mac) == 0) { Serial.println("DHCP Failed, reset Arduino to try again"); Serial.println(); } else { Serial.println("Arduino connected to network using DHCP"); Serial.println(); } delay(1000); }

void posCal(){ xval = 0; yval = 0; zval = 0; for (int i = 0; i<100; i++) { xval += analogRead(xpin); yval += analogRead(ypin); zval += analogRead(zpin); } xbar = (xval)/100; ybar = (yval)/100; zbar = (zval)/100;
}

/* This function should use the running totMag value to determine if there has been a step, and if there has, the step counter should be increased by 1 */ // If Mag is greater than threshold change flag to 1

void stepDetect(){ xval = analogRead(xpin); yval = analogRead(ypin); zval = analogRead(zpin); totMag = sqrt((xval-xbar)(xval-xbar)+(yval-ybar)(yval-ybar)+(zval-zbar)*(zval-zbar)); if ((totMag > 40) && (flag == 0)){ Serial.println("Step"); oneStep = oneStep + 1; steps = steps + 1; flag = 1; } //Serial.println(totMag); if (totMag < 40){ flag = 0; } //removed check }

Share this project:

Updates