0

I am trying to develop a class for a pump that works on a stepper motor, it should be simple but its not working the way I thought it would. Once I move the timer object into the class the code wont compile I have tried a lot of things but nothing seems to work correctly. The goal of this whole thing is getting the stepper motor to step on its own based off of the calls from the timer object.

pump.h

#include "TimerObject.h"`
#ifndef Pump_h
#define Pump_h

class Pump
{
  public:
     Pump(char pin_, char dir_);
    void pumpstep(void);
  private:
    char pin;
    char dir;
    TimerObject *pumptimer;
};

#endif

pump.cpp

Pump::Pump(char pin_, char dir_)
{
    pin = pin_;
    dir = dir_;
    pumptimer = new TimerObject(100, &this->pumpStep); //PROBLEM IS HERE

  pinMode(pin, OUTPUT);
  pinMode(dir, OUTPUT);
}

void Pump::pumpstep(void) {
     Serial.println("Stepping");
}

my .ino simply creates the class passing in the needed parameters but everything binds up when I try to compile because of the callback in the constructor for the timer, for some reason It wont let me use the address of a non-static method here but I cant make the method static each pumpstep() method must be separate depending on which pump is running. I have tried using &Pump::pumpstep, &(Pump::pumpstep) and many more pointers but cant seem to get the one I need.

outside this class the timer was working great I used this line below:

pumptimer = new TimerObject(100, &pumpStep);

The library for the timer can be found here: https://playground.arduino.cc/Code/ArduinoTimerObject

Any help would be greatly appreciated.

  • You cannot. A member function has a different prototype to a global function. There are ways around it, but you really dont need that library to make something happen periodically. Only a couple of lines of code and one unsigned long variable. – Majenko Nov 5 '18 at 23:06
0

The function prototype of a member function is completely different to that of a global function. The two are not interchangeable.

There are ways of working around it, such as "bouncing" your callback through a global function, but they're messy.

However, in this situation you are better off just ditching TimerObjects.h and doing it manually - it's not exactly difficult:

#ifndef Pump_h
#define Pump_h

class Pump
{
  public:
     Pump(char pin_, char dir_);
     void pumpstep(void);
     uint32_t ts;
     void run()
  private:
    char pin;
    char dir;
};

#endif

Pump::Pump(char pin_, char dir_)
{
    pin = pin_;
    dir = dir_;
    ts = 0;
    pinMode(pin, OUTPUT);
    pinMode(dir, OUTPUT);
}

void Pump::pumpstep(void) {
     Serial.println("Stepping");
}

void Pump::run() {
    if (millis() - ts >= 100) {
        ts += 100;
        pumpStep();
    }
}

Then in loop call:

myPump.run();

You can, of course, just combine run() and pumpstep() into one single function.

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.