I will build a 121212 RGBLEDCube and currently planning stuff and also coding the base of the code.
To show an animation I will call a member function of a class(derived class of class 'animation') instance(pointer) in the heap.
This member function(void render()) is blocking. To change animations or colors, a ESP8266 sends Serial data to the main microcontroller.
Because the main microcontroller is stuck in the render() function it wont recognize that data.
That's why the ESP8266 pulls an Interrupt Pin to GND which calls a InterruptServiceRoutine function(ISR function(void)) on the main microcontroller while this microcontroller is in the blocking render() function.
This ISR function should change animations or colors.
In some cases like changing the animation will it be neccessary that the instance (the blocking void render() is member of this instance and is currently executed) gets deleted or/and that after the ISR function the microcontroller does not continue where it stopped in the render() function.
The ISR function is member of the main class 'LEDCube'. The pointer to the instance(void render() is its member) is also a member of the class 'LEDCube'. Do you have an idea how to 'jump' to another position in the code after the ISR function?
Would goto be useful? Making void render() non-blocking is no option.
I hope you understood what I mean, simplified code:
#ifndef LEDCUBE_H
#define LEDCUBE_H
class LEDCube {
public:
LEDCube(OctoWS2811 & l, CubeConfig c) : config(c)
{
utils = new utilities(l, c);
}
void begin()
{
pinMode(config.SerialInterruptPin, INPUT_PULLUP);
attachInterrupt(config.SerialInterruptPin, SerialISR, FALLING);
}
void SerialISR() {} //ISR function
void setnewani(animation *newani)
{
if (ani)
delete ani;
ani = newani;
newani->init(utils);
ani->render();
}
animation * ani = 0; //pointer to the instance
utilities * utils;
CubeConfig & config;
};
#endif
#ifndef ANIMATION_H
#define ANIMATION_H
class animation {
public:
animation() {};
virtual void render() = 0; //blocking for a long time
void init(utilities *u)
{
utils = u;
}
protected:
utilities *utils;
};
#endif
Making your "render" method non-blocking would solve your biggest problem. In your ISR, you could set a global volatile variable to indicate color change and since render no longer blocks, you could adjust color accoringly to that variable.
Danois90:
Making your "render" method non-blocking would solve your biggest problem. In your ISR, you could set a global volatile variable to indicate color change and since render no longer blocks, you could adjust color accoringly to that variable.
Void render() does, how the name implies, render the RGB values for 1728RGB LEDs in Cube with several strings of WS2811 F8 LEDs. Making this function non-blocking is very difficult. I already thought of making a global bool that makes the render function non-blocking if the bool is true and the ISR would make it true but this would be a dirty way because lots of processing power would be wasted by repeadetly checking if this bool is true inside the render() function.
hallolo:
because lots of processing power would be wasted by repeadetly checking if this bool is true inside the render() function.
You could check the variable for each 12 (or 12*12) LED's you render and save some compute power 
Danois90:
You could check the variable for each 12 (or 12*12) LED's you render and save some compute power 
Ok, that's a very good Idea. The render() function does repeatedly call the function(void) show(). Show does send out the data signal to the LEDs-> show() commits a frame. I think adding the check for the bool there and let render() return if true is a good way of solving this problem. Thank you.
But another question: If I add the check to the show() function(void) how can I let render() return?:
void show() {
//send data signal
if(cancel)//cancel would be the bool var
return; //Would just let show() return and not render() if show() called in render()
}
It would be easier to check "cancel" in render, but you also could do this:
bool show() {
if (cancel) return false;
//Showing stuff
return true;
}
void render() {
//Do something
if (!show()) return;
}
Danois90:
It would be easier to check "cancel" in render, but you also could do this:
bool show() {
if (cancel) return false;
//Showing stuff
return true;
}
void render() {
//Do something
if (!show()) return;
}
Ok, I will do that, thank you.