c++visual-studioarduinovisualmicro

Problem with calling constructor outside the setup() in Arduino


I had a OLED SPI display 128x64 and I was using Adafruit_GFX and Adafruit_SSD1306 to control it. I had a class name Engine which had a public constructor like this:

Engine::Engine() {
    display.begin(2U, 0U, true, false);

  // Define some pinmode not a problem
    pinMode(button1Pin, INPUT_PULLUP);
    pinMode(button2Pin, INPUT_PULLUP);
    pinMode(xPin, INPUT);
    pinMode(yPin, INPUT);
    pinMode(buzzerPin, OUTPUT);

  //clear the screen and display
    clearScreen();
    display.display();
    time = 0;
}

Then in my .ino file I have something like this:

Engine engine = Engine();

void setup() {
    Serial.begin(115200);
    Serial.println("testing...");
}

The problem is that the program kind of freeze up. I don't know if the code was working or not (I think it was not). I tried to debug it and if I have the engine declare inside setup it would be fine. Or if I remove the line display.begin() and keep the declare outside the setup. Why? Did I need to call display.begin() inside setup(). How to get away with this?

P.S: I was using visual micro for this. But after that I move the code to Arduino and the problem still appeared.


Solution

  • You need to split that constructor into two parts. Right now your constructor is doing things with hardware like calling pinMode. But if you call it at global scope before setup is called then it will get called before main calls init() and sets up the hardware. Basically, you're calling pinMode before the board is ready to set a pinMode. What you need to do is separate all the hardware stuff into a begin() or init() method in the class that you can call form setup. All the constructor should do is initialize any variables that need it and construct the object. You should have engine.begin() that you can call from setup to do all the pinMode and hardware stuff once the hardware is ready to run. Look at how your lcd code works with a begin method.