I am creating a haptic glove that uses stepper motors in conjunction with other sensors. The way I am keeping everything sorted is to use a class to create objects for each finger eg. Finger thumb(); and functions like index.getAngle();
I want this class to be able to have an AccelStepper stepper object within it (as there is a stepper motor per finger). This is what I was thinking of doing to achieve this:
#include <AccelStepper.h>
#define MAX_SPEED 500
// Class for each finger
class Finger {
private:
// Pins setup
int stepPin;
int dirPin;
public:
// Constructor for each finger object
Finger(int stepPin, int dirPin) : stepper(AccelStepper::DRIVER, stepPin, dirPin) {
this->stepper = stepper;
stepper.setMaxSpeed(MAX_SPEED);
}
AccelStepper stepper;
};
Finger Thumb(2, 3);
void loop(){
//Example of how I want to use the stepper finger class
Thumb.stepper.moveTo(90);
}
I don't do too much in C++ so any help would be greatly apreciated.
Yes, the idea is good. There are a number of ways, but since every part has exactly one stepper motor, you can put the object in the class.
A nicer way could be: 'class Finger : AccelStepper'
That way the 'AccelStepper' class is used, with your 'Finger' class as an extra. I think that 'Thumb.moveTo(90)' is nicer.
I took a look at the AccelStepper library, and it is a good, versatile and compatible class. So you can use it in every way without problems.
To distinguish the variables that are a member, they often get a underscore.
private:
int _stepPin;
int _dirPin;
public:
AccelStepper _stepper;
Then you also don't need "this->" anymore.
I don't know if you need the _stepPin and _dirPin, maybe it is enough if they are in the _stepper.
So every finger only has one stepper? Then this should work. Compiles without error.
#include <AccelStepper.h>
#define MAX_SPEED 500
// Class for each finger
class Finger : public AccelStepper
{
private:
public:
// Constructor for each finger object
Finger(int stepPin, int dirPin) : AccelStepper(DRIVER, stepPin, dirPin)
{
setMaxSpeed(MAX_SPEED);
}
};
Finger Thumb(2, 3);
void setup() {}
void loop()
{
//Example of how I want to use the stepper finger class
Thumb.moveTo(90);
}
Is the finger a stepper (Inheritance)
or
Has the finger a stepper (composition)
The finger might have even more steppers one day, a touch sensor, a temperature sensor, a bending sensor...
So I believe the stepper is just one part of the finger.
I would keep the composition.
#include <AccelStepper.h>
#define MAX_SPEED 500
// Class for each finger
class Finger {
protected:
// Pins setup
const int stepPin; // do you really need them? at least make them const
const int dirPin;
public:
// Constructor for each finger object
Finger(int stepPin, int dirPin) :
stepPin{stepPin},
dirPin{dirPin},
stepper(stepPin, dirPin)
{
stepper.setMaxSpeed(MAX_SPEED); // are you sure this is a good idea in the constructor?
}
AccelStepper stepper;
};
Finger Thumb(2, 3);
void setup() {
}
void loop() {
//Example of how I want to use the stepper finger class
Thumb.stepper.moveTo(90);
}
The finger has a stepper, it also has three other sensors connected to it. So composition.
I notice in the code you have protected: what is the purpose of this?
I gather that keeping the composition would mean that I can still have Thumb.stepper.moveTo(90); which would be ideal as like you said it is more futureproof.
However in your code, the constructor for the stepper doesn't have it being set as DRIVER? Is this not required? From what I gather AccelStepper does not default to DRIVER mode?
Finally, in terms of stepPin and dirPin I don't need them if there is a better way around? They are just used for setting up the stepper object.
default for class is private. But I find protected more comfortable if I ever have to inherit from that class. If you don't like it - use private (or leave it).
Thank you for you solution, I tried it and it worked (been a long while since I have seen this code compile successfully).
To answer your question, yes every finger has one stepper (as well as three other sensors which are handled by other classes I made (I did not include that code here as I saw it irrelevant)).
I was just wondering if in this code, if I wanted to run an AccelStepper function within the class (for example creating Finger.testFunction() would I need to prefix the AccelStepper fuction with anything or just do what is shown in the constructor setMaxSpeed(MAX_SPEED) eg.
class Finger : public AccelStepper
{
public:
Finger(int stepPin, int dirPin) : AccelStepper(DRIVER, stepPin, dirPin)
{
setMaxSpeed(MAX_SPEED);
}
//No prefix
void testFunction(){
moveTo(90);
}
//Somesort of prefix?
void testFunction(){
stepper.moveTo(90);
}
};
default for class is private. But I find protected more comfortable if I ever have to inherit from that class. If you don't like it - use private (or leave it).
#include <AccelStepper.h>
#define MAX_SPEED 500
// Class for each finger
class Finger {
public:
// Constructor for each finger object
Finger(int stepPin, int dirPin) :
stepper(AccelStepper::DRIVER, stepPin, dirPin)
{
stepper.setMaxSpeed(MAX_SPEED); // are you sure this is a good idea in the constructor?
}
AccelStepper stepper;
};
Finger Thumb(2, 3);
void setup() {
}
void loop() {
//Example of how I want to use the stepper finger class
Thumb.stepper.moveTo(90);
}
Because the Finger class inherits the behaviors of the AccelStepper class, it can use all of the AccelStepper methods directly, like I did with setMaxSpeed() in the constructor.