1

I am trying to create an interactive program for a stepper motor that receives commands and moves to the assigned position, to said command.

I am confused on defining a struct within a class pertaining to the motor itself. I am using the Arduino stepper library to move the motor, but I wish to define the commands within a class, with structs. The process would be, defining the struct, defining a function that creates a customizable struct, and using the elements inside the struct to drive the commands. I feel like I could use a pointer in the if statements, but I am unsure how to proceed with that.

#include "Stepper.h"
const int stepsPerRevolution = 200;
String command;
int stepsTotal = 0;
int currentPos = 3;  // this is the default home position.
int newPos = 0;
int stepsPos = 210;  //steps between each position, approximately 27 degrees
int steps = 0;


//future header file
class Motor {
public:
  Motor() = default;
  void SetupMotor(Stepper* step);
  void SetupCommands();
  void MoveMotor(String, String);
  struct TripLog {
    int CurrentLoc;
  };
  struct Positioner {
    String InputPosition[10];  //
    int StepAdv[10];           //
    String Waypoints[7];
    int WaypointAdv[7];
  };
private:
  Stepper* _Stepper1;
};

// future compiled functions
void Motor::SetupCommands(){
    //custom commands:
  Motor::Positioner PosCommands;
  int i;
  char pos[10];
  for (i = 1; i <= 10; i++) {
    PosCommands.InputPosition[i - 1] = "Position " + pos[i];
    PosCommands.StepAdv[i - 1] = i;
  }
  // Can reduce this to another for loop, just make another object with names, and loop over
  // maybe accepts a list with the names? Counts how many there are, and loops over both sides.
  //PosCommands.Waypoints[0] = "home"; incorporate this?
  PosCommands.Waypoints[0] = "posTest";
  PosCommands.Waypoints[1] = "posTestNeg";
  PosCommands.Waypoints[2] = "current position";
  PosCommands.Waypoints[3] = "nextPos";
  PosCommands.Waypoints[4] = "prevPos";
  PosCommands.Waypoints[5] = "reposition cw";
  PosCommands.Waypoints[6] = "reposition ccw";
  PosCommands.WaypointAdv[0] = 316;
  PosCommands.WaypointAdv[1] = -316;
  PosCommands.WaypointAdv[2] = 0;
  PosCommands.WaypointAdv[3] = 211;
  PosCommands.WaypointAdv[4] = -211;
  PosCommands.WaypointAdv[5] = 40;
  PosCommands.WaypointAdv[6] = -20;
  return PosCommands;
}

void Motor::SetupMotor(Stepper* step) {
  _Stepper1 = step;
  _Stepper1->setSpeed(60);
}

void Motor::MoveMotor(String motor, String position) {
  _Stepper1->step(200);  //here is the steps

}

Motor motorTest;
Stepper Stepper1 = Stepper(stepsPerRevolution, 8, 9, 10, 11);  //from stepper library

void setup() {
  motorTest.SetupMotor(&Stepper1);
  Serial.begin(9600);
  delay(2000);
  motorTest.SetupCommands();
}

void loop() {
  if(Serial.available())
  {
    command = Serial.readStringUntil('\n');
    if (PosCommands.InputPosition[i] == command)
    {
      return PosCommands.StepAdv[i];
    }
    if (PosCommands.Waypoint[i] == command)
    {
      return PosCommands.WaypointAdv[i];
    }
  }
  //motorTest.MoveMotor("Motor", "Position 10"); //test example to see if it compiles
}

I get a

Compilation error: 'PosCommands' was not declared in this scope

message in the loop, but I would like to avoid redefining the scope here, to avoid any issues with the Arduino.

mabsch
  • 11
  • 1
  • check on which line you get the error – Juraj Feb 15 '23 at 06:14
  • I see 2 problems in your code: 1. In `Motor::SetupCommands()` you are returning `PosCommands`, though the function is declared as void. If you want to return something, then you need to declare the function with the correct return data type. 2. You use `PosCommands` inside of `loop()`, but this is only defined inside `Motor::SetupCommands()`, so the compiler cannot know that variable in that scope. If you want to use it in `loop()`, you need to think about how to move the needed data between the different contexts (main program vs your class), maybe about getter/setter functions. – chrisl Feb 15 '23 at 08:29

0 Answers0