Howto speed up script on ADXL34 Accelerometer Controlled A4988 Driven Steppers

I am controlling 2 steppers with the ADXL345 and it seems to work well but I am wondering if it would be possible to speed up this script and the associated movement. FYI I am a novice so please be kind. This script was put together with use of Easy_Driver example and also the Adafruit ADXL345 example code. Also arduino needs a reset after initial startup in order for code to function guessing a delay before the loop may help with this.

What if anything should I be looking at. Thanks Nick

 * Stepper_Acclerometer sketch
 *
 * stepper is controlled from the ADXL345.
 * 
 *
 */
 
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
 
int dirPin0 = 10;
int stepPin0 = 11;
int dirPin1 = 7;
int stepPin1 = 8;


int speed = 100;    // desired speed in steps per second
int stepsY = 0;      // the number of steps to make
int stepsX = 0;

void setup()
{
  accel.begin();
  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);
  accel.setDataRate( ADXL345_DATARATE_100_HZ);
  pinMode(dirPin0, OUTPUT);
  pinMode(stepPin0, OUTPUT);
  pinMode(dirPin1, OUTPUT);
  pinMode(stepPin1, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  

  sensors_event_t event; 
  accel.getEvent(&event);
  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");Serial.println("m/s^2 ");
  stepsY = event.acceleration.y * 8;
  stepsX = event.acceleration.x * 8;

  int stepDelay = 100 / speed;  //delay in ms for speed given as steps per sec
  int stepsToY;
  int stepsToX;

  // determine direction based on whether steps_to_mode is + or -
  if (stepsY > 0)
  {
    digitalWrite(dirPin0, HIGH);
    stepsToY = stepsY;
  }
  if (stepsX > 0)
  {
    digitalWrite(dirPin1, HIGH);
    stepsToX = stepsX;
  }  
  
  if (stepsY < 0)
  {
    digitalWrite(dirPin0, LOW);
    stepsToY = abs(stepsY);
  }
    if (stepsX < 0)
  {
    digitalWrite(dirPin1, LOW);
    stepsToX = abs(stepsX);
  }
  // decrement the number of steps, moving one step each time
  while(stepsToY > 0)
  {
    digitalWrite(stepPin0,HIGH);
    //delayMicroseconds(1);
    digitalWrite(stepPin0,LOW);
    delay(stepDelay);
    stepsToY--;      // decrement the steps Y
  }
  while(stepsToX > 0)
  {
    digitalWrite(stepPin1,HIGH);
    //delayMicroseconds(1);
    digitalWrite(stepPin1,LOW);
    delay(stepDelay);
    stepsToX--;      // decrement the steps X
  }
}

Apart from the problem at startup, it sounds like the script is behaving as expected. So I'm not clear what you have in mind by "speed up this script". Have you tried changing the value of the variable "speed"?

Incidentally, the calculation "int stepDelay = 100 / speed;" may give unexpected results as it is dividing integers. Why not enter stepDelay directly as a number of millisecs?

You could rewrite the code so it only takes one step for every iteration of loop() (which would allow the Arduino to do other stuff between steps) but it shouldn't have any impact on the speed of the motor which is governed by setpDelay.

...R

Setting an increment value and constant delay is getting me what i was looking for and i suspect removing some math errors.

FYI: I was looking for quicker response and movement and less delay between X/Y.

Thanks for the hints.

Nick

/*
 * Stepper_Easystepper sketch
 *
 * stepper is controlled from the serial port.
 * a numeric value followed by '+' or '-' steps the motor
 *
 */
 
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
 
int dirPin0 = 10;
int stepPin0 = 11;
int dirPin1 = 7;
int stepPin1 = 8;


int speedd = 100;    // desired speed in steps per second
int stepsY = 0;      // the number of steps to make
int stepsX = 0;

void setup()
{
  accel.begin();
  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);
  accel.setDataRate( ADXL345_DATARATE_100_HZ);
  pinMode(dirPin0, OUTPUT);
  pinMode(stepPin0, OUTPUT);
  pinMode(dirPin1, OUTPUT);
  pinMode(stepPin1, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  

  sensors_event_t event; 
  accel.getEvent(&event);
  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");Serial.println("m/s^2 ");
  stepsY = event.acceleration.y * 20;
  stepsX = event.acceleration.x * 20;

  int stepDelay = 10; // speed;  //delay in ms for speed given as steps per sec
  int Ysteps;
  int Xsteps;
  int increment = 50;

  // determine direction based on whether steps_to_mode is + or -
  if (stepsY > 0)
  {
    digitalWrite(dirPin0, HIGH);
    Ysteps = increment;
  }
  if (stepsX > 0)
  {
    digitalWrite(dirPin1, HIGH);
    Xsteps = increment;
  }  
  
  if (stepsY < 0)
  {
    digitalWrite(dirPin0, LOW);
    Ysteps = increment;
  }
    if (stepsX < 0)
  {
    digitalWrite(dirPin1, LOW);
    Xsteps = increment;
  }
  // decrement the number of steps, moving one step each time
  while(Ysteps > 0)
  {
    digitalWrite(stepPin0,HIGH);
    delayMicroseconds(1);
    digitalWrite(stepPin0,LOW);
    delayMicroseconds(speedd);
    Ysteps--;      // decrement the steps left
  }
  while(Xsteps > 0)
  {
    digitalWrite(stepPin1,HIGH);
    delayMicroseconds(1);
    digitalWrite(stepPin1,LOW);
    delayMicroseconds(speedd);
    Xsteps--;      // decrement the steps left
  }
}

nic579: FYI: I was looking for quicker response and movement and less delay between X/Y.

You haven't explained to me what is (or what you think is) preventing you from getting a quicker response.

Is it possibly the fact that all the X movement takes place before any of the Y movement? Which is how your program is currently written.

If that's the problem then it can be solved by interleaving the steps so there is one X step and then one Y step. Of course its a tiny bit more complex if (say) you want to move 23 X steps in the same time as 19 Y steps. The answer then is to use a FOR loop that iterates 437 times (23 x 19) and moves one motor one step every 23 iterations and moves the other motor one step every 19 iterations.

...R

I took your advise and increment 1 step at a time for Y than X + it was recommended elsewhere to remove the serial commutations as this was adding a delay. The division was a problem and the constant for the delay is working great and has removed the issues when initially started so no reset is needed now. I was getting a stepper lockup when attempting to move quicker previously, now speed can be adjusted by step increment or delay.

This code works smoothly and now pauses at 0 XY. Thanks again for the help.

Nick

/*
 * Stepper_Easystepper - ADXL345 3-axis accelerometer
 *
 * Stepper is controlled from the ADXL345 3-axis accelerometer.
 * 
 *
 */
 
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
 
int dirPin0 = 10;
int stepPin0 = 11;
int dirPin1 = 7;
int stepPin1 = 8;


int speedd = 1;    // desired speed in steps per second
int stepsY = 0;      // the number of steps to make
int stepsX = 0;

void setup()
{
  accel.begin();
  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_2_G);
  // displaySetRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);
  accel.setDataRate( ADXL345_DATARATE_100_HZ);
  pinMode(dirPin0, OUTPUT);
  pinMode(stepPin0, OUTPUT);
  pinMode(dirPin1, OUTPUT);
  pinMode(stepPin1, OUTPUT);
  //Serial.begin(115200);
}

void loop()
{
  

  sensors_event_t event; 
  accel.getEvent(&event);
  /* Display the results (acceleration is measured in m/s^2) */
  //Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
  //Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
  //Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");Serial.println("m/s^2 ");
  stepsY = event.acceleration.y ;
  stepsX = event.acceleration.x ;

  int Ysteps;
  int Xsteps;
  int increment = 1;
  

  // determine direction based on whether steps_to_mode is + or -
  if (stepsY == 0)
  {
    digitalWrite(dirPin0, HIGH);
    Ysteps = 0;
  }
  if (stepsX == 0)
  {
    digitalWrite(dirPin1, HIGH);
    Xsteps == 0;
  }  
  
  if (stepsY == 0)
  {
    digitalWrite(dirPin0, LOW);
    Ysteps = 0;
  }
    if (stepsX == 0)
  {
    digitalWrite(dirPin1, LOW);
    Xsteps = 0;
  }
  
   // determine direction based on whether steps_to_mode is + or -
  if (stepsY > 0)
  {
    digitalWrite(dirPin0, HIGH);
    Ysteps = increment;
  }
  if (stepsX > 0)
  {
    digitalWrite(dirPin1, HIGH);
    Xsteps = increment;
  }  
  
  if (stepsY < 0)
  {
    digitalWrite(dirPin0, LOW);
    Ysteps = increment;
  }
    if (stepsX < 0)
  {
    digitalWrite(dirPin1, LOW);
    Xsteps = increment;
  }
  // decrement the number of steps, moving one step each time
  while(Ysteps > 0)
  {
    digitalWrite(stepPin0,HIGH);
    digitalWrite(stepPin0,LOW);
    delayMicroseconds(speedd);
    Ysteps--;      // decrement the steps Y
  }
  while(Xsteps > 0)
  {
    digitalWrite(stepPin1,HIGH);
    digitalWrite(stepPin1,LOW);
    delayMicroseconds(speedd);
    Xsteps--;      // decrement the steps X
  }
}

Glad its doing what you want.

I had envisaged having only a single WHILE loop that moves both motors one step. Yours moves one motor all the way before it starts moving the other one.

...R