Abstract
CRUTCH: Comfortable Responsive Universal Technology for Crutch Health revolutionizes mobility with a blend of smart technology and advanced mechanical support. Equipped with responsive sensors, ESP32 communication, Xiao boards, and a system of springs and dampers, CRUTCH transforms traditional crutches into adaptive, health-boosting tools. The integration of springs and dampers reduces impact and provides a smoother, more cushioned experience, minimizing strain on the user’s joints. With real-time tracking of posture, weight distribution, and movement through precise accelerometers, CRUTCH offers personalized feedback to encourage optimal alignment and prevent injury. This breakthrough project redefines support, ensuring each step is as safe, comfortable, and intelligent as possible.

Introduction : Background

Currently, traditional crutch designs lack dynamic responsiveness and adequate shock absorption, often leading to user discomfort and upper body strain. Our C.R.U.T.C.H project aims to address these limitations by integrating a mass-spring-damper system, offering adaptive damping and propulsion to enhance mobility and user comfort across diverse needs.
Introduction : Problem Statement

Traditional crutches fail to provide sufficient shock absorption and energy efficiency, leading to discomfort and strain for users. Our project seeks to solve this by integrating a mass-spring-damper system to enhance ergonomics and adaptability for diverse user needs.
Main Project Goals

Our project, C.R.U.T.C.H, stands for Comfortable, Responsive, Universal Technology for Crutch Health. The aim is to address the shortcomings of current crutch designs by integrating a mass-spring-damper system to improve shock absorption, energy transfer, and user comfort.
Project Mind Map
The following images demonstrate some of our initial design ideas that we wished to integrate into our CRUTCH project.


Project Breakdown
Beginner
ESP32 to ESP32 Communication
ESP32-to-ESP32 communication is a key component of this project, enabling the direct and wireless exchange of data from various sensors, such as accelerometers and load cells, without relying on a central router. By leveraging protocols like ESP-NOW or Wi-Fi, two ESP32 boards can seamlessly transmit and receive information, ensuring efficient data collection and storage.
Within the CRUTCH system, this capability allows sensor data, including accelerometer readings, to be shared wirelessly between crutches or with a central device. As a result, healthcare providers and users gain real-time insights into movement patterns, walking stability, and overall health metrics. This direct communication channel ultimately enhances the system’s efficiency, responsiveness, and ability to support improved patient safety and recovery outcomes.

ESP32 to Accelerometer Connection
An accelerometer is a sensor that measures acceleration, the rate of change in velocity over time. The MPU6050, a specific device integrating a 3-axis accelerometer and a 3-axis gyroscope, provides a comprehensive 6-degree-of-freedom motion tracking solution. By integrating this system with an ESP32 microcontroller, it becomes possible to efficiently detect motion and reliably transmit data, enabling robust monitoring and control applications. Such a setup can be employed to analyze walking patterns, detect irregularities such as uneven strides or improper crutch usage, and ultimately enhance user safety through real time feedback.
Workflow:
Data from accelerometer (MPU6050) → ESP32 processing → Communication via I2C.
Explanation of Components:
ESP32 Wroom:
- Powerful microcontroller with built-in Wi-Fi and Bluetooth.
- Ideal for wireless data logging and real-time sensor data transmission.
MPU6050 Accelerometer:
- Integrated 3-axis accelerometer and 3-axis gyroscope sensor.
- Measures acceleration, orientation, and movement patterns in real time.
Wiring Components:
Below is the wiring configuration for connecting an ESP32 to the MPU6050 sensor module:

After physically installing and connecting the ESP32 module to the MPU6050 accelerometer, the next step is to set up the software environment.
Begin by downloading and installing the Arduino IDE, an open-source development platform used for writing, compiling, and uploading code to various microcontrollers, including the ESP32. With the Arduino IDE, you can streamline the programming workflow—configuring I2C communication with the accelerometer, calibrating sensor readings, and integrating motion-related data directly into your CRUTCH project’s functionality.
Install the MPU6050 Arduino Library and then follow these steps:
- Open the Arduino IDE.
- Navigate to Sketch > Include Library > Manage Libraries.
- In the search bar, type “MPU6050”.
- Locate and install the MPU6050 library by Electronic Cats (or another reputable source).
This ensures the necessary functions and classes are readily available for interfacing your ESP32 with the MPU6050 accelerometer.
Now we can upload our code to a new sketch in the Arduino IDE to read data from the MPU6050 accelerometer. Before uploading, ensure that “ESP32 Dev Module” is selected as the board, and verify that the correct communication port is chosen to match your ESP32 device.
Code for ESP32 Sender (Connected to Accelerometer)
#include <Wire.h>
#include <WiFi.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
// Wi-Fi credentials
const char* ssid = “esp-32-server”;
const char* password = “12345678”;
// IP Address of Receiver ESP32
const char* receiverIP = “192.168.4.1”;
const int port = 8080;
// MPU6050 setup
Adafruit_MPU6050 mpu;
void setup() {
Serial.begin(115200);
// Initialize MPU6050
if (!mpu.begin()) {
Serial.println(“Failed to find MPU6050 chip. Check wiring!”);
while (1);
}
Serial.println(“MPU6050 initialized!”);
// Wi-Fi connection
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println(“Connecting to esp-32-server…”);
}
Serial.println(“Connected to Wi-Fi!”);
}
void loop() {
// Get accelerometer data
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
// Prepare data with labels
String data = “X: ” + String(a.acceleration.x) + “, Y: ” + String(a.acceleration.y) + “, Z: ” + String(a.acceleration.z);
// Send data to receiver ESP32
WiFiClient client;
if (client.connect(receiverIP, port)) {
client.println(data);
Serial.println(“Data sent: ” + data);
client.stop();
} else {
Serial.println(“Failed to connect to receiver”);
}
delay(500); // Adjust this for data frequency
}
Code for ESP32 Receiver (Connected to Computer)
#include <WiFi.h>
// Wi-Fi credentials
const char* ssid = “esp-32-server”;
const char* password = “12345678”;
// Create Wi-Fi server
WiFiServer server(8080);
void setup() {
Serial.begin(115200);
// Set up Wi-Fi Access Point
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print(“AP IP Address: “);
Serial.println(IP);
// Start server
server.begin();
}
void loop() {
WiFiClient client = server.available(); // Wait for client
if (client) {
String data = client.readStringUntil(‘\n’); // Read data
Serial.println(“Received: ” + data); // Forward to Serial Monitor
client.stop();
}
}


ESP32 to HX711 Amplifier to Load Cells Connection
For our CRUTCH project we established communication between two ESP32 WROOM to HX711 Sparkfun Amplifier and 50kg Load Cells. The purpose of this setup was to measure the forces exerted during the dynamic use of our CRUTCH and to compare the forces experienced using a regular crutch versus the CURTCH system that we created, which was equipped with a spring and damper mechanism. The data collected from this setup is important to help assess the impact-absorbing performance of the CRUTCH and its potential to help improve user comfortability and stability.
In this section, we will provide a step-by-step guide on how to complete the connection to this setup.
Explanation of Components:
- ESP32 Wroom:
- A powerful microcontroller with Wi-Fi and Bluetooth capabilities that is ideal for wireless data logging and allows real-time transmission of load cell data for visualization.
- HX711 SparkFun Amplifier:
- A 24-bit ADC (Analog-to-Digital Converter) that converts the small signals from the load cells into digital data that is readable by our ESP32 WROOM.
- 50kg Load Cells:
- A strain gauge sensor that measures forces applied during crutch use.
Wiring Components:
Using the following charts, schematics, and wiring pins, we can create a connection between the Load Cells and the HX711 Amplifier, as well as the HX711 Amplifier and our ESP32 WROOM.
- Load Cells to HX711 Amplifier:
- Connect the load cell wires to the HX711 pins following the connections of this image with the appropriate wiring colors

- HX711 Amplifier to ESP32 WROOM:
- Establish connection between the HX711 Amplifier to the ESP32 WROOM following this chart:

After physically installing and connecting the ESP32 WROOM to the HX711 Amplifier and 50kg load cells, we can install the software components.
For this, it is important to download Arduino IDE. This open-source software is used to write, compile, and upload code to Arduino boards and other compatible microcontrollers, such as the ESP32 that we are using for our CRUTCH project.
Install the HX711 Arduino Library and:
- Open the Arduino IDE.
- Go to Sketch > Include Library > Manage Libraries.
- Search for “HX711” and install the library by Bogdan Necula (bogde).
Now we can upload our code to a new sketch in Arduino IDE to calibrate our load cells. For this step, it is important to select “ESP32 Dev Module” as our board and the correct port to your computer.
Calibrating Code:
#include “HX711.h”
#define DT 4 // Data pin connected to GPIO 4
#define SCK 5 // Clock pin connected to GPIO 5
HX711 scale;
void setup() {
Serial.begin(115200);
scale.begin(DT, SCK);
// Calibrate your scale (adjust this factor based on testing)
scale.set_scale(2280.f); // Change this value based on calibration
scale.tare(); // Reset scale to 0
Serial.println(“HX711 Initialized!”);
}
void loop() {
if (scale.is_ready()) {
float weight = scale.get_units();
Serial.println(“Weight: ” + String(weight) + ” kg”); // Replace “kg” with “N” for force
} else {
Serial.println(“HX711 not ready”);
}
delay(500);
}
After uploading the code, do the following steps to make sure that the load cells are calibrated properly.
- Use a known weight to calibrate the load cells.
- Replace the value in scale.set_scale(2280.f) with the correct calibration factor after testing.
Now that we have calibrated our load cells, we can establish connection between both ESP32s. We want to do this so that we can get data transmission and one ESP32 (server) can collect sensor data (e.g., force from our load cells) and send it to another ESP32 (client) wirelessly.
This is useful for distributed systems like our CRUTCH project, where one ESP32 collects data and another processes it or displays it.
For this, each ESP32 will serve their own function as follows:
- Server ESP32: Handles data collection (e.g., load cell readings)
- Client ESP32: Sends data to our computer
We want to make sure that we have wireless connection to eliminate the need for physical connections, making the system more compact and practical. This is useful for testing and deployment of our CRUTCH in real-world conditions.
Here are the following Server and Client Codes that we will upload into our system:
Server Code (ESP32 connected with Load Cells):
#include <Wire.h>
#include <WiFi.h>
#include “SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h”
NAU7802 myScale;
// Calibration factor – Adjust this based on your calibration routine
float calibration_factor = 1000.0; // Example value; you need to calibrate this
// Wi-Fi credentials
const char* ssid = “ESP32_Server”;
const char* password = “12345678”;
// Wi-Fi server
WiFiServer server(80);
bool isTared = false; // Flag to check if tare is performed
unsigned long lastTareTime = 0;
const unsigned long tareInterval = 60000; // Retare every 60 seconds if unloaded
void setup() {
Serial.begin(115200);
Wire.begin(); // Initialize I2C communication
// Initialize the NAU7802
if (!myScale.begin()) {
Serial.println(“Failed to detect NAU7802. Check your wiring.”);
while (1); // Halt program
}
Serial.println(“NAU7802 detected!”);
// Set the calibration factor
myScale.setCalibrationFactor(calibration_factor);
Serial.println(“Calibration factor set.”);
// Set up Wi-Fi Access Point
WiFi.softAP(ssid, password);
Serial.println(“Wi-Fi Access Point started.”);
// Start the server
server.begin();
Serial.println(“Server started.”);
}
void loop() {
float forceInN = 0.0;
// Perform tare operation only once at startup
if (!isTared) {
Serial.println(“Taring the load cell. Please ensure it is unloaded…”);
delay(3000); // Wait for stabilization
myScale.calculateZeroOffset(); // Set the zero offset
Serial.println(“Tare completed.”);
isTared = true;
}
// Check if a new reading is available
if (myScale.available()) {
forceInN = myScale.getWeight(true);
// Clamp small or negative values to 0
if (forceInN < 0.5) {
forceInN = 0.0;
}
// Periodically retare the load cell if the weight is zero
if (forceInN == 0.0 && millis() – lastTareTime > tareInterval) {
myScale.calculateZeroOffset();
lastTareTime = millis();
Serial.println(“Re-tared the load cell.”);
}
}
// Handle client connections
WiFiClient client = server.available();
if (client) {
unsigned long timestampMillis = millis(); // Time in milliseconds
float timestampSeconds = timestampMillis / 1000.0; // Time in seconds
float timestampMinutes = timestampSeconds / 60.0; // Time in minutes
// Send both seconds and minutes to the client
String dataToSend = String(timestampSeconds, 3) + ” seconds (” + String(timestampMinutes, 3) + ” minutes), ” + String(forceInN) + ” N”;
client.println(dataToSend); // Send data to client
client.stop(); // Close connection
}
// Print timestamped force to the Serial Plotter
unsigned long timestampMillis = millis();
float timestampSeconds = timestampMillis / 1000.0;
float timestampMinutes = timestampSeconds / 60.0;
Serial.println(String(timestampSeconds, 3) + ” seconds (” + String(timestampMinutes, 3) + ” minutes): ” + String(forceInN) + ” N”);
delay(100); // Reduce delay for smoother real-time plotting
}
Client Code (ESP32 connected to computer):
#include <WiFi.h>
// Server Wi-Fi credentials
const char* ssid = “ESP32_Server”;
const char* password = “12345678”;
// Server details
const char* host = “192.168.4.1”; // Default IP for ESP32 in softAP mode
const int port = 80;
void setup() {
Serial.begin(115200); // Use the same baud rate as Serial Plotter
delay(2000); // Allow time for Serial Monitor/Plotter to connect
Serial.println(“Client setup started…”);
// Connect to the server’s Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println(“Connecting to Wi-Fi…”);
}
Serial.println(“Connected to Wi-Fi.”);
}
void loop() {
WiFiClient client;
// Connect to the server
if (client.connect(host, port)) {
// Wait for server response
while (client.connected() && client.available() == 0);
if (client.available()) {
String forceData = client.readStringUntil(‘\n’);
// Print timestamped data for Serial Plotter
if (forceData.length() > 0) {
Serial.println(forceData); // Output: seconds (minutes): force
}
}
client.stop(); // Close the connection
} else {
Serial.println(“0.000 seconds (0.000 minutes),0”); // Plot 0 for both timestamp and force if connection fails
}
delay(100); // Reduce delay for smoother real-time plotting
}
Once these codes are uploaded and the serial monitor and serail plotter are opened, the following data should be showing:
Here are the images of the components that we used for this setup:
ESP32 WROOM, HX711 Amplifier, and 50kg load cells



Here are some images of our physical setup once it has been connected to a battery power source.

Brief explanation of mechanical concepts of spring and damper

Here, we can see how the mass-spring-damper system works in a standard walker. This illustration helps us understand how these principles can be adapted for other mobility devices like crutches.

By applying mass-spring-damper system to the crutch, we designed a 3D CAD model of our crutch. We placed a spring under the shoulder pad in order to improve propulsion and we put a shock absorber at the bottom of the crutch to improve energy transfer.

By incorporating the mass-spring-damper system into our crutch design, we provide users with shock absorption tailored to their specific loads. This adaption ensures both comfort and efficiency in motion.
Intermediate
Real-time Measurement of Data for ESP32 and Accelerometer Connection
Real-time Measurement of Data for Load Cells Connection and Experiment
Our group decided to run an experiment that would compare our CRUTCH with a regular crutch using our load cells set up in order to be able to quantify the advantages of our CRUTCH system, which integrates a spring-damper mechanism, compared to a regular crutch. By using load cells to measure and analyze the forces exerted during crutch use, we could objectively evaluate the performance and validate our design’s benefits.
For this, we needed to log our data in real time and plot graphs of this data during our experiment.
To do this, we used the same codes that were provided in the beginner’s module: the server and client codes, along with the Python script provided below. This Python script is essential for real-time data visualization and analysis. It complements the ESP32 server and client setup by processing, displaying, and logging the load cell data sent wirelessly.
Python Script:
import serial
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from datetime import datetime
# Configuration
SERIAL_PORT = ‘/dev/cu.usbserial-0001’ # Replace with your ESP32 port
BAUD_RATE = 115200
# Open serial connection
ser = serial.Serial(SERIAL_PORT, BAUD_RATE)
# Data storage
timestamps_seconds = []
forces = []
# Create a CSV file to save data
output_filename = f”load_cell_data_{datetime.now().strftime(‘%Y%m%d_%H%M%S’)}.csv”
with open(output_filename, ‘w’) as f:
f.write(“Timestamp (s),Time (min),Force (N)\n”) # Updated header
# Function to parse the ESP32 data
def parse_data(line_data):
“””
Parses the raw data from ESP32.
“””
try:
if ‘,’ not in line_data:
print(“Invalid data format, skipping:”, line_data)
return None, None
parts = line_data.split(‘,’)
if len(parts) != 2:
print(“Unexpected number of parts, skipping:”, parts)
return None, None
timestamp_part = parts[0].strip()
force_part = parts[1].strip()
seconds = float(timestamp_part.split(‘ ‘)[0])
force = float(force_part.replace(‘N’, ”).strip())
return seconds, force
except ValueError as e:
print(f”Error parsing data: {e} – Raw Data: {line_data}”)
return None, None
# Plot setup
fig, ax = plt.subplots()
line, = ax.plot([], [], linewidth=2, label=”Force (N)”, color=’blue’)
ax.set_xlim(0, 10)
ax.set_ylim(0, 100)
ax.set_xlabel(“Time (s)”)
ax.set_ylabel(“Force (N)”)
ax.set_title(“Real-Time Load Cell Data”)
ax.legend()
# Initialize the plot
def init():
return line,
# Update the plot with new data
def update(frame):
global timestamps_seconds, forces
try:
# Read data from ESP32
line_data = ser.readline().decode(‘utf-8’).strip()
print(f”Raw Data: {line_data}”) # Print raw data to the terminal
# Parse the data
seconds, force = parse_data(line_data)
if seconds is None or force is None:
return line # Skip this frame if parsing failed
# Store parsed values
timestamps_seconds.append(seconds)
forces.append(force)
# Calculate time in minutes
minutes = seconds / 60
# Save data to CSV
with open(output_filename, ‘a’) as f:
f.write(f”{seconds},{minutes:.3f},{force}\n”) # Include minutes in the CSV
# Plot only the most recent 50 points
recent_timestamps = timestamps_seconds[-50:]
recent_forces = forces[-50:]
line.set_data(recent_timestamps, recent_forces)
# Dynamically adjust axis limits
ax.set_xlim(0, max(recent_timestamps[-1], 10)) # Expand X-axis dynamically
ax.set_ylim(0, max(recent_forces) * 1.1 if recent_forces else 100) # Adjust Y-axis dynamically
except Exception as e:
print(f”Error in update(): {e}”)
return line,
# Animate the plot
ani = FuncAnimation(fig, update, init_func=init, blit=False, interval=100)
# Show the plot
plt.show()
# Save the final graph when the script stops
plt.plot(timestamps_seconds, forces, linewidth=2, label=”Force (N)”, color=’blue’)
plt.xlabel(“Time (s)”)
plt.ylabel(“Force (N)”)
plt.title(“Final Load Cell Data”)
plt.legend()
graph_filename = f”load_cell_plot_{datetime.now().strftime(‘%Y%m%d_%H%M%S’)}.png”
plt.savefig(graph_filename)
print(f”Data saved to {output_filename}”)
print(f”Graph saved as {graph_filename}”)
In this experiment, we captured real-time data and plotted the forces experienced by YJ while walking back and forth using our CRUTCH system equipped with a spring-damper mechanism. The data was logged dynamically using load cells, allowing us to analyze the forces exerted during each step.
Key Findings:
- Reduced Peak Forces:
- Our CRUTCH significantly reduced peak forces compared to a regular crutch, with force differences as significant as 140 N versus 600 N.
- This demonstrates the effectiveness of the spring-damper system in absorbing shock and distributing forces more evenly.
- Improved Shock Absorption:
- The spring-damper mechanism successfully absorbed impacts and minimized sharp force spikes, showcasing its ability to reduce strain on the user.
- Enhanced User Comfort:
- The reduced forces and smoother force profiles indicate that our CRUTCH is more comfortable for users, potentially minimizing fatigue and long-term physical strain compared to a standard crutch.
Conclusion from our Experiment:
These results validate the design goals of our CRUTCH, proving that integrating a spring-damper system improves comfort, stability, and usability. This makes it a superior alternative to traditional crutches, especially for users requiring extended mobility support.


Electronic System Integration to Crutch
In this section, we provide imagery of the electronic system integration and the final product of our crutch compared to the regular crutch.


Stepper Motor Connection
Purpose of Using a Stepper Motor:
- The goal was to integrate a motorized mechanism that allows the user to adjust the stiffness of the damper with the use of a motor.
- This feature would provide:
- Customizable support for users based on their recovery needs or preferences.
- Adaptability to various terrains, such as smooth surfaces, gravel, or grass.
- Increased flexibility, making the crutch suitable for a wide range of users and conditions.
What We Achieved this semester:
- Successfully operated the stepper motor using a compact and efficient setup:
- Components used: Xiao ESP32 S3 microcontroller and an A4988 stepper motor driver.
- Controlled via a computer interface to demonstrate functionality.
Importance for our CRUTCH System:
- The ability to adjust damper stiffness provides a tailored experience, reducing strain during use and improves overall comfort.
- Makes the crutch adaptable for users with different injuries or mobility needs, and for varied environmental conditions.
- Supports our project’s focus on creating a lightweight, ergonomic, and user-friendly device.
Future Work:
- Simplified Control Mechanism:
- Replace the computer interface with a button-operated system, making adjustments easier and more intuitive.
- This aligns with our commitment to increasing accessibility and usability for the end-user.
Conclusion:
Although the stepper motor wasn’t fully implemented into our CRUTCH, the successful demonstration of its functionality highlights its potential to improve the system. With further development, this feature could greatly enhance the crutch’s versatility, making it more user-friendly and adaptable for a wider range of applications.
The following code was used to get the stepper motor to work:
// Define stepper motor connections and steps per revolution:
#define dirPin 8
#define stepPin 7
#define stepsPerRevolution 3200
// Variables to store input data
int numSteps = 0;
String direction = “”;
int speed = 500; // Default speed (delay in microseconds)
void setup() {
// Initialize serial communication:
Serial.begin(9600);
// Declare pins as output:
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
// Print instructions to Serial Monitor:
Serial.println(“Enter command in format ‘M: (num steps) D: (forward/back) S: (speed in microseconds)'”);
}
void loop() {
if (Serial.available() > 0) {
// Read the input string from Serial Monitor:
String input = Serial.readStringUntil(‘\n’);
input.trim(); // Remove any extra whitespace
// Parse the input string:
if (parseCommand(input)) {
// Set the direction:
if (direction == “forward”) {
digitalWrite(dirPin, HIGH);
} else if (direction == “back”) {
digitalWrite(dirPin, LOW);
}
// Rotate the stepper motor for the specified number of steps:
for (int i = 0; i < numSteps; i++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(speed); // Use the specified speed
digitalWrite(stepPin, LOW);
delayMicroseconds(speed);
}
// Acknowledge the command:
Serial.println(“Command executed: ” + input);
} else {
Serial.println(“Invalid command. Please use ‘M: (num steps) D: (forward/back) S: (speed in microseconds)'”);
}
}
}
// Function to parse the command from Serial Monitor
bool parseCommand(String command) {
// Check if the input contains “M:”, “D:”, and “S:”:
if (command.startsWith(“M:”) && command.indexOf(“D:”) > 0 && command.indexOf(“S:”) > 0) {
int mIndex = command.indexOf(“M:”) + 2; // Start of number of steps
int dIndex = command.indexOf(“D:”) + 2; // Start of direction
int sIndex = command.indexOf(“S:”) + 2; // Start of speed
// Extract and parse the number of steps:
String stepsStr = command.substring(mIndex, command.indexOf(“D:”));
stepsStr.trim(); // Remove whitespace
numSteps = stepsStr.toInt();
// Extract and parse the direction:
String directionStr = command.substring(dIndex, command.indexOf(“S:”));
directionStr.trim(); // Remove whitespace
direction = directionStr;
// Extract and parse the speed:
String speedStr = command.substring(sIndex);
speedStr.trim(); // Remove whitespace
speed = speedStr.toInt();
// Validate inputs:
if (numSteps > 0 && (direction == “forward” || direction == “back”) && speed > 0) {
return true; // Valid command
}
}
return false; // Invalid command
}
The following set of images shows the components used for our motor as well as the wiring connections needed to get our compact system to function properly.



Spring and Damper Mechanism Integration for our Crutch

From the top of the figure on the left, our crutch is split into sections A and B respectively.
Section A uses springs. Part 1 is free to glide along the frame of the crutches, and part 2 is firmly secured to the frame. The springs connect these two parts, which are responsible for relieving the impact force when the crutches touch the ground. For part 2, fixing this part was a major challenge because it had to bear all the load on the user. We’re going to look a little further down on this page.
Section B is the damper part and serves to mitigate the initial reaction force transmitted from the ground to the user’s armpits and arms.

All parts were modeled using Autodesk Fusion 360 and 3D printed.
When designing Part 1, the most important thing to consider was the gap between the two holes. If this gap is too narrow or wide, it will not only be able to fit on crutches, but it will also be stuck between the two frames of crutches, making it impossible to move smoothly.
After several experiments, comparing the distance between the two cylinders of the crutch, the optimal distance between the two holes was set to be 3 mm longer than this distance.
In addition, since the upper part of Part 1 touches the user’s armpit, a curved design is applied to increase the user’s feeling and to apply the rubber pad.
There is a square hole in the middle and it requires additional shape optimization to minimize weight and material cost.

Part 2 design is characterized by semicircular holes on both sides that have the same diameter as the cylinder part of the crutches, because part 2 needs to be attached to the cylinder as much as possible.
Furthermore, if Part 2’s length is too long, the frame of the crutches will be spread out to both sides, making it impossible for Part 1 to move smoothly as Part 1 could get stuck between the frames. Through several experiments, this length was set to 2 mm smaller than Part 1’s length on both sides.
Also, the shape optimization will proceed for this part as well.

When designing Part 2, there were two things that were most important.
First, it’s a strong holding force because it’s the part that has to bear the weight of the user.
The second is the possibility of a quick position change, because if a different length of spring is applied depending on the user’s weight and body shape, part 2 must be moved up or down and fixed again accordingly.
To do this, four methods were considered as follows.
In the case of fixing part 2 with a clamp, it was difficult to fully adhere to the cylinder, and in order to change the position of part 2, it was inconvenient to rotate the screw to move the clamp position. This method was rejected
In the case of extending the length of part 2 to both sides, it was rejected as well because it could affect the movement of part 1 if it was extended a lot for a strong fixing force.
Also, drilling was rejected because the movement of part 2 became impossible.
The final method was to remove and attach Part 2 using Velcro. It was finally adopted because it is the simplest and cheapest method for both strong fixation and fast movement.

Parts 3 and 4 are applied to ensure that the damper and rubber packing are secured without shaking, respectively.

It is the result of shape optimization in Parts 1 and 2. The analysis was conducted by applying the same conditions as when using crutches in practice as follows.
– Materials: Since PLA, the material of the 3D printer, was not among the options available, shape optimization was conducted with PC/ABS Plastic with the most similar properties.
– Preserved region: Set the lower part of Part 1 and the upper part of Part 2 as preservation region, which should never be deleted for spring fixation.
– Loads: Load value is applied assuming that 75 kg (165 lb), the average weight of an adult male, is applied
– Constraints: Part 1 shall glide over the frame of the crutches through two holes, and part 2 shall be firmly attached and secured to the frame of the crutches through the semicircular sections on both sides. Constraints have been established for each part in consideration of these two conditions.
– Contact Points: A human load is placed on the upper curved design part of Part 1, which is transferred through the spring to the upper flat part of Part 2. A contact point is established in consideration of these conditions.
It was found that shape optimization is possible for the middle part of each part as shown in the figure.
Advanced
Data Analysis of Simulations and Experiments on Crutch

We used a mathematical approach to model the mass-spring-damper system. The equation above represents the dynamics, factoring in mass, damping, and stiffness. Apply Laplace transform, we solved for displacement as a function of time under various force inputs.

This is the Simulink Block Diagram of Mass-Spring-Damper system. We used Simulink block diagram to simulate MSD system and plot a visual graph.

In order to grab a general understanding of the MSD system in our crutch, we implemented simple simulations as shown above. We got a left-hand side graph when the system is undamped (regular crutch) and the right-hand side graph when the system is damped (C.R.U.T.C.H system).
Simulations demonstrate how different damping and stiffness values affect displacement over time. By tuning these coefficients, we aim to optimize the crutch’s responsiveness to user loads.

For example, higher damping reduces overshooting,

while varying spring stiffness adjusts energy return.

After we finished the simulations, we planned experiments to show our device functionality. Our experiment plan includes analyzing ground reaction forces to optimize the spring and damper coefficients. This process involves simulating and testing the forces exerted during crutch use, ensuring the system adapts to different users effectively.

The second experiment compares shoulder trajectory across different designs. With optimized damping and propulsion, our design achieves smoother and more natural motion, as seen in trajectory (c). This highlights the potential ergonomic benefits of our C.R.U.T.C.H system.
Meet the Team

Nohemi Sepulveda
Electrical Communication Integration:
-Arduino Nano to Load Cells Comms
-ESP32 to Load Cells Comms
-Motor System Configuration with XIAO Setup
-Real-time data plotting and visualization for live CRUTCH experiment results

Electrical Communication Integration:
-ESP32 to ESP32 Comms
-ESP32 to Accelerometer Comms
-CAD model development of CRUTCH
-Real-time plotting of Accelerometer data for live CRUTCH experiment
Yongjae Lee
Structural & Mechanical Design and Analysis:
-Ideation and conceptualization for the CRUTCH project
-Designed the installation method of spring, damper, and new additional parts
-3D modeling and printing of new additional parts of CRUTCH
-Shape optimization of each part with FEA
Yong Hyun Chung
Theoretical and Computational Analysis:
-Conceived and coordinated Project C.R.U.T.C.H
-Designed experiments to analyze ground reaction forces & crutch motion trajectory
– Carried out measurements for the C.R.U.T.C.H system validation
-Performed the theoretical and computational analysis on mass-spring-damper system and ordinary differential equation