Как исправить «неверное использование нестатической функции-члена» в библиотеке, импортирующей другую библиотеку - PullRequest
0 голосов
/ 09 мая 2019

Я пишу библиотеку для arduino, которая в определенный момент должна вызывать функцию после фиксированной задержки без использования функции задержки.

Поскольку стандартные библиотеки c ++ не включены, я должен использовать библиотеки arduino, и я выбрал FlexiTimer2, который полезен для запуска функции каждые X единиц времени (это только введение, проблема не связана с arduino, а связана с c ++ ).

.h file

#ifndef StepperDriverController_h
#define StepperDriverController_h

#include <stdlib.h>
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#include <wiring.h>
#endif

class StepperDriverController
{
    public:
        StepperDriverController(unsigned char step, unsigned char direction);

        void setPulseWidth(unsigned short width);
        // other methods

    protected:
        void stepPinDown();
        void step(bool blocking = true);

    private:
        unsigned char _pins[2];
        // some attributes
};
#endif

.cpp file

#include "StepperDriverController.h"
#include <Thread.h>

void StepperDriverController::stepPinDown()
{
    digitalWrite(_pins[0], LOW);
    FlexiTimer2::stop();
}

void StepperDriverController::setPulseWidth(unsigned short width)
{
    _pulseWidth = width;
    FlexiTimer2::set(width, 1/1000000, stepPinDown);
}

void StepperDriverController::step()
{
    digitalWrite(_pins[1], _direction ? HIGH : LOW);

    digitalWrite(_pins[0], HIGH);
    FlexiTimer2::start();
}

Я получаю недопустимое использование нестатической функции-члена для кода FlexiTimer2 :: set (width, 1/1000000, stepPinDown); и '_ pins' не было объявлено в этой области на digitalWrite (_pins [0], LOW);

Я прочитал много вопросов, связанных с этой ошибкой, но все равно не смог найти способ ее исправить

EDIT

FlexiTimer не следует создавать, а использовать как я, как показано в официальной библиотеке пример

1 Ответ

1 голос
/ 10 мая 2019

Перегрузка FlexiTimer2::set(), которую вы пытаетесь использовать, объявляется так:

namespace FlexiTimer2 {
    // ...
    void set(unsigned long units, double resolution, void (*f)());
}

Третий аргумент void (*f)(). Это указатель на функцию free , возвращающую void и не принимающую аргументов. Однако вы передаете функцию-член . Это не может работать.

Затем вы попытались изменить stepPinDown() из функции-члена в свободную функцию. Это также не сработает, поскольку создание бесплатной функции не позволяет получить доступ к членам StepperDriverController.

Вместо этого вы можете передать лямбду, которую вы заставляете совместить со свободной функцией (используя синтаксис +), например:

FlexiTimer2::set(width, 1/1000000, +[]{ /* your code here */ });

Теперь проблема в том, как получить доступ к StepperDriverController экземпляру и вызвать stepPinDown() на нем. Обычно с лямбдами вы просто делаете лямбда-захват экземпляра:

[&obj]{ obj.stepPinDown(); }

Однако такую ​​лямбду нельзя передать функции, которая ожидает указатель на функцию. Запись + в +[]{ /* your code here */ } как раз для того, чтобы прояснить, что лямбда не должна захватывать что-либо. Вы можете опустить +, если вы не делаете захват; это просто средство самодокументирования и более четкого кода.

Таким образом, поскольку вам не разрешено делать лямбда-захват, и я не знаю точных внутренних частей вашего кода, неясно, как лучше всего вызвать stepPinDown() внутри лямбды. Но кажется, что StepperDriverController является одноэлементным объектом, а это означает, что существует только один его экземпляр. Таким образом, вы можете иметь глобальный указатель на этот экземпляр и использовать его в лямбда-выражении:

FlexiTimer2::set(width, 1/1000000, +[]{ globalInstance->stepPinDown(); });

Я не могу сказать вам, каково правильное решение в вашем случае, но это суть этого.

Есть также проблема, которая не связана ни с чем из этого, но стоит отметить:

1/1000000

Это не делает то, что вы думаете, что делает. Это целочисленное деление, и результат будет 0. Вам нужно:

1.0/1000000.0

Чтобы получить 0,000001 в результате.

...