Hey Guys!
I'm having a problem combining my IMU with my stepper motor. The speed of the stepper motor is very slow and is not increasing at all.
The problem is for sure the timing because the IMU is blocking the Stepper. If I uncomment this line: "BMI160.readAccelerometer(rawXAcc, rawYAcc, rawZAcc);" the stepper motor runs with the speed I want.
If I add the IMU-read the Stepper is very slow. I just don't know how to solve the timing problem.. Maybe someone can help me implement Timing Interrupts?
I am using the AccelStepper Library for speed control.
Sensor: BMI160, Stepper Driver: TMC2209, CNC Shield
#include <BMI160Gen.h>
#include <PID_v1.h>
#include <AccelStepper.h>
#define BAUDRATE 115200
// Sensor Data
#define SENSE_RATE 100
#define GYRO_RANGE 250
#define ACCL_RANGE 2
#define deg_to_rad(a) (a/180*M_PI)
#define rad_to_deg(a) (a/M_PI*180)
#define motorInterfaceType 1
const int8_t i2c_addr = 0x69;
//Stepper Motors
//X-Axis:
const int DirX1 = 6;
const int StepX1 = 3;
AccelStepper myStepperX1(motorInterfaceType, StepX1, DirX1);
void print_roll_pitch()
{
myStepperX1.setSpeed(4000);
myStepperX1.runSpeed();
//---------------------------------If i don't read the IMU Values everything works great----------------//
int rawXAcc, rawYAcc, rawZAcc; // x, y, z
BMI160.readAccelerometer(rawXAcc, rawYAcc, rawZAcc);
}
void setup() {
myStepperX1.setMaxSpeed(4000);
myStepperX1.setSpeed(0);
Serial.begin(115200);
BMI160.begin(BMI160GenClass::I2C_MODE, i2c_addr);
BMI160.setGyroRate(SENSE_RATE);
BMI160.setAccelerometerRate(SENSE_RATE);
BMI160.setGyroRange(GYRO_RANGE);
BMI160.setAccelerometerRange(ACCL_RANGE);
BMI160.autoCalibrateGyroOffset();
BMI160.autoCalibrateAccelerometerOffset(X_AXIS, 0);
BMI160.autoCalibrateAccelerometerOffset(Y_AXIS, 0);
BMI160.autoCalibrateAccelerometerOffset(Z_AXIS, 1);
}
void loop() {
print_roll_pitch();
}
use a different library for the stepper-motors that is able to create the step-pulses in the backround.
The MobaTools can do that.
Anyway: driving a stepper-motor requires the most tightest timing you can think of.
Depending on your overall project it might be a good idea to use a much faster microcontroller or to let create the step-pulses by a second microcontroller who has nothing else to do than creating step-pulses.
IMU sounds like balancing a robot. I have no experience with balancing robots. But using a stepper-motor for balancing to me seems hard to do.
Any balancing-device I have seen so far uses DC-motors or maybe closed-loop servomotors.
It is always a good idea to give an overview about your project except maybe if you are developing a putler "neutralizing" device
Not true in any sense. Stepper motors have no timing requirements at all. Most STEP/DIR drivers have extremely loose timing requirements, for example STEP is usually triggered on a rising edge.
only in the sense of that the timing-pulses can be different long.
If you vary the the point in time the next pulse is created - except accelerating / deccelerating
executing code like reading a I2C-device or from the serial-interface inbetween creating the stepper-pulses makes the stepper-motor move unsteady.
Of course the stepper-motor is able to exactly following the unsteady pulsetrain until the point the unsteadyness makes the stepper-motor stall.
But in most cases you want the stepper-motor rotate in the most possible smooth way.
best regards Stefan
Thank's for your Input! You are right I am building a ball-balancing robot. I know it would be easier with DC-Motors but it is also a bit of challenge for me realizing it with stepper motors.
That was also my thought using a second microcontroller just for the IMU and calculating but wouldn't there be the same challenge with timing?
I have seen some similar projects (two-wheel balancing robot) with stepper. They are using Timer Interrupts but I have no experience with those.. Is that the only way? Can you recommend another approach?
You don't need experience with the timer-interrupts.
The MobaTools-library is using timer-interrupts internally
You simply call commands to step back and forth
If you can successfully balance the ball depends on the inertia of your system and especially of the ball.
If the inertia of the ball is bigger the movements of the ball will be slower = more time to measure and react with corrections.
You haven't posted what IMU-sensor you are using.
My picture of a ball balancing robot would be there is a plate with a ball on top of the plate and a mechanic that pitches the plate counteracting on ball-movements to correct the ball-position.
But for this there is no IMU-sensor required.
So how does your balancing robot look like?
Thank's I didn't know about that library. Sounds good I will try it!
I am building a robot that balances on a ball using omnidirectional wheels and Stepper motors. The IMU-Sensor I am using is a DFRobot BMI160 (Bosch).
Massive thanks to you! It works. This Library is a lifesaver.