Hi everyone! I'm writing a class to manage led ([bclass led][/b]). I included in the constructor the following line
where "pin_number" is the argument of the constructor. I declare an instance of led class globally, i.e.:
//implicit call to pinMode(4, OUTSIDE);
So the strange thing is that "pinMode" function is called outside the "setup()" . It's a good initialization? Does this can cause some problem?
It depends on just where it is, of course. To be sure include a begin method like the Serial library.
Just store the pin number during the constructor and add:
in setup so you know exactly when it takes place.
That is a good idea but it is a little cumbersome. I can also declare a global pointer and place a new instruction in setup() function
p_led = new led(4);
But I'd like to know what could happen in my former implementation. I made the experiment, and it seems that all is going ok.
You would have to disassemble the hex file and see when the constructor is called.
C++ constructors are called BEFORE main() (which makes sense, right?)
The AVR peripherals are initialized AFTER main() (main() calls init(), from the core library.)
Therefore, constructors cannot do things to peripherals that are dependent on them already being initialized, or that will be un-done when the peripherals are initialized. You should not do pinMode(pin, OUTPUT) in a constructor because other things needed before pinMode() will work might not have been done, and because init() might (sensibly) set the pins to the expected startup state (all inputs) afterwards…
(now, in fact, init() on AVRs doesn’t do anything with the gpio pins, counts on “all inputs” being left over from the HW reset, and pinMode() from a constructor would probably work just fine. But you still shouldn’t do it! (especially because AVRs are not the only CPUs out there any more!)
This should be included in "Q&A After blink and delay". I spent some time before I found this great answer.