Использование классов таймеров внутри классов
Я пытаюсь разработать класс для насоса, работающего на шаговом двигателе. Он должен быть простым, но работает не так, как я думал. Как только я перемещаю объект таймера в класс, код не компилируется. Я пробовал много вещей, но, похоже, ничего не работает правильно. Целью всего этого является заставить шаговый двигатель работать самостоятельно на основе вызовов объекта таймера.
насос.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); //ПРОБЛЕМА ЗДЕСЬ
pinMode(pin, OUTPUT);
pinMode(dir, OUTPUT);
}
void Pump::pumpstep(void) {
Serial.println("Stepping");
}
мой .ino просто создает класс, передавая необходимые параметры, но все привязывается, когда я пытаюсь скомпилировать из-за обратного вызова в конструкторе для таймера, по какой-то причине он не позволяет мне использовать адрес нестатического здесь, но я не могу сделать метод статическим, каждый метод pumpstep() должен быть отдельным в зависимости от того, какой насос работает. Я пробовал использовать &Pump::pumpstep, &(Pump::pumpstep) и многие другие указатели, но, похоже, не нашел того, который мне нужен.
вне этого класса таймер работал отлично. Я использовал эту строку ниже:
pumptimer = new TimerObject(100, &pumpStep);
Библиотеку таймера можно найти здесь: https://playground.arduino.cc/Code/ArduinoTimerObject
Будем очень благодарны за любую помощь.
@cameroony, 👍0
Обсуждение1 ответ
Лучший ответ:
Прототип функции-члена полностью отличается от прототипа глобальной функции. Эти два понятия не являются взаимозаменяемыми.
Есть способы обойти эту проблему, например «перенаправить» обратный вызов через глобальную функцию, но они запутаны.
Однако в этой ситуации лучше просто отказаться от TimerObjects.h и сделать это вручную — это не так уж сложно:
#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();
}
}
Затем в цикле вызов:
myPump.run();
Конечно, вы можете просто объединить run()
и pumpstep()
в одну функцию.
- Как изменить направление шагового двигателя с помощью библиотеки AccelStepper?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Шаговый двигатель с концевыми выключателями
- Запустить два степпера одновременно
- Могу ли я запретить библиотеке Stepper удерживать двигатель?
- Как контролировать скорость шагового двигателя 28BYJ-48 без использования библиотеки?
- Странная проблема. Ардуино перестает работать через несколько часов. Мнения, пожалуйста
- TCCR1A и TCCR2A на Леонардо
Вы не можете. Функция-член имеет прототип, отличный от глобальной функции. Есть способы обойти это, но вам действительно не нужна эта библиотека, чтобы периодически что-то происходить. Всего пара строк кода и одна беззнаковая длинная переменная., @Majenko