├── README.md └── main.cpp /README.md: -------------------------------------------------------------------------------- 1 | # ClubMaster: Golf Club Swing Tracker 2 | This project is an Arduino-based golf club swing tracker named "ClubMaster." It uses an Arduino Nano with an LSM6DSOX inertial measurement unit (IMU) to measure and track the swing speed, angle, and acceleration of a golf club. The data is then sent to the Arduino IoT Cloud for real-time monitoring and analysis. 3 | 4 | ## Features 5 | Measure Swing Speed: Calculates the speed of the golf club head at the point of impact. 6 | Track Swing Angle: Measures the angle of the swing to analyze swing path. 7 | Acceleration Monitoring: Tracks the acceleration during the swing to identify key metrics. 8 | Stroke Count: Counts the number of strokes/hits during practice. 9 | Maximum Speed: Records the maximum swing speed achieved. 10 | IoT Cloud Integration: Sends data to the Arduino IoT Cloud for real-time monitoring. 11 | ## Components 12 | Arduino Nano with LSM6DSOX IMU 13 | Lithium Battery (provides 4 hours of battery life) 14 | Step-up Converter (to power the Arduino) 15 | 3D-printed Mount (design available in the repository) 16 | # Getting Started 17 | ## Hardware Setup 18 | Reccomended board: Arduino Nano RP2040 (Has the built-in IMU) 19 | Assemble Components: Connect the Arduino Nano, battery, and step-up converter according to the circuit diagram. 20 | Install in Golf Club: Place the assembled components inside the 3D-printed mount and secure it in the golf club. 21 | ## Software Setup 22 | Arduino IDE: Install the Arduino IDE. 23 | Libraries: Install the following libraries through the Arduino Library Manager: 24 | Arduino_LSM6DSOX 25 | Arduino IoT Cloud 26 | Upload Code: Upload the provided Arduino code to the Arduino Nano. 27 | Arduino Code 28 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "thingProperties.h" 2 | #include 3 | 4 | float Ax, Ay, Az; 5 | float velocity = 0; 6 | bool toggle = true; 7 | unsigned long previousMillis = 0; // Store the last update time 8 | unsigned long currentMillis = millis(); 9 | float deltaTime = (currentMillis - previousMillis) / 1000.0; // Delta time in seconds 10 | float accel; 11 | 12 | const float conversionFactor = 2.237; 13 | 14 | void setup() { 15 | // Initialize serial and wait for port to open: 16 | Serial.begin(9600); 17 | 18 | if (!IMU.begin()) { 19 | Serial.println("Failed to initialize IMU!"); 20 | while (1); 21 | } 22 | 23 | Serial.print("Accelerometer sample rate = "); 24 | Serial.print(IMU.accelerationSampleRate()); 25 | Serial.println("Hz"); 26 | Serial.println(); 27 | 28 | Serial.print("Gyroscope sample rate = "); 29 | Serial.print(IMU.gyroscopeSampleRate()); 30 | Serial.println("Hz"); 31 | Serial.println(); 32 | 33 | 34 | // Defined in thingProperties.h 35 | initProperties(); 36 | 37 | // Connect to Arduino IoT Cloud 38 | ArduinoCloud.begin(ArduinoIoTPreferredConnection); 39 | 40 | /* 41 | The following function allows you to obtain more information 42 | related to the state of network and IoT Cloud connection and errors 43 | the higher number the more granular information you’ll get. 44 | The default is 0 (only errors). 45 | Maximum is 4 46 | */ 47 | setDebugMessageLevel(2); 48 | ArduinoCloud.printDebugInfo(); 49 | 50 | max_mph = 0; 51 | } 52 | 53 | void loop() { 54 | ArduinoCloud.update(); // Update any cloud-related functions 55 | 56 | if (IMU.accelerationAvailable()) { 57 | IMU.readAcceleration(Ax, Ay, Az); 58 | 59 | 60 | // Calculate the magnitude of the acceleration vector 61 | // This is a more accurate representation than just summing the components 62 | accel_magnitude = (sqrt(Ax * Ax + Ay * Ay + Az * Az) - 1)*10; // Subtract gravity 63 | currentMillis = millis(); 64 | deltaTime = (currentMillis - previousMillis) / 1000.0; // Delta time in seconds 65 | 66 | 67 | if (abs(accel_magnitude) > 0.5) { 68 | velocity += accel_magnitude * deltaTime; 69 | } else { 70 | velocity = 0; // or apply some decay factor to velocity 71 | } 72 | 73 | // Convert to MPH 74 | mph = velocity * conversionFactor; 75 | 76 | // Check if the acceleration exceeds a threshold and the toggle is true 77 | if (accel_magnitude > 4.0 && toggle == true) { 78 | stroke_Count += 1; // Increment the hit counter 79 | toggle = false; // Reset toggle to avoid counting the same hit multiple times 80 | } 81 | else if (accel_magnitude <= 4.0 && toggle == false) { 82 | toggle = true; // Reset toggle when acceleration is back to normal 83 | } 84 | } 85 | previousMillis = currentMillis; 86 | if(mph > max_mph){ 87 | max_mph = mph; 88 | } 89 | Serial.println(accel_magnitude); 90 | 91 | delay(100); // Wait for 100 milliseconds before the next loop iteration 92 | } 93 | 94 | 95 | /* 96 | Since AccelMagnitude is READ_WRITE variable, onAccelMagnitudeChange() is 97 | executed every time a new value is received from IoT Cloud. 98 | */ 99 | void onAccelMagnitudeChange() { 100 | // Add your code here to act upon AccelMagnitude change 101 | } 102 | 103 | /* 104 | Since StrokeCount is READ_WRITE variable, onStrokeCountChange() is 105 | executed every time a new value is received from IoT Cloud. 106 | */ 107 | void onStrokeCountChange() { 108 | // Add your code here to act upon StrokeCount change 109 | } 110 | 111 | /* 112 | Since MaxMph is READ_WRITE variable, onMaxMphChange() is 113 | executed every time a new value is received from IoT Cloud. 114 | */ 115 | void onMaxMphChange() { 116 | // Add your code here to act upon MaxMph change 117 | } 118 | 119 | /* 120 | Since Mph is READ_WRITE variable, onMphChange() is 121 | executed every time a new value is received from IoT Cloud. 122 | */ 123 | void onMphChange() { 124 | // Add your code here to act upon Mph change 125 | } 126 | 127 | /* 128 | Since Reset is READ_WRITE variable, onResetChange() is 129 | executed every time a new value is received from IoT Cloud. 130 | */ 131 | void onResetChange() { 132 | // Add your code here to act upon Reset change 133 | stroke_Count = 0; 134 | max_mph = 0; 135 | } 136 | --------------------------------------------------------------------------------