Как получить переменную из функции обратного вызова?

Есть библиотека davetcc/IoAbstraction. Единственная библиотека, работающая должным образом с моим поворотным энкодером. Проблема в том, что при вращении я вижу только серийный вывод с данными о положении, но не могу получить эти данные как какое-то значение переменной.

В main.cpp есть инициализация коммутатора и определение функции. switches.addSwitch(spinwheelClickPin, onSpinwheelClicked);

void onSpinwheelClicked(uint8_t pin, bool heldDown) {
  Serial.print("Button pressed ");
  Serial.println(heldDown ? "Held" : "Pressed");
}

Определение из SwitchInput.cpp

bool SwitchInput::addSwitch(pinid_t pin, KeyCallbackFn callback,uint8_t repeat, bool invertLogic) {
    if(internalAddSwitch(pin, invertLogic)) {
        KeyboardItem item(pin, callback, repeat, invertLogic);
        return keys.add(item);
    }
    
    return false;
}

Существует определение типа функции обратного вызова из SwitchInput.h

.
typedef void(*KeyCallbackFn)(pinid_t key, bool heldDown);

Я канон просто меняю void на bool. Итак, как я могу получить значение этой переменной heldDown?

Извините, если вопрос глупый.

, 👍4


1 ответ


Лучший ответ:

3

Функции обратного вызова обычно void и не возвращают реальных данных, потому что они вызываются какой-либо системой обработки событий, например упомянутой библиотекой. Поскольку это вызывает функцию обратного вызова, а не вы, нет особого смысла возвращать из нее данные. Чтобы получить это возвращаемое значение, вам нужно будет изменить библиотеку для каждого бита данных, который вы хотите. Таким образом, возвращаемые значения функций обратного вызова являются либо void, либо некоторым сообщением системе обработки событий (например, чтобы система событий отправила событие следующему возможному обработчику).

Но вы можете использовать глобальные переменные для получения данных обратного вызова. Определите глобальную переменную для значения, которое вы хотите извлечь, и внутри функции обратного вызова установите эту переменную. Затем в других местах вашего кода вы можете использовать эту глобальную переменную.

Библиотека, которую вы связали, похоже, обрабатывает событие в основном коде, а не в прерываниях. Таким образом, вы можете просто использовать глобальные переменные по своему усмотрению.

Хотя для полноты: когда задействованы прерывания и вы изменяете глобальные переменные внутри подпрограммы обработки прерывания, вам нужно быть очень осторожным. Однобайтовые переменные не проблема, но с многобайтовыми переменными вы можете получить зашифрованные данные, так как прерывание может произойти в середине обработки этой переменной. Затем нужно ввести критическую секцию, где прерывания отключаются на очень короткое время.

,