0

I'm writing a program for an ATmega microcontroller using the Arduino framework. While implementing an hardware-related class (one to manage LEDs), I put some hardware initialization code such as pinMode(OUTPUT) in the class constructor. Then I realized that in all Arduino libraries I know the hardware initialization is done in a begin() or init(), so I created one for my Led class as well and moved pinMode() there.

Now I'm wondering if I really should define such initialization funcitons, i.e. why they are needed - or, if they are not, why so many libraries have them. I played around a bit and found that for example this code works on an ATmega1284 (it makes the LED on pin 28 light up).

struct Test {
  Test() {
    pinMode(28, OUTPUT);
    digitalWrite(28, HIGH);
    // other stuff
  }
  // ...
};

Test test;

void setup() {
}

void loop() {
}

I presume that this code is somehow ill-conceived, letting alone the fact that it lights up a led without any code in the main function (or maybe that is exaclty the problem?), but if so I can not see why. What did I not consider? Should the code above be rather writte as in the following snippet, as the existence of all these begin() functions leads me to believe?

struct Test {
  Test() {
    // other stuff
  }
  void begin() {
    pinMode(28, OUTPUT);
    digitalWrite(28, HIGH);
  }
  // ...
};

Test test;

void setup() {
  test.begin();
}

void loop() {
}
  • Although Arduino API styleguide recommends to use begin() to set thing up. To me both are works and is a design consideration, provided that you know what have been configured and initialised by the Arduino.h and variants for a particular boards, and what you are trying to do in the construct will not be overrided by the init() within the Arduino Core main(). For example, you see many library use the construct to set thing up like LCD lcd(SDL, SDA);. – hcheung Mar 31 at 1:08
  • 1
    To your question about setup() and loop(), see the source code of Arduino Core main.cpp for better understanding. – hcheung Mar 31 at 1:09
1

It's all to do with the order of execution.

Constructors are executed before normal functions. That includes the main() function which eventually calls setup() and (repeatedly) loop(). One of the other things that main() does is call init() (or some variant of) which configures the hardware.

Since that happens after any global constructors have been run anything that the constructor did to the hardware could potentially be undone.

Thus it is normal to defer any hardware configuration until after main() has done the work of setting things up, and the convention is to use a begin() function to do it.

| improve this answer | |
  • Thanks for the answer! And what is actually this init() function? Where is it defined? And, by the way, where is the main() function in an Arduino project? – noearchimede Mar 30 at 22:15
  • It's all in the core. Read the cores source code. – Majenko Mar 30 at 22:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.