1

I have a function for manually jogging a stepper motor using the AccelStepper library. At the beginning of the function I would like the motor in question to be selected until told to stop.

Here is what I imagine it would look like:

AccelStepper X_Axis(AccelStepper::DRIVER, 3, 2);
AccelStepper Y_Axis(AccelStepper::DRIVER, 5, 4);
AccelStepper Z_Axis(AccelStepper::DRIVER, 7, 6);

void ManualJog(int Dir, int Spd, int axis)
{
  int i;
  if (Dir == 0){i = 1;}else{i =- 1;}
  setSpeed(i * Spd);
  switch(axis)
    {
      case 1:
      axis = X_Axis;
      break;

      case 2:
      axis = Y_Axis;

      case 3:
      axis = Z_Axis
    }
  while (!Serial.available()){

      axis.runSpeed();
    }
  }

The axis variable should map to whichever axis is called and so control the desired stepper.

How can I achieve this?

Note: I submitted this to StackOverflow with no response. Any help would be appreciated

0

How about using an array?

const int x = 0;
const int y = 1;
const int z = 2; 

AccelStepper axis[] = { {AccelStepper::DRIVER, 3, 2}, ... };

void ManualJog(int Dir, int Spd, int axisIdx)
{
   axis[axisIdx].runSpeed();
}
1

To do it in the form you have, you would want to use a pointer.

void ManualJog(int Dir, int Spd, int axis)
{
  int i;
  AccellStepper *thisAxis = NULL;

  if (Dir == 0) {
    i = 1;
  } else {
    i =- 1;
  }
  setSpeed(i * Spd);
  switch(axis)
  {
    case 1:
      thisAxis = &X_Axis;
      break;

    case 2:
      thisAxis = &Y_Axis;
      break;

    case 3:
      thisAxis = &Z_Axis
      break
  }

  if (thisAxis != NULL) {
    while (!Serial.available()) {
      thisAxis->runSpeed();
    }
  }
}

Briefly: the & before the name of a variable in assignment means "Give me the address of this variable". A * before a variable when declaring that variable means "Make this variable hold the address of another variable of this type". You then have the address variable hold the address of your chosen axel, and then "dereference" that with the "poiner dereference operator" -> (instead of using .).

A check is added to see if thisAxis has actually been assigned anything or not, although you could use the default: case in your switch to abort on an invalid axis number instead.

Depending on how the rest of your program works, though, it may be possible to not use the "axis" integer at all, but pass a reference to the correct stepper to the function:

void ManualJog(int Dir, int Spd, AccelStepper &axis) {
  int i;
  if (Dir == 0) {
    i = 1;
  } else {
    i =- 1;
  }
  setSpeed(i * Spd);
  while (!Serial.available()) {
    axis.runSpeed();
  }
}

In this example the & before the axis variable in the function prototype means "Pass me the address of the variable", and a new variable is created located in the same memory space. This is the pass by reference operator in C++.

  • I very much don't like using "magical numbers" to select the axis. It would be much nicer (and faster) not to pass int axis into ManualJog method, but pass a reference to AccellStepper so the code is more readable. – Filip Franik Aug 24 '18 at 10:44
  • @FilipFranik I agree wholeheartedly - however judging by the way the question is worded, and how the function looks like it's meant to work, at some point the correct axis is going to have to be "selected", and that will probably mean setting a pointer at some point in the sequence. – Majenko Aug 24 '18 at 10:45
  • Brilliant, thank you for this. Pointers are something I have not dealt with before. you are correct in that i wish to select the reference of the motor depending on the input. I will give this a go and respond with my working code. – MJ2507 Aug 24 '18 at 12:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.