Hi,
I am trying to move a series of motors using my web browsers and I am using void * pointers in doing this.
But I find it hard to manage in my code.
I have a series of sequences to execute like the distance of motor movements.
#include <Arduino.h>
struct StepData
{
char command;
int value;
};
struct MoveMotorSequence
{
const char *sequenceName = "Move Motor";
int currentStep = 0;
int stepSize = 5;
StepData steps[5] = {StepData{'1', 700}, StepData{'3', 6000}, StepData{'2', 160000}, StepData{'3', 17000}, StepData{'2', 0}};
};
struct MoveFeederSequence
{
const char *sequenceName = "Move Feeder";
int currentStep = 0;
int stepSize = 3;
StepData steps[3] = {StepData{'3', 800}, StepData{'2', 10000}, StepData{'1', 200}};
};
// More sequence
void *currentSequence;
const char *getSequence()
{
// Input from user through web browser
const char *userCommand = "Move Motor";
return userCommand;
}
void setup()
{
Serial.begin(9600);
}
void loop()
{
// Get the command
const char *command = getSequence();
if (strcmp("Move Motor", command) == 0)
{
// Initialize the Move Motor sequence
MoveMotorSequence moveMotorSequence;
currentSequence = &moveMotorSequence;
// Do the Motor Movement
}
else if (strcmp("Move Feeder", command) == 0)
{
// Initialize the Move Feeder sequence
MoveFeederSequence moveFeederSequence;
currentSequence = &moveFeederSequence;
// Do the Motor Movement
}
}
As you can see I am using a void * pointer to do this but I find it cumbersome like what if I add additional sequences with different steps.
Is there a better alternative to using void * pointers?
I am no C++ expert and have just learned it on my own.
The two structs MoveMotorSequence and MoveFeederSequence should both be instances of the same type. Or should at least derive from the same type. Then currentSequence can be a pointer to that type. In order for them to have different numbers of steps then you will need to make that struct a template. This is fairly advanced.
The easier method is to decide now what is the maximum number of steps you'll allow and then make each instance big enough to hold that many and have another member variable that tells how many there actually are.
Returning a pointer to a local variable is a bad idea. You may find that by the time you access that pointer and try to print from it or compare to it, the text that it points to may have changed.
The two structs MoveMotorSequence and MoveFeederSequence should both be instances of the same type. Or should at least derive from the same type. Then currentSequence can be a pointer to that type. In order for them to have different numbers of steps then you will need to make that struct a template. This is fairly advanced.
Thanks for the reply, do you mean about Classes? Where I could have a Base Class (e.g Sequence) and a Derive Class (e.g MoveMotorSequence, MoveFeederSequence ) and then use the Sequence field instead of the void * pointers?
I have been reading about this but have not used this in an actual Arduino program though.
const char *getSequence()
{
// Input from user through web browser
const char *userCommand = "Move Motor";
return userCommand;
}
Oh, I have just typed this on top of my head. What should be the proper way of doing this?
You can do the same thing with structs. In the old days there was a difference between classes and stucts. Nowadays the only difference is that the default access for classes is private and for stucts it is public.
Both sequence structs could have a sequence pointer. Then they would be equal and you could use a sequence struct pointer instead of a void pointer
Much safer...
Hint: an array name is a pointer...
If the base type has a virtual runSequence function, and then each derived type implements that, then you could use a pointer to the base type to call runSequence and have it call the function from whatever struct type the pointer pointed to.