/* Zachary Allen ENGR 103 Professor Heer 12 June 2023 My program tracks my roommate’s gaming activity for 24 hours. Using an ultrasonic sensor to detect his presence at his desk, I tracked how close he is to his screen with a programmed Arduino ESP32 embedded device. For every 10 minutes, I tracked the total time he is at his desk in that interval, the closest he got to his screen, and the farthest (while still being at the desk) he got to the screen. By the end of the 24 hours, I had data on how much time he was active, his average distance from the screen for every ten minutes, and his overall closest and farthest distance from the screen. */ //Variables that change based off apparratus const int trigPin = 5; const int echoPin = 18; const float inactiveDistanceMark = 85.00; //define sound speed in cm/uS #define SOUND_SPEED 0.034 //Count time active vs. inactive float secondsActive = 0; float secondsInactive = 3;//3 seconds of inactivity as program runs setup() //Every Ten Minute Values //Array to keep data for 10 min float avgDistance = 0; float lowDistance = inactiveDistanceMark;//Will be checked through inequalities, so set to max float highDistance = 0; float secondsActiveinTenMin = 0; float secondsInactiveinTenMin = 0; int activeCheck = 0;//Checks if there was any activity within the 10 minutes //24 Hour Values //Each Column represents 10 min in the 24 hours const unsigned long oneDay = 86400000; //Row 1 = Average Distance from screen WHEN ACTIVE //Row 2 = Closest Distance to screen WHEN ACTIVE //Row 3 = Farthest Distance from the screen WHEN ACTIVE float distanceStats[3][144]; int minCounter = 0;//tracks index of column for distanceStats[][] //Calculates distance for every second float FindDistanceCm(void){ long duration; float distance; //Clears trigger digitalWrite(trigPin, LOW); delayMicroseconds(2); //Activates Trigger digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); //Counts time it takes to come back duration = pulseIn(echoPin, HIGH); //Converts to Distance distance = duration * SOUND_SPEED/2; return distance; } //Inputs values into main array and resets needed values for every 10 minutes void tenMinutes(int col){ //If any activity for 24 hours if(activeCheck==1){ distanceStats[0][col]=avgDistance/secondsActiveinTenMin; distanceStats[1][col]=lowDistance; distanceStats[2][col]=highDistance; }else{ distanceStats[0][col] =0; distanceStats[1][col] =0; distanceStats[2][col] = 0; } //reset ten minute values avgDistance = 0; lowDistance = inactiveDistanceMark; highDistance = 0; secondsActiveinTenMin = 0; activeCheck = 0; } //Does same thing as tenMinutes without resetting values void promptCheck(int col){ if(activeCheck==1){ distanceStats[0][col]=avgDistance/secondsActiveinTenMin; distanceStats[1][col]=lowDistance; distanceStats[2][col]=highDistance; }else{ distanceStats[0][col] =0; distanceStats[1][col] =0; distanceStats[2][col] = 0; } } //For 24 hour info, could just call array directly but this helps with formatting float checkStorage(int row, int col){ return distanceStats[row][col]; } //For 10min ifo float checkTempStorage(int index){ if(index ==0){ //average distance return avgDistance; } if(index == 1){ //closest distance return lowDistance; } if(index == 2){ //farthest distance return highDistance; } } //Calculate over average, max, min distances void calcAvg(int col){ float totAvg = 0; for(int i = 0; i<=col; i++){ if(distanceStats[0][col]!=0){ totAvg = totAvg + distanceStats[0][col]; } } totAvg = totAvg/(float)(col+1); Serial.print(totAvg); Serial.println(" centimeters"); } void calcFar(int col){ float farthest = distanceStats[2][0]; for(int i =0; i<=col;i++){ if(distanceStats[2][col]>farthest){ farthest = distanceStats[2][col]; } } Serial.print(farthest); Serial.println(" centimeters"); } void calcClose(int col){ float closest = distanceStats[1][0]; for(int i =0; i<=col;i++){ if(distanceStats[1][col]0){ closest = distanceStats[1][col]; } } Serial.print(closest); Serial.println(" centimeters"); } //prints out average distance for 10 minute periods where Grant is active at some point void print10MinSumm(int col){ Serial.print("Average distance from screen for "); Serial.print((col)*10); Serial.print("-"); Serial.print((col+1)*10); Serial.print(" minutes: "); Serial.print(distanceStats[0][col]); Serial.println(" centimeters"); } void printUserInfo(int col){ Serial.print("Seconds Active: "); Serial.println(secondsActive); Serial.print("Seconds Inactive: "); Serial.println(secondsInactive); Serial.print("Average Distance From Computer When Active: "); calcAvg(minCounter); Serial.print("Farthest Distance From Computer When Active: "); calcFar(minCounter); Serial.print("Closest Distance From Computer When Active: "); calcClose(minCounter); Serial.println("List of averages for every 10 minute interval (centimeters):"); Serial.println("If Grant was not active for those 10 minutes, \"INACTIVE\" will be displayed"); for(int i = 0;i<=col;i++){ if(distanceStats[0][i]!=0){ Serial.println(distanceStats[0][i]); }else{ Serial.println("INACTIVE"); } } Serial.println("END OF SUMMARY"); } //Done once, takes 3 seconds void setup() { Serial.begin(115200); // Starts the serial communication pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output pinMode(echoPin, INPUT); // Sets the echoPin as an Input } //On repeat, takes 1 second each iteration void loop() { //get Distance for second float instantDistance = FindDistanceCm(); //Checks for inactivty if(instantDistancecheckTempStorage(2)){ highDistance = instantDistance; } }else{ //Inactive secondsInactive = secondsInactive +1; //Helps keep track for averages secondsInactiveinTenMin = secondsInactiveinTenMin +1; } Serial.println(instantDistance); //Regulates time, loop only goes after each second while((millis()%1000)!=0){ delay(1); } //Checks if a ten minute update is needed if(millis()%600000==0){ Serial.println("It has been 10 minutes."); //Every ten minutes if(activeCheck==1){ Serial.println("Grant was active in the past 10 minutes"); } else{ Serial.println("Grant was not active in the past 10 minutes"); } tenMinutes(minCounter); print10MinSumm(minCounter); minCounter = minCounter + 1;// moves index of array } //print out a user prompt if(Serial.read()=='y'){ //updates stats promptCheck(minCounter); //print averages for each ten minute interval Serial.print("Summary of Grant's Activity for "); Serial.print(millis()/60000); Serial.println(" minutes:"); printUserInfo(minCounter); } //Signifies end of measured period if(millis()==oneDay){//one day in milliseconds Serial.println("It has been a day"); printUserInfo(minCounter); } } //Work Cited //Ruis Santos' code was used as a framework for the mechanics of the ultrasonic sensor as well as the conversion into cm of distance /********* Rui Santos Complete project details at https://RandomNerdTutorials.com/esp32-hc-sr04-ultrasonic-arduino/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. *********/