Alternative to void * pointer in my project

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.

Thanks

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?

userCommand needs to either be global or static.

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.

Thanks for the info. I am just thinking if I do a Parent-Derived relationship with my sequence. I would still need to cast the code somewhere right?

This is a pseudocode

Sequence *currentSequence;

if (command == "Move Motor")
(MoveMotorSequence)currentSequence
else
(MoveFeederSequence)currentSequence

Somewhere, along the loop.. If I have multiple sequences then I still need to do a bunch of if else and typecasting?

To do what? The 'void *' variable currentSequence serves absolutely no purpose in the posted code. You set it twice:

currentSequence = &moveMotorSequence;
currentSequence = &moveFeederSequence;

But you never use the value for anything. What are your trying to accomplish?

But you never use the value for anything. What are your trying to accomplish?

Depending on the user's input, I could execute either of the sequences.

Thanks

You cannot return your command like this. The pointer points to a place in memory that is local to this function.

When the function is left, this memory is not available anymore.

You should reserve this space before calling the function and then hand that to the function...

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...

This is a case for a virtual method.

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.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.