Nothing outside Main.cpp runs! please help

Hello, I cannot seem to get anything to happen outside of the main.cpp file, here is what I have currently.

Main.cpp:

#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

#include "Power.h"
// #include "Color.h"
#include "OnboardLEDs.h"
#include "LEDs.h"

// Adafruit_NeoPixel strip(8, PIN_PC0, NEO_GRB + NEO_KHZ800);
// static uint16_t startHue = 0;
static OnboardLEDs obleds {};

void setup()
{
  //   strip.begin();
  //   strip.show();
  //   strip.setBrightness(15);
}

void loop()
{
  obleds.periodic();
  // for (int i = 0; i < 8; i++)
  // {
  //   int pixelHue = (startHue + (i * 360 / 8)) % 360;
  //   strip.setPixelColor(i, Color::fromHSV(pixelHue, 1, 1));
  // }
  // strip.show();
  // startHue ++;
  // startHue %= 360;
}

OnboardLEDs.h:

#ifndef ONBOARD_LEDS_H
#define ONBOARD_LEDS_H

#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

#include "Color.h"

class OnboardLEDs {
    public:
        static Adafruit_NeoPixel leds;
        static uint16_t startHue;
        OnboardLEDs() {
            leds = Adafruit_NeoPixel(8, PIN_PC0, NEO_GBR + NEO_KHZ800);
            leds.begin();
            leds.show();
            leds.setBrightness(15);

            startHue = 0;
        }
        void periodic() {
            for (int i = 0; i < 8; i++)
            {
                int pixelHue = (startHue + (i * 360 / 8)) % 360;
                leds.setPixelColor(i, Color::fromHSV(pixelHue, 1, 1));
            }
            leds.show();
            startHue++;
            startHue %= 360;
        };
        // void identify();

};

#endif // ONBOARD_LEDS_H

Everthing commented out in the Main.cpp file works fine on its own, I do not understand why when moving it into its own class it does not work. (Yes I know I should have the implementation in a cpp file I just have been trying to see if I was doing something dumb, so its in the header rn.)

Calling APIs in the constructor is dangerous. This happens at a very early stage in the boot process and you don’t yet know if the Arduino APIs you’re calling into will be responsive.

Also the setting of the leds object looks wrong, it should be a constructor initialzation list. It also doesn’t need to be static I think.

Can you just try this instead

class OnboardLEDs {
    public:
        Adafruit_NeoPixel leds;
        uint16_t startHue;
        OnboardLEDs() : leds(8, PIN_PC0, NEO_GBR + NEO_KHZ800) {
            startHue = 0;
        }
        void begin() {
            leds.begin();
            leds.show();
            leds.setBrightness(15);
        }
        void periodic() {
            for (int i = 0; i < 8; i++)
            {
                int pixelHue = (startHue + (i * 360 / 8)) % 360;
                leds.setPixelColor(i, Color::fromHSV(pixelHue, 1, 1));
            }
            leds.show();
            startHue++;
            startHue %= 360;
        };
        // void identify();
};

Then call obleds.begin(); in setup().

That works!
Can you elaborate more on what I was doing wrong? I am very new to cpp (coming from Java) and most of this is quite confusing lol.
Thank you very much!

Looking into which call exactly caused the failure is beyond the time I want to spend, but the basics still apply: Only do object construction / simple data assignments in the constructor code. No calling into Arduino APIs or the functions or the (sub-)constructed objects, and you’ll be fine.

The detailed explanation takes you all the way from the CPU bootup to the startup assembly to __libc_init_array() to initialization of FreeRTOS etc.

This is all about initialization order and being unable (read “should not if you don’t wanna crash”) to call into some functions at constructor-call-time.

1 Like