Using an MPU6050 to stop a NEMA 17 Stepper Motor if a rapid change in acceleration has occurred

Hey! I am using an MPU6050 and want to stop the NEMA 17 Steppermotor when there is any sudden acceleration in any direction - x,y, or z. I am having trouble getting the slope and the resultant to work to detect this rapid change

Here is some code to start:

/*
Accelerometer code - Automatic shutoff of NEMA 17 Stepper Motor 
April 1, 2024 
*/
#include <MPU6050_tockn.h> // Include the MPU6050 library
#include <Wire.h> // Include the Wire library for I2C communication

MPU6050 mpu6050(Wire); // Initialize the MPU6050 object with the Wire library

const int dirPin = 3; // Define the pin for stepper motor direction control
const int stepPin = 4; // Define the pin for stepper motor step control
const int buttonPin = 13;  // Define the pin for the pushbutton
const int stepsPerRevolution = 200; // Define the number of steps per revolution for the stepper motor

long timer = 0; // Initialize a variable to store the current time
float prevAccX = 0; // Initialize a variable to store the previous X-axis acceleration
float prevAccY = 0; // Initialize a variable to store the previous Y-axis acceleration
float prevAccZ = 0; // Initialize a variable to store the previous Z-axis acceleration
bool rapidChangeDetected = false; // Initialize a flag to indicate if a rapid change in acceleration is detected

void setup() {
  Serial.begin(9600); // Start serial communication at 9600 baud rate
  Wire.begin(); // Initialize the I2C communication
  mpu6050.begin(); // Initialize the MPU6050 sensor
  mpu6050.calcGyroOffsets(true); // Calibrate the gyroscope offsets
  
  pinMode(buttonPin, INPUT); // Set the button pin as input
  pinMode(stepPin, OUTPUT); // Set the step pin for the stepper motor as output
  pinMode(dirPin, OUTPUT); // Set the direction pin for the stepper motor as output
}

void loop() {
  mpu6050.update(); // Update MPU6050 sensor readings

  // Read acceleration values
  float accX = mpu6050.getAccX(); // Read X-axis acceleration
  float accY = mpu6050.getAccY(); // Read Y-axis acceleration
  float accZ = mpu6050.getAccZ(); // Read Z-axis acceleration

  Serial.println("=======================================================");
    Serial.print("temp : ");Serial.println(mpu6050.getTemp());
    Serial.print("accX : ");Serial.print(mpu6050.getAccX());
    Serial.print("\taccY : ");Serial.print(mpu6050.getAccY());
    Serial.print("\taccZ : ");Serial.println(mpu6050.getAccZ());

  // Check for rapid change in acceleration
  if (millis() - timer > 1000) { // Check if it's time to check for a rapid change
    float deltaX = abs(accX - prevAccX); // Calculate change in X-axis acceleration
    float deltaY = abs(accY - prevAccY); // Calculate change in Y-axis acceleration
    float deltaZ = abs(accZ - prevAccZ); // Calculate change in Z-axis acceleration
    float deltaAcc = sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ); // Calculate total change in acceleration

    if (deltaAcc > 0.3) { // Check if rapid change in acceleration exceeds threshold
      rapidChangeDetected = true; // Set flag to indicate rapid change detected
      float timeDiff = (millis() - timer) / 1000.0; // Calculate time difference since last check
      float slope = deltaAcc / timeDiff; // Calculate slope of acceleration change
      Serial.print("Slope: "); // Print slope to serial monitor
      Serial.println(slope);
    }

    prevAccX = accX; // Update previous X-axis acceleration
    prevAccY = accY; // Update previous Y-axis acceleration
    prevAccZ = accZ; // Update previous Z-axis acceleration
    timer = millis(); // Update timer to current time
  }

  // Set motor direction clockwise
  digitalWrite(dirPin, HIGH); // Set direction pin to control motor direction

  // Read button state
  int buttonState = digitalRead(buttonPin); // Read state of pushbutton

  // Rotate motor if button is pressed and no rapid change detected
  if (buttonState == LOW ) { // Check if button is pressed and no rapid change detected
    for (int i = 0; i < stepsPerRevolution &&rapidChangeDetected; i++) { // Loop for specified number of steps per revolution
      digitalWrite(stepPin, HIGH); // Set step pin to high to trigger a step
      delayMicroseconds(450); // Delay to control step timing
      digitalWrite(stepPin, LOW); // Set step pin back to low
      delayMicroseconds(450); // Delay to control step timing
    }

      if (buttonState == HIGH) // if button is not pressed, turn the motor off
    digitalWrite(stepPin, LOW);

  } else { // Stop motor if rapid change detected
    digitalWrite(stepPin, LOW); // Set step pin low to stop the motor
    rapidChangeDetected = false; // Reset the flag
  }
}

2 posts were merged into an existing topic: Using an MPU6050 to stop a NEMA 17 stepper motor from spinning