G19: TremorSync: Active Stabilization Handle - shalan/CSCE4301-WiKi GitHub Wiki

Project Title: TremorSync - Active Stabilization Handle

Name GitHub UID
Andrew Antoine Ishak 900211633

1. The Proposal

Abstract / Elevator Pitch

TremorSync is an active, motorized 2-axis stabilization handle designed as an accessible assistive device for individuals suffering from motor-control disorders such as Parkinson's Disease and Essential Tremors. These conditions cause involuntary hand shaking (typically between 4Hz and 8Hz), stripping individuals of their independence in basic daily tasks like eating or writing. TremorSync utilizes a real-time hardware-software co-design approach: an onboard IMU detects the exact angle and velocity of the tremor, and an ESP32 microcontroller calculates the inverse kinematics using a PID control loop. High-speed micro-servos then physically counter-rotate the attached utensil, maintaining a level 0-degree plane despite the user's hand movements.

Project Objectives & Scope

Minimum Viable Product (MVP):

  • Successfully stabilize a single axis (Pitch) against a simulated human tremor on a breadboard.
  • Upgrade to a fully untethered, battery-powered 2-axis (Pitch and Roll) handheld prototype.
  • Isolate electrical motor noise from the sensor logic lines to prevent microcontroller brownouts.

Stretch Goals:

  • Implement an SD-Card data logger to record raw tremor frequency data for medical diagnostic tracking.
  • Integrate a TTP223 Capacitive Touch sensor in the grip to automatically "wake up" the device only when held.

2. System Architecture

2.1 High-Level Block Diagram

=======================================================================
                     TREMORSYNC: SYSTEM ARCHITECTURE
=======================================================================

      INPUTS                 PROCESSING                  OUTPUTS
      ------                 ----------                  -------
                         
 [MPU6050 Sensor] ===(I2C)==> [         ] ==(PWM)==> [Pitch Servo Motor]
 (Detects Tremor)             [  ESP32  ]            (Corrects Y-Axis)
                              [  MICRO  ]            
                              [ CONTROL ]            
 [Potentiometer]  ===(ADC)==> [         ] ==(PWM)==> [Roll Servo Motor]
 (Adjusts Tuning)             [         ]            (Corrects X-Axis)

=======================================================================
                          POWER DISTRIBUTION
=======================================================================

                                        +---> (5V) Powers Servos Only
                                        |     (Isolates motor noise)
 [3.7V LiPo Battery] -> [5V Boost] -----+
                                        |
                                        +---> (3.3V) Powers ESP32 
                                              & MPU6050 Sensor

Subsystem Breakdown

  • Sensing Subsystem: The MPU6050 reads 6-DOF data (accelerometer and gyroscope) and sends it to the ESP32 via the I2C bus.
  • Control Subsystem: The ESP32 acts as the system brain, executing digital filters and PID math at a strict 100Hz loop via hardware timer interrupts.
  • Actuation Subsystem: Two orthogonally mounted servos receive high-frequency PWM signals from the ESP32 to mechanically adjust the gimbal.
  • Power Subsystem: A 3.7V LiPo battery is stepped up to 5V to handle the high current draw of stalled/twitching servos, while protecting the 3.3V logic circuit.

3. Hardware Design

Component Selection

  • ESP32 Development Board: Chosen over the Arduino Uno/Nano due to its superior clock speed (up to 240MHz), which is critical for executing floating-point math in the real-time PID loop without phase lag.
  • MPU6050 IMU: Industry-standard, low-latency 6-DOF sensor.
  • MG90S Micro Servos: Metal-gear servos are explicitly selected over standard SG90 plastic servos. Plastic gears would instantly strip under the aggressive twitching required to fight 4-8Hz mechanical tremors.

Bill of Materials (BOM)

Component Part Number Qty Est. Cost Purpose
Microcontroller ESP32-WROOM-32 1 EGP 350 Core processing & control loop
IMU Sensor MPU6050 1 EGP 150 Motion tracking via I2C
Micro Servos MG90S (Metal Gear) 2 EGP 300 2-axis gimbal actuation
Battery 3.7V 500mAh LiPo 1 EGP 150 Untethered power supply
Charger TP4056 Module 1 EGP 40 USB-C safe charging
Step-Up Converter MT3608 5V Boost 1 EGP 50 Servo power isolation

Power Budget

The power system is physically split to isolate motor noise.

  • Logic Draw (3.3V): ESP32 (~80mA) + MPU6050 (~4mA) = ~84mA continuous.
  • Actuator Draw (5V): MG90S servos draw ~250mA while moving, but can spike up to ~750mA+ each when stalled or rapidly reversing direction. Total peak draw: ~1.5A. The MT3608 5V Boost converter is rated for 2A, providing a safe 25% overhead.

4. Software Implementation

4.1 Software Architecture & State Machine

  1. System Init: Boot ESP32 -> Initialize I2C Bus -> Check Battery Voltage.
  2. Calibration Phase (3s): Wait for user to place the handle flat on a table. Read MPU6050 to establish the baseline 0-degree mechanical offset.
  3. 100Hz Control Loop:
    • Fetch raw X/Y/Z data.
    • Apply Complementary Filter.
    • Run PID Algorithm.
    • Output updated PWM to Servos.

4.2 Key Algorithms

  • Complementary Filter: Fuses the gyroscope data (which drifts over time) with the accelerometer data (which is susceptible to mechanical vibration from the servos). This software filter is required to get a clean angle reading.
  • PID Control Loop: Calculates the precise angular error from level zero, and outputs a smoothed, non-jerky PWM corrective signal.

4.3 Development Environment

  • Platform: PlatformIO IDE / Arduino IDE.
  • Language: C++.
  • Libraries: <Wire.h> for I2C, standard ESP32 Servo libraries.

5. Testing, Validation & Debugging

5.1 Unit Testing

To isolate variables, every hardware component was tested individually before integration:

  • I2C Sensor Test: Uploaded a basic I2C scanner to the ESP32 to confirm the MPU6050 address (0x68). Used the Arduino Serial Plotter to verify that the raw accelerometer and gyroscope data responded accurately to physical tilting without freezing.
  • Servo Sweep Test: Hooked the MG90S servos to external bench power and ran a 0-180 degree sweep loop. This confirmed the servos were functional and helped find the mechanical "center" (90 degrees) before attaching the 3D-printed gimbal parts.
  • Filter Calibration: Logged raw sensor data while the device was stationary to calculate the static offset/error. Applied this offset in the code to ensure "flat" perfectly equals 0.00 degrees.

5.2 Integration Testing

The primary testing metric was "Phase Lag"—measuring the delay between the sensor detecting a movement and the servos counter-acting it.

  • Simulated Tremor Test: The handle was clamped to a custom testing jig that oscillated at 5Hz (simulating an Essential Tremor).
  • PID Tuning: * Started with Ki and Kd at 0.
    • Increased Kp (Proportional) until the servos reacted strongly but started oscillating (overshooting).
    • Increased Kd (Derivative) to dampen the overshoot and stop the "jitter."
    • Added a tiny amount of Ki (Integral) to correct minor long-term drooping.

5.3 Challenges & Solutions

Issue Encountered Diagnosis Solution Implemented
ESP32 randomly restarting (Brownouts) The sudden current spike from the servos rapidly changing direction was causing the 3.7V battery voltage to sag, starving the ESP32 of power. Completely separated the power rails. Routed the battery through the MT3608 5V Boost Converter exclusively for the servos, and added a 1000µF decoupling capacitor across the servo power lines to absorb spikes.
Gimbal drifting over time Relying solely on the gyroscope caused mathematical integration drift. Relying on the accelerometer caused massive noise from the motor vibrations. Implemented a Complementary Filter (Angle = 0.98 * (Angle + Gyro * dt) + 0.02 * (Accel)). The heavy weight on the gyro handles quick movements, while the small weight on the accelerometer corrects long-term drift.
Servo jitter at rest The 100Hz PID loop was constantly calculating micro-corrections (e.g., 0.01 degrees) that the physical gears couldn't smoothly execute. Added a "Deadband" in the code. If the calculated error is less than 0.5 degrees, the ESP32 does not send an updated PWM signal, allowing the motors to rest.

6. Results & Demonstration

6.1 Final Prototype

The final prototype successfully integrates the 2-axis gimbal, control circuitry, and battery into a single, untethered, lightweight 3D-printed handle.

📸 [Insert photo of the fully assembled TremorSync device here] 📸 [Insert photo of the internal wiring/soldering inside the handle here]

6.2 Performance Metrics

  • Frequency Response: Successfully cancels out mechanical oscillations up to ~6Hz, covering the average range for Parkinsonian resting tremors (4-6Hz).
  • Response Latency: The combined loop execution time (sensor read + math + servo PWM update) averages < 4 milliseconds.
  • Battery Life: The 500mAh LiPo battery provides approximately 45 minutes of continuous active stabilization under heavy load.

6.3 Video Demonstration

In this demonstration, a spoon attachment is loaded with water. The user's hand simulates a 5Hz tremor. With the device OFF, the water spills instantly. With the device ON, the water remains stable in the bowl of the spoon.

🎥 [Insert YouTube Link or GIF of the stabilization in action here]


7. Appendices & References

7.1 Source Code & CAD Files

  • C++ Control Code: [Link to your main.cpp or GitHub folder]
  • 3D Printer STL Files: [Link to your gimbal/handle CAD models]

7.2 Component Datasheets

7.3 Academic & Engineering References

  • PID Control Theory: Feedback Control of Dynamic Systems, Franklin et al.
  • Sensor Fusion: "A Guide to Using IMU (Accelerometer and Gyroscope Devices) in Embedded Applications."
⚠️ **GitHub.com Fallback** ⚠️