MPU605 with Accelstepper

Dear Forum:
I am having trouble interfacing a MPU6050 with the accelstepper library. I wish to use the MPU6050 to control the speed and acceleration of the stepper. This is moving back and forth a defined number of steps. Between each change of direction, the angle of the sensor (i.e. Y) needs to be measured and then used to change the speed. If the angle is too steep, the motor needs to stop and wait a bit.
I have checked the output angle of the MPU6050 and this is resonably close to the results of a digital protractor. The motor works fine but the speed does not change with a change of the angle. Is there some timing problem involved? I have had to deal with a few such problems on other projects.

This is my first attempt using a MPU6050 and also using accelstepper. I have done other projects with steppers and other motors with good success. (These have been accomplished without needing the help of the experts. ) Parts of the code have been copied from other sources. Some variables will be needed for other processes later when this problem has been solved. Proper callibration can come later as well. Sorry if the formatting is not correct. I am using 2.0.

Here is the code for this portion of the project:

#include <Arduino.h>
#include <AccelStepper.h>

AccelStepper stepper(1, 4, 5);  // Stepper mode 1, Pins 4 and 5 see below:
#include <Wire.h>

const int dirPin = 4;
const int stepPin = 5;

bool toggle = false;
#define motor_steps 800
AccelStepper StepperMotor(AccelStepper::DRIVER, stepPin, dirPin);

// Define Conections
volatile unsigned int CumulativeRotationSteps, StepCounter, StatusCounter, UpperLimit, LowerLimit;
volatile int CheckPinsB, CheckPinsD, InitializeSteps;
volatile bool DirectionStatus, TurnMotorStatus, EnableStatus,  Test1SwitchStatus, Test2SwitchStatus, FindBottom, Prepare_Status;
volatile bool InitializeStatus, Hall_MagasinUpFlag, Hall_SchopferDownFlag, Hall_MagasinUpInput, Hall_SchopferDownInput;
unsigned long PreviousStepperMicros = 0, NextStep, PullAcceleration, ReturnAcceleration, PullUpSpeed, ReturnDownSpeed, SpeedCorrection, MappedSpeed, ReturnDownSpeedFast, ReturnDownSpeedSlow;
volatile unsigned long CurrentMicros, NextSTepMicros, CycleDurationMicros, CalculatedMicros, TurnMotorStartMicros;

const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ, GyroX, GyroY, GyroZ;
volatile float accAngleX, accAngleY, gyroAngleX, gyroAngleY, angleX, angleY;
volatile float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, Y_inverted, LastYPosition, CurrentYPosition, YPostionCorection ;
float elapsedTime, currentTime, previousTime;
int c = 0;
struct IMU {
  float angleX, angleY;
  unsigned long timeStamp;
};
IMU imu;

void setup() {

  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);

  //Serial.begin(57600);
  initialize_MPU6050();

  PORTD &= ~_BV(PD7);  //digitalWrite(dirPin, LOW);  //Set motor direction Cclockwise
  StepperMotor.setCurrentPosition(0);  //?????????????????????

  PullAcceleration = 2000;
  ReturnAcceleration = 1000;
  PullUpSpeed = 2000;
  ReturnDownSpeed = 1000;
  SpeedCorrection = 50;
  ReturnDownSpeedFast = 4000;
  ReturnDownSpeedSlow = 1000;

  UpperLimit = 2400;
  LowerLimit = 100;
  LastYPosition = 0;
  CurrentYPosition = 0;
}

void loop() {

  // Serial.print(Y_inverted); Serial.print(' '); Serial.print(CurrentYPosition); Serial.print(' '); Serial.println(MappedSpeed);;

  read_IMU();  // from MPU6050
  CalculateCurrentSpeedAcceleration();

  PullUpRun();

  read_IMU();  // from MPU6050
  CalculateCurrentSpeedAcceleration();

  if (Y_inverted < 45) {
    MoveDown();
  }
  if (Y_inverted > 45)   {
    TopReached();
  }
  }


  void initialize_MPU6050() {
    Wire.begin();                      // Initialize comunication
    Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
    Wire.write(0x6B);                  // Talk to the register 6B
    Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
    Wire.endTransmission(true);        //end the transmission
    // Configure Accelerometer
    Wire.beginTransmission(MPU);
    Wire.write(0x1C);                  //Talk to the ACCEL_CONFIG register
    Wire.write(0x00);                  //Set the register bits as 00010000 (+/- 2g full scale range)
    Wire.endTransmission(true);
    // Configure Gyro
    Wire.beginTransmission(MPU);
    Wire.write(0x1B);                   // Talk to the GYRO_CONFIG register (1B hex)
    Wire.write(0x00);                   // Set the register bits as 00010000 (1000dps full scale)//changed from 10!!!!!!!!!!!!!!!
    Wire.endTransmission(true);
  }

  void calculate_IMU_error() {  //This is probably not important at present but should be used later.
    // We can call this funtion in the setup section to calculate the accelerometer and gury data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
    // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
    // Read accelerometer values 1000times
    while (c < 1000) {
      Wire.beginTransmission(MPU);
      Wire.write(0x3B);
      Wire.endTransmission(false);
      Wire.requestFrom(MPU, 6, true);
      AccX = (Wire.read() << 8 | Wire.read()) / 4096.0 ;
      AccY = (Wire.read() << 8 | Wire.read()) / 4096.0 ;
      AccZ = (Wire.read() << 8 | Wire.read()) / 4096.0 ;
      // Sum all readings
      AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * 180 / PI));
      AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * 180 / PI));
      c++;
    }
    //Divide the sum by 1000to get the error value
    AccErrorX = AccErrorX / 1000;
    AccErrorY = AccErrorY / 1000;
    c = 0;
    // Read gyro values 1000times
    while (c < 1000) {
      Wire.beginTransmission(MPU);
      Wire.write(0x43);
      Wire.endTransmission(false);
      Wire.requestFrom(MPU, 4, true);
      GyroX = Wire.read() << 8 | Wire.read();
      GyroY = Wire.read() << 8 | Wire.read();
      // Sum all readings
      GyroErrorX = GyroErrorX + (GyroX / 32.8);
      GyroErrorY = GyroErrorY + (GyroY / 32.8);
      c++;
    }
    //Divide the sum by 1000to get the error value
    GyroErrorX = GyroErrorX / 1000;
    GyroErrorY = GyroErrorY / 1000;
    // Print the error values on the Serial Monitor
    Serial.print("AccErrorX: ");
    Serial.println(AccErrorX);
    Serial.print("AccErrorY: ");
    Serial.println(AccErrorY);
    Serial.print("GyroErrorX: ");
    Serial.println(GyroErrorX);
    Serial.print("GyroErrorY: ");
    Serial.println(GyroErrorY);
  }

  void read_IMU() {
    // === Read acceleromter data === //
    Wire.beginTransmission(MPU);
    Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
    //For a range of +-8g, we need to divide the raw values by 4096, according to the datasheet
    AccX = (Wire.read() << 8 | Wire.read()) / 4096.0; // X-axis value
    AccY = (Wire.read() << 8 | Wire.read()) / 4096.0; // Y-axis value
    AccZ = (Wire.read() << 8 | Wire.read()) / 4096.0; // Z-axis value

    // Calculating angle values using
    accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) + 1.15; // AccErrorX ~(-1.15) See the calculate_IMU_error()custom function for more details
    accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) - 0.52; // AccErrorX ~(0.5)  Only Y axis used in this construction.  X axis also possible

    // === Read gyro data === //
    previousTime = currentTime;        // Previous time is stored before the actual time read
    imu.timeStamp = millis();            // Current time actual time read
    currentTime = float(imu.timeStamp);
    elapsedTime = (currentTime - previousTime) / 200;   // Divide by 1000 to get seconds  //Changed from 1000!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!111111!!
    Wire.beginTransmission(MPU);
    Wire.write(0x43); // Gyro data first register address 0x43
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 4, true); // Read 4 registers total, each axis value is stored in 2 registers
    GyroX = (Wire.read() << 8 | Wire.read()) / 32.8; // For a 1000dps range we have to divide first the raw value by 32.8, according to the datasheet
    GyroY = (Wire.read() << 8 | Wire.read()) / 32.8;
    GyroX = GyroX + 1.85; //// GyroErrorX ~(-1.85)
    GyroY = GyroY - 0.15; // GyroErrorY ~(0.15)
    // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
    gyroAngleX = GyroX * elapsedTime;
    gyroAngleY = GyroY * elapsedTime;

    // Complementary filter - combine acceleromter and gyro angle values
    imu.angleX = 0.98 * (imu.angleX + gyroAngleX) + 0.02 * accAngleX;  // X Value not needed depending on sensor direction
    imu.angleY = 0.98 * (imu.angleY + gyroAngleY) + 0.02 * accAngleY;
    Y_inverted = -imu.angleY;  // resulting angle of sensor.  Inversion (-) necessary depending on which part of sensor is up!
  }

  void CalculateCurrentSpeedAcceleration() {
    MappedSpeed = map(Y_inverted, 0, 45, 15000, 1000);
    PullUpSpeed = MappedSpeed;
    if (Y_inverted > 25)  {
      ReturnDownSpeed = ReturnDownSpeedSlow;
    }
    else  {
      ReturnDownSpeed = ReturnDownSpeedFast;
    }
    PullAcceleration = MappedSpeed / 2;
    ReturnAcceleration = ReturnDownSpeed / 2;
  }


  void PullUpRun()  {
    StepperMotor.setMaxSpeed(PullUpSpeed);   // by setting this to the desired speed, the motor accelerates to this speed exactly without overshoot.  StepperMotor.setMaxSpeed(PullUpSpeed);
    StepperMotor.setAcceleration(PullAcceleration);
    StepperMotor.moveTo(UpperLimit);
    StepperMotor.runToPosition ();
  }


  void MoveDown()  {

    StepperMotor.setMaxSpeed(ReturnDownSpeed);
    StepperMotor.setAcceleration(2400);
    StepperMotor.moveTo(LowerLimit);

    StepperMotor.runToPosition();

  }

  void TopReached()   {

    StepperMotor.setMaxSpeed(ReturnDownSpeedSlow);
    StepperMotor.setAcceleration(2400);
    StepperMotor.moveTo(LowerLimit);
    StepperMotor.runToPosition();

    do {
      delay(700);
      read_IMU();
    } while (Y_inverted > 40);
  }

The way that your code is posted makes it hard to help you. It is not easy to read and follow because of the lack of formatting and the extraneous white space. It is very hard to copy so that one can paste it into the IDE or a text editor for examination.

Read the forum guidelines to see how to properly post code and some information on how to get the most from this forum.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

Please go back and fix your original post by highlighting the code and clicking the </> in the menu bar.
code tags new

#include <Arduino.h>
#include <AccelStepper.h>

AccelStepper stepper(1, 4, 5);  // Stepper mode 1, Pins 4 and 5 see below:
#include <Wire.h>

const int dirPin = 4;
const int stepPin = 5;

bool toggle = false;
#define motor_steps 800
AccelStepper StepperMotor(AccelStepper::DRIVER, stepPin, dirPin);

// Define Conections
volatile unsigned int CumulativeRotationSteps, StepCounter, StatusCounter, UpperLimit, LowerLimit;
volatile int CheckPinsB, CheckPinsD, InitializeSteps;
volatile bool DirectionStatus, TurnMotorStatus, EnableStatus,  Test1SwitchStatus, Test2SwitchStatus, FindBottom, Prepare_Status;
volatile bool InitializeStatus, Hall_MagasinUpFlag, Hall_SchopferDownFlag, Hall_MagasinUpInput, Hall_SchopferDownInput;
unsigned long PreviousStepperMicros = 0, NextStep, PullAcceleration, ReturnAcceleration, PullUpSpeed, ReturnDownSpeed, SpeedCorrection, MappedSpeed, ReturnDownSpeedFast, ReturnDownSpeedSlow;
volatile unsigned long CurrentMicros, NextSTepMicros, CycleDurationMicros, CalculatedMicros, TurnMotorStartMicros;

const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ, GyroX, GyroY, GyroZ;
volatile float accAngleX, accAngleY, gyroAngleX, gyroAngleY, angleX, angleY;
volatile float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, Y_inverted, LastYPosition, CurrentYPosition, YPostionCorection ;
float elapsedTime, currentTime, previousTime;
int c = 0;
struct IMU {
  float angleX, angleY;
  unsigned long timeStamp;
};
IMU imu;

void setup() {

  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);

  //Serial.begin(57600);
  initialize_MPU6050();

  PORTD &= ~_BV(PD7);  //digitalWrite(dirPin, LOW);  //Set motor direction Cclockwise
  StepperMotor.setCurrentPosition(0);  //?????????????????????

  PullAcceleration = 2000;
  ReturnAcceleration = 1000;
  PullUpSpeed = 2000;
  ReturnDownSpeed = 1000;
  SpeedCorrection = 50;
  ReturnDownSpeedFast = 4000;
  ReturnDownSpeedSlow = 1000;

  UpperLimit = 2400;
  LowerLimit = 100;
  LastYPosition = 0;
  CurrentYPosition = 0;
}

void loop() {

  // Serial.print(Y_inverted); Serial.print(' '); Serial.print(CurrentYPosition); Serial.print(' '); Serial.println(MappedSpeed);;

  read_IMU();  // from MPU6050
  CalculateCurrentSpeedAcceleration();

  PullUpRun();

  read_IMU();  // from MPU6050
  CalculateCurrentSpeedAcceleration();

  if (Y_inverted < 45) {
    MoveDown();
  }
  if (Y_inverted > 45)   {
    TopReached();
  }



  void initialize_MPU6050() {
    Wire.begin();                      // Initialize comunication
    Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
    Wire.write(0x6B);                  // Talk to the register 6B
    Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
    Wire.endTransmission(true);        //end the transmission
    // Configure Accelerometer
    Wire.beginTransmission(MPU);
    Wire.write(0x1C);                  //Talk to the ACCEL_CONFIG register
    Wire.write(0x00);                  //Set the register bits as 00010000 (+/- 2g full scale range)
    Wire.endTransmission(true);
    // Configure Gyro
    Wire.beginTransmission(MPU);
    Wire.write(0x1B);                   // Talk to the GYRO_CONFIG register (1B hex)
    Wire.write(0x00);                   // Set the register bits as 00010000 (1000dps full scale)//changed from 10!!!!!!!!!!!!!!!
    Wire.endTransmission(true);
  }

  void calculate_IMU_error() {
    // We can call this funtion in the setup section to calculate the accelerometer and gury data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
    // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
    // Read accelerometer values 1000times
    while (c < 1000) {
      Wire.beginTransmission(MPU);
      Wire.write(0x3B);
      Wire.endTransmission(false);
      Wire.requestFrom(MPU, 6, true);
      AccX = (Wire.read() << 8 | Wire.read()) / 4096.0 ;
      AccY = (Wire.read() << 8 | Wire.read()) / 4096.0 ;
      AccZ = (Wire.read() << 8 | Wire.read()) / 4096.0 ;
      // Sum all readings
      AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * 180 / PI));
      AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * 180 / PI));
      c++;
    }
    //Divide the sum by 1000to get the error value
    AccErrorX = AccErrorX / 1000;
    AccErrorY = AccErrorY / 1000;
    c = 0;
    // Read gyro values 1000times
    while (c < 1000) {
      Wire.beginTransmission(MPU);
      Wire.write(0x43);
      Wire.endTransmission(false);
      Wire.requestFrom(MPU, 4, true);
      GyroX = Wire.read() << 8 | Wire.read();
      GyroY = Wire.read() << 8 | Wire.read();
      // Sum all readings
      GyroErrorX = GyroErrorX + (GyroX / 32.8);
      GyroErrorY = GyroErrorY + (GyroY / 32.8);
      c++;
    }
    //Divide the sum by 1000to get the error value
    GyroErrorX = GyroErrorX / 1000;
    GyroErrorY = GyroErrorY / 1000;
    // Print the error values on the Serial Monitor
    Serial.print("AccErrorX: ");
    Serial.println(AccErrorX);
    Serial.print("AccErrorY: ");
    Serial.println(AccErrorY);
    Serial.print("GyroErrorX: ");
    Serial.println(GyroErrorX);
    Serial.print("GyroErrorY: ");
    Serial.println(GyroErrorY);
  }

  void read_IMU() {
    // === Read acceleromter data === //
    Wire.beginTransmission(MPU);
    Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
    //For a range of +-8g, we need to divide the raw values by 4096, according to the datasheet
    AccX = (Wire.read() << 8 | Wire.read()) / 4096.0; // X-axis value
    AccY = (Wire.read() << 8 | Wire.read()) / 4096.0; // Y-axis value
    AccZ = (Wire.read() << 8 | Wire.read()) / 4096.0; // Z-axis value

    // Calculating angle values using
    accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) + 1.15; // AccErrorX ~(-1.15) See the calculate_IMU_error()custom function for more details
    accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) - 0.52; // AccErrorX ~(0.5)  Only Y axis used in this construction.  X axis also possible

    // === Read gyro data === //
    previousTime = currentTime;        // Previous time is stored before the actual time read
    imu.timeStamp = millis();            // Current time actual time read
    currentTime = float(imu.timeStamp);
    elapsedTime = (currentTime - previousTime) / 200;   // Divide by 1000 to get seconds  //Changed from 1000!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!111111!!
    Wire.beginTransmission(MPU);
    Wire.write(0x43); // Gyro data first register address 0x43
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 4, true); // Read 4 registers total, each axis value is stored in 2 registers
    GyroX = (Wire.read() << 8 | Wire.read()) / 32.8; // For a 1000dps range we have to divide first the raw value by 32.8, according to the datasheet
    GyroY = (Wire.read() << 8 | Wire.read()) / 32.8;
    GyroX = GyroX + 1.85; //// GyroErrorX ~(-1.85)
    GyroY = GyroY - 0.15; // GyroErrorY ~(0.15)
    // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
    gyroAngleX = GyroX * elapsedTime;
    gyroAngleY = GyroY * elapsedTime;

    // Complementary filter - combine acceleromter and gyro angle values
    imu.angleX = 0.98 * (imu.angleX + gyroAngleX) + 0.02 * accAngleX;  // X Value not needed depending on sensor direction
    imu.angleY = 0.98 * (imu.angleY + gyroAngleY) + 0.02 * accAngleY;
    Y_inverted = -imu.angleY;  // resulting angle of sensor.  Inversion (-) necessary depending on which part of sensor is up!
  }

  void CalculateCurrentSpeedAcceleration() {
    MappedSpeed = map(Y_inverted, 0, 45, 15000, 1000);
    PullUpSpeed = MappedSpeed;
    if (Y_inverted > 25)  {
      ReturnDownSpeed = ReturnDownSpeedSlow;
    }
    else  {
      ReturnDownSpeed = ReturnDownSpeedFast;
    }
    PullAcceleration = MappedSpeed / 2;
    ReturnAcceleration = ReturnDownSpeed / 2;
  }


  void PullUpRun()  {
    StepperMotor.setMaxSpeed(PullUpSpeed);   // by setting this to the desired speed, the motor accelerates to this speed exactly without overshoot.  StepperMotor.setMaxSpeed(PullUpSpeed);
    StepperMotor.setAcceleration(PullAcceleration);
    StepperMotor.moveTo(UpperLimit);
    StepperMotor.runToPosition ();
  }


  void MoveDown()  {

    StepperMotor.setMaxSpeed(ReturnDownSpeed);
    StepperMotor.setAcceleration(2400);
    StepperMotor.moveTo(LowerLimit);

    StepperMotor.runToPosition();

  }

  void TopReached()   {

    StepperMotor.setMaxSpeed(ReturnDownSpeedSlow);
    StepperMotor.setAcceleration(2400);
    StepperMotor.moveTo(LowerLimit);
    StepperMotor.runToPosition();

    do {
      delay(700);
      read_IMU();
    } while (Y_inverted > 40);
  }

[quote="silbermannorganfan, post:3, topic:988969"]


[/quote]Now I understand better how to introduce Code into the forum. Sorry!
Thanks for any help.
Andrew
Andrew

Thanks for posting the code in code tags. I do wish that you would fix your original post though. That is a lot of scrolling to get back up to the original problem description.

How do you know what is going on inside the code? Sprinkle some debugging prints in the code so that you can monitor program flow and the intermediate values of variables. The serial port is your best tool for troubleshooting.

Dear groundFungus:
I did try various tests with print, first without using the accelstepper orders and also in the main routine. When the line " ```
StepperMotor.runToPosition ();" is not in operation, the read MPU6050 values seem to be quite good. Particularly when the motor is moving back down this seems to be a big problem. (My experience with the serial.printer in the past has been that there were often conflicts with the timing for the stepper commands. Maybe the baud rate was not high enough. )I did not try to see what the values for setMaxSpeed(PullUpSpeed); were.
I also set up a LED to light up at various spots in the program and this also seemed to work correctly.
Sorry about this, my background (musician and recording engineer) is not at all programming and I am trying to learn and understand as I go along.

Andrew

Post #3 is (slightly)incorrect. A bracket was missing at the end of Loop. The original has been corrected.
The main problem is still there and I will try to figure it out further.

Solved the problem. Some variables which are used in multiple locations were not discribed as volatile.

Wrote a simple test routine and tried it out. Also checked with print commands.
At least I learned how to post to the forum.

Thanks for the advice.

After further tests I still have not found a solution to my problems. Even though I was able to get everything working and calibrated without an extra MPU6050 library, in the end for the sake of convenience I did now use the MPU6050_light library. On its own, everything works correctly. Activating the stepper motor either using AccelStepper or FlexiStepper (blocking) means that everything goes crazy!! Alone, without the MPU6050 the Stepper is quite happy.

I have reached the conclusion that this is probably not going to work at all and I will have to find a different solution. This will probably involve a flex sensor. It will not be as easy to mount or to calibrate but the code will be much simpler.

If anyone has ideas about how to use the MPU6050 with stepper acceleration functions I would appreciate advice. Would a different arduino processor work or could I tandem two arduino unos?
Thanks
Anyway, here is the completed code:


#include <MPU6050_light.h>
#include <FlexyStepper.h>
#include <Wire.h>


FlexyStepper stepper;
//stepper.connectToPins(stepPin, dirPin);//FlexStep

#define motor_steps 800

char ReadPinsB = 0;
char ReadPinsD = 0;
volatile const byte Hall_SchopferDown = 3;  //PD3
const int dirPin = 4;
const int stepPin = 5;
volatile const byte ENABLE_out = 6;
volatile const byte Test1Switch = 8;
volatile const byte Test2Switch = 9;
volatile const byte Test3Switch = 10;
volatile const byte LED_12 = 12;


MPU6050 mpu(Wire);
unsigned long timer = 0;

// Define Conections
volatile unsigned int  UpperLimit, LowerLimit;
volatile unsigned long   PullUpSpeed, ReturnDownSpeed, SpeedCorrection, MappedSpeed, ReturnDownSpeedFast, ReturnDownSpeedSlow;
volatile unsigned long  PullAcceleration, ReturnAcceleration;

volatile long  Y_inverted,  CurrentYPosition,  Y_from_MPU_light;
const int MPU = 0x68; // MPU6050 I2C address

void setup() {
  Serial.begin(115200);
  Wire.begin(0);
  stepper.connectToPins(stepPin, dirPin);
  byte status = mpu.begin();
  Serial.print(F("MPU6050 status: "));
  Serial.println(status);
  while (status != 0) { } // stop everything if could not connect to MPU6050

  Serial.println(F("Calculating offsets, do not move MPU6050"));
  delay(1000);
  // mpu.upsideDownMounting = true; // uncomment this line if the MPU6050 is mounted upside-down  Does not work for Y axis!
  mpu.calcOffsets(); // gyro and accelero
  Serial.println("Done!\n");

  PORTD &= ~_BV(PD7);  //digitalWrite(dirPin, LOW);  //Set motor direction Cclockwise
  stepper.setCurrentPositionInSteps(0);  // check homing function!!

  PullAcceleration = 2000;
  ReturnAcceleration = 1000;
  PullUpSpeed = 2000;
  ReturnDownSpeed = 500;
  ReturnDownSpeedFast = 4000;
  ReturnDownSpeedSlow = 1000;
  UpperLimit = 2400;
  LowerLimit = 100;
  CurrentYPosition = 0;
}

void loop() {
  mpu.update();
  CalculateCurrentSpeedAcceleration();

  PullUpRun();
  MoveDown();

}
void CalculateCurrentSpeedAcceleration() {
  Y_from_MPU_light = mpu.getAngleY();
  Y_inverted = -Y_from_MPU_light;  // resulting angle of sensor.  Inversion (-) necessary depending on which part of sensor is up!
  CurrentYPosition = Y_inverted;
  MappedSpeed = map (Y_inverted, 0, 45, 15000, 1000); // converts position values of Balg (MPU6050) to stepper speed values  faster at bottom than top
  Serial.print(Y_inverted); Serial.print(' '); Serial.print(Y_from_MPU_light); Serial.print(' '); Serial.print(MappedSpeed); Serial.println();
  PullUpSpeed = MappedSpeed;
  PullAcceleration = MappedSpeed / 2;
  ReturnAcceleration = ReturnDownSpeed / 3;
  //digitalWrite(LED_12, HIGH);
  // Serial.print(PullUpSpeed); Serial.print(' ');   Serial.print(Y_inverted); Serial.print("\n");
}

void PullUpRun()  {

  stepper.setSpeedInStepsPerSecond(PullUpSpeed);
  stepper.setAccelerationInStepsPerSecondPerSecond(PullAcceleration);
  stepper.setTargetPositionInSteps(UpperLimit);
  stepper.moveToPositionInSteps(UpperLimit);
}


void MoveDown()  {
  stepper.setSpeedInStepsPerSecond(ReturnDownSpeedFast);
  stepper.setAccelerationInStepsPerSecondPerSecond(2000);
  stepper.setTargetPositionInSteps(LowerLimit);
  stepper.moveToPositionInSteps(LowerLimit);

}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.