that function which has the same name as the class is called a constructor.
LedPanel(uint8_t pin, size_t count, uint32_t col, bool en = true)
this is what gets called with the parameters from your code, for example when you do
LedPanel panels[] = {
{2, 5, 0xFF0000}, // pin 2, 5 pixels, red
{4, 10, 0x00FF00}, // pin 4, 10 pixels, green
{5, 15, 0x0000FF}, // pin 5, 15 pixels, blue
};
then for the first one, pin is 2, count is 5 and col is 0xFF0000. The last parameter (en
) is optional since it has a default value (so we don't need to mention it in {2, 5, 0xFF0000}, // pin 2, 5 pixels, red
if we want it to be true but we could write {2, 5, 0xFF0000, false}, // pin 2, 5 pixels, red and disabled
if we wanted to pass that parameter to the constructor)
after the function's signature that's where you usually have the code of the function within {}. but for the constructor you have what's called a member initializer list. You simply put a colon after the function and then list how you assign values (taking possibly from the parameters) to the instance variables (members) of the class.
you'll see (skipping the first for the time being)
: gpio(pin), numLeds(count), defColor(col), panelEnabled(en)
which means the gpio instance variable takes the value of the pin parameter, the numLeds instance variable takes the value of the count parameter etc..
there is a special part before those though
Adafruit_NeoPixel(count, pin, NEO_GRB + NEO_KHZ800)
Because our class inherits from Adafruit_NeoPixel as written in its definition
class LedPanel : public Adafruit_NeoPixel {
and we want to call the constructor of the parent class, that's where we do it. The syntax is the name of the parent class Adafruit_NeoPixel
and within the parenthesis the parameters you want to pass to the parent's constructor.
last we have the code of the function but since we initialized everything needed already, we just have an empty function { }
so that explains
LedPanel(uint8_t pin, size_t count, uint32_t col, bool en = true) // <=== constructor signature
: Adafruit_NeoPixel(count, pin, NEO_GRB + NEO_KHZ800), gpio(pin), numLeds(count), defColor(col), panelEnabled(en) // <=== initializer list
{} // <=== nothing in the body of the function
that was just an example. you can define what you want as functions of your class. Note though the syntax with the two colons
void begin() {
Adafruit_NeoPixel::begin();
...
we defined a begin() member function in our class which starts by calling the begin() function of the parent class (Adafruit_NeoPixel) and then we can do something else. But if you have nothing special to do other than calling the parent class (say you want to call setPixelcolor()
) then you don't need you own version of setPixelcolor inside your custom class. because you inherited from Adafruit_NeoPixel, you are a kind of Adafruit_NeoPixel and so your instance knows to do whatever Adafruit_NeoPixel knows to do (and code add stuff).
long story short, you can just write panels[1].setPixelcolot(i,color);
because panels[1]
is a "strip" (a kind of Adafruit_NeoPixel)
if you get that then you got the beauty of Object Oriented Programming
hope that makes sense