Eww, totally forgot to reply, sorry...
class LedXY
{
public :
LedXY();
void attach( uint8_t & led );
void on();
void off();
void update();
void setOnColor ( uint8_t const r, uint8_t const g, uint8_t const b, uint8_t const a = 255 );
void setOffColor ( uint8_t const r, uint8_t const g, uint8_t const b, uint8_t const a = 255 );
void setOnColorRGB ( uint32_t const rgb, uint8_t const a = 255 );
void setOffColorRGB ( uint32_t const rgb, uint8_t const a = 255 );
void setOnColorRGBA ( uint32_t const rgba, uint8_t const a = 0 );
void setOffColorRGBA( uint32_t const rgba, uint8_t const a = 0 );
void calcOffColor ( uint8_t const alpha = 75 );
void blink( uint16_t const * const pattern, size_t const length, int8_t const count = -1 );
void blink( uint16_t const timeOn = 1000, uint16_t const timeOff = 1000, int8_t const count = -1 );
void flash( uint16_t const timeOn );
void setBlinkFinishedHandler( void (* func)( LedXY const & led ) );
bool operator == ( LedXY const & obj ) const { return this == &obj; }
bool operator != ( LedXY const & obj ) const { return this != &obj; }
LedXY( LedXY const & ) = delete;
LedXY & operator = ( LedXY const & ) = delete;
void * operator new( size_t ) = delete;
void * operator new[]( size_t ) = delete;
private :
uint8_t * m_ledPtr;
bool m_isOn;
uint8_t m_colors[2][3];
uint32_t m_millis;
uint16_t m_time;
int8_t m_count;
uint16_t const * m_patternPtr;
uint16_t m_pattern[2];
size_t m_patternLength;
size_t m_patternIndex;
void setState ( bool const on );
void updateColor ( bool const on );
void setColor ( bool const on, uint8_t const r, uint8_t const g, uint8_t const b, uint8_t const a = 255 );
void setColorRGB ( bool const on, uint32_t const rgb, uint8_t const a = 255 );
void setColorRGBA( bool const on, uint32_t const rgba, uint8_t const a = 0 );
void (*m_blinkFinishedHandler)( LedXY const & led );
};
LedXY::LedXY() :
m_ledPtr ( nullptr ),
m_isOn ( false ),
m_colors { { 255, 255, 255 }, { 0, 0, 0 } },
m_millis ( 0 ),
m_time ( 0 ),
m_count ( 0 ),
m_patternPtr ( nullptr ),
m_pattern { 0, 0 },
m_patternLength ( 0 ),
m_patternIndex ( 0 ),
m_blinkFinishedHandler( nullptr )
{
}
void LedXY::attach( uint8_t & led )
{
m_ledPtr = &led;
updateColor( false );
}
void LedXY::setState( bool const on )
{
if ( m_patternLength > 1 && m_blinkFinishedHandler != nullptr )
{
m_blinkFinishedHandler( *this );
}
m_count = 0;
m_patternPtr = nullptr;
m_patternIndex = 0;
m_patternLength = 0;
m_isOn = on;
updateColor( on );
}
void LedXY::on() { setState( true ); }
void LedXY::off() { setState( false ); }
void LedXY::updateColor( bool const on )
{
if ( m_ledPtr != nullptr )
{
uint8_t const i = on ? 0 : 1;
for ( uint8_t j = 0; j < 3; j++ )
{
m_ledPtr[j] = m_colors[i][j];
}
}
}
void LedXY::setColor( bool const on, uint8_t const r, uint8_t const g, uint8_t const b, uint8_t const a )
{
uint8_t const i = on ? 0 : 1;
if ( a != 255 )
{
float const m = a / 255.0;
m_colors[i][0] = uint8_t( r * m );
m_colors[i][1] = uint8_t( g * m );
m_colors[i][2] = uint8_t( b * m );
}
else
{
m_colors[i][0] = r;
m_colors[i][1] = g;
m_colors[i][2] = b;
}
}
void LedXY::setColorRGB( bool const on, uint32_t const rgb, uint8_t const a )
{
uint8_t const * const c = (uint8_t *) &rgb;
setColor( on, c[2], c[1], c[0], a );
}
void LedXY::setColorRGBA( bool const on, uint32_t const rgba, uint8_t const a )
{
uint8_t const * const c = (uint8_t *) &rgba;
setColor( on, c[3], c[2], c[1], a == 0 ? c[0] : a );
}
void LedXY::setOnColor ( uint8_t const r, uint8_t const g, uint8_t const b, uint8_t const a ) { setColor( true, r, g, b, a ); }
void LedXY::setOffColor ( uint8_t const r, uint8_t const g, uint8_t const b, uint8_t const a ) { setColor( false, r, g, b, a ); }
void LedXY::setOnColorRGB ( uint32_t const rgb, uint8_t const a ) { setColorRGB ( true, rgb, a ); }
void LedXY::setOffColorRGB ( uint32_t const rgb, uint8_t const a ) { setColorRGB ( false, rgb, a ); }
void LedXY::setOnColorRGBA ( uint32_t const rgba, uint8_t const a ) { setColorRGBA( true, rgba, a ); }
void LedXY::setOffColorRGBA( uint32_t const rgba, uint8_t const a ) { setColorRGBA( false, rgba, a ); }
void LedXY::calcOffColor ( uint8_t const alpha ) { setColor( false, m_colors[0][0], m_colors[0][1], m_colors[0][2], alpha ); }
void LedXY::setBlinkFinishedHandler( void (*func)( LedXY const & led ) ) { m_blinkFinishedHandler = func; }
void LedXY::blink( uint16_t const * const pattern, size_t const length, int8_t const count )
{
if ( count != 0 && length > 0 && pattern != nullptr )
{
m_isOn = true;
updateColor( true );
m_millis = millis();
m_count = count;
m_patternPtr = pattern;
m_patternLength = length;
m_patternIndex = 0;
m_time = m_patternPtr[0];
}
}
void LedXY::blink( uint16_t const timeOn, uint16_t const timeOff, int8_t const count )
{
m_pattern[0] = timeOn;
m_pattern[1] = timeOff;
blink( m_pattern, 2, count );
}
void LedXY::flash( uint16_t const timeOn )
{
m_pattern[0] = timeOn;
blink( m_pattern, 1, 1 );
}
void LedXY::update()
{
if ( m_count != 0 && millis() - m_millis >= m_time )
{
if ( m_patternLength == 1 )
{
setState( false );
}
else if ( ++m_patternIndex < m_patternLength )
{
m_time = m_patternPtr[ m_patternIndex ];
}
else
{
if ( m_count != -1 )
{
m_count--;
}
if ( m_count == 0 )
{
setState( false );
}
else
{
m_patternIndex = 0;
m_time = m_patternPtr[0];
}
}
if ( m_count != 0 )
{
m_millis = millis();
m_isOn = !m_isOn;
updateColor( m_isOn );
}
}
}
...
LedXY myLed;
void onBlinkFinished( LedXY const & led )
{
if ( led == myLed )
{
Serial.println( "myLed finished blinking" );
}
}
...
void setup()
{
...
myLed.setOnColor( 255, 0, 0 );
myLed.setOffColor( 255, 255, 255, 75 );
myLed.setBlinkFinishedHandler( onBlinkFinished );
myLed.attach( RemoteXY.led_1_r );
static const uint16_t blinkPattern[] = { 250, 750, 250, 750, 250, 4750 };
myLed.blink( blinkPattern, sizeof(blinkPattern)/sizeof(blinkPattern[0]) );
...
}
void loop()
{
...
myLed.update();
...
}