Я пытаюсь реализовать класс NeopixelAnimator этой библиотеки: https://github.com/Makuna/NeoPixelBus.
Я создал класс аниматора, который содержит экземпляр библиотечного класса NeoPixelAnimator. Для запуска анимации мне нужно позвонить: .StartAnimation(uint16_t indexAnimation, uint16_t duration, UpdateCallback animUpdate)
.
Моя цель - создать очередь анимаций, которые анимируются друг за другом. Вторая анимация должна начаться, когда первая будет завершена. Поскольку сама библиотека не предоставляет способ сделать это, я создал вектор, представляющий очередь, он содержит анимацию для анимации и ее цвет.
Проблема в том, что функция .StartAnimation()
ожидает параметр UpdateCallback
, который является функцией обратного вызова, которая запускается при вызове функции .UpdateAnimations()
.
Анимации будут запускаться переключателями, подключенными к Arduino Due, которые вызывают функцию .add()
(не в коде примера). Сейчас я хочу проверить, работает ли он, добавив одну анимацию в .init()
.
Мой план состоял в том, чтобы создать массив указателей на функции, которые указывают на эти функции обратного вызова. Проблема в том, что я не могу заставить типы данных совпадать.
Помощь будет принята с благодарностью. Кроме того, отзывы о том, как подходить к решению подобных проблем и создавать код, будут с благодарностью.
Я использую platformIO с библиотекой Arduino на плате Arduino Due.
defines.h:
//Amount of different animations should correspond to the number of callback functions
#define NUMBER_OF_ANIMATIONS 2
//Animation ID's:
#define WIPE_ANIM 0
//Colour ID's:
#define GREEN 0
animator.h:
#include <arduino.h>
#include <NeoPixelAnimator.h>
#include <NeoPixelBrightnessBus.h>
#include <array>
#include <vector>
class Animator
{
public:
private:
//NeoPixel animation time management object
NeoPixelAnimator animations;
//Neopixel strip communication object
NeoPixelBrightnessBus<NeoGrbFeature, Neo800KbpsMethod> strip1; //NeoPixel strip 1 object
//Array of AnimUpdateCallback function pointers to the animation callback functions
AnimUpdateCallback (*_callbackPt[NUMBER_OF_ANIMATIONS])(const AnimationParam ¶m);
//Vector of arrays to store animations to be animated (animId, colorId)
std::vector<std::array<uint8_t, 2>> _animationQueue;
public:
Animator();
void init();
void run();
void add(uint8_t animId, uint8_t colorId);
private:
void updateQueue();
animator.cpp:
#include <Animator.h>
//Default constructor
Animator::Animator() : strip1(NUMBER_OF_LEDS_1, LED_PIN_1),
_callbackPt{wipeColorAnim, wipeColorAnim}
{
}
//Inititalisation function, inits strips, sets brightness for strips, sets inital color with wipeColorAnim()
void Animator::init()
{
strip1.Begin();
strip1.SetBrightness(100);
add(WIPE_ANIM, GREEN); //wipeColor strip1 with Green
}
//Add aniamtion to the queue
void Animator::add(uint8_t animId, uint8_t colorId)
{
//Create array storing the animation ID and its color
std::array<uint8_t, 2> animation{animId, colorId};
//Add the animation to the end of the queue
_animationQueue.push_back(animation);
}
//Loop this function to update animations
void Animator::run()
{
//if there is an animation running
if (animations.IsAnimating())
{
animations.UpdateAnimations(); //update running animation
strip1.Show();
}
else
{
updateQueue();
}
}
//Checks whether there is an animation in the queue if so it's started
void Animator::updateQueue()
{
//if there is an animation waiting in the queue
if (!_animationQueue.empty())
{
//Start next animation in queue on channel 0 with specified time and animUpdate callback function (channel, time, callback)
animations.StartAnimation(0, _animationQueue[0][1], _callbackPt[_animationQueue[0][0]]);
//Remove the just started animation from the queue
_animationQueue.erase(_animationQueue.begin());
}
}
main.cpp:
Animator animator;
void setup()
{
animator.init();
}
void loop()
{
//Put new animation requests in queue and update animations
animator.run();
}
platformio.ini:
[env:due]
lib_ldf_mode = chain+
platform = atmelsam
board = due
framework = arduino
monitor_speed = 115200
monitor_port = COM16
lib_deps =
NeoPixelBus
вызов animations.StartAnimation(0, _animationQueue[0][1], _callbackPt[_animationQueue[0][0]]);
не дает ошибок компиляции. Попытка создания экземпляра функций обратного вызова в массиве указателей на функции делает, однако:
значение типа "AnimUpdateCallback (Animator::*)(const AnimationParam ¶m)
" нельзя использовать для инициализации объекта типа "AnimUpdateCallback (*)(const AnimationParam ¶m)
"
Мое основное замешательство:
каким должен быть тип данных функций обратного вызова в моем классе (void
или AnimUpdateCallback
)?
почему (const AnimationParam ¶m)
необходимо добавить в конце (*_callbackPt[NUMBER_OF_ANIMATIONS])
, в противном случае я получаю ошибку, что типы данных также не совпадают